LiteX/VexRiscv 简介与使用 (二点七五) 斯有海与陆地植物

有点惨,上篇说得想办法把FPU塞进来的路给打通,但是实在受限硬体资源,有点悲剧。
我是已经订了一张85F的orangecrab,但是送来大概也是铁人赛後了。

但没办法,我们fallback回来soft-fp的路子吧。要打造soft-fp的musl-porting其实在近日已经没有太大的状况,然而目前系列所提及的工程手法有点粗糙,那就是没有好好打造 phase1、phase2的cross-compiler,也就是先用host-tool打出一套完全不带library的phase1 cross-compiler,而後以该cross-compiler去编译libc跟其他fundamental library (e.g. libgcc/libcompiler-rt)、并且配上来自kernel的header( e.g. include/linux/*.h) 等等,最後统一装进一个sysroot里面的phase2 compiler,这其实会导致在交叉编译工具时,有些麻烦事情发生。

musl习惯性的操作方式是直接使用 gcc 的spec file 机智覆盖掉原本的builtin spec。但对於日後需要大量交叉编译usperspace program来讲,这是很不方便的、因为prefix不符合惯性。

所以这一章节我们偷一下riscv-gnu-toolchain来用:

git clone https://github.com/riscv/riscv-gnu-toolchain
./configure --musl-src /path/to/our/musl --with-arch=rv32imac --withabi=ilp32
make musl

这两个步骤都会非常的久。

在成功後,我们会获得一包prefix统一的riscv32-unknown-linux-musl-*的cross toolchain。
用这套我们终於可以摆脱要靠 spec file跟各式makefile/configure hack的路,以後遇到有考虑过cross build的专案,基本上设好 CROSS_COMPILE=riscv32-unknown-linux-musl-或着在configure时将make tuple的host设定为 riscv32-unknown-linux-musl,多半都会动。(极少量我们还是会需要改一下autotool的档案)

事不宜迟,将上一篇的busybox以这套toolchain重编,便可以丢到OrangeCrab上了。
这边顺便说一声,Lite/VexRiscv的linux-soc为了可以serial sideload,把baudrate条得非常快,是 1000000 这个非标准的baudrate,所以一些terminal的支援可能会出状况。如果一定要用仅能支援标准baudrate的环境,可以修改 soc_linux.py,将 uart_baudrate 设定的逻辑直接干掉(LiteX预设是115200)或着重订为想要的baudrate。

那麽,我们就透过litex的terminal、litex_term示范一次:

$ cat ./boot.json #rootfs/Linux Image是buildroot编的、OpenSBI按照readme、dts是透过 make.py时,LiteX会从自己的meta data生出来
{
	"Image":       "0x40000000",
	"rv32.dtb":    "0x40ef0000",
	"rootfs.cpio": "0x41000000",
	"opensbi.bin": "0x40f00000"
}
$ lxterm --images ./boot.json --speed 1e6 /dev/ttyACM0
        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2020 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Sep 19 2021 12:10:02
 BIOS CRC passed (a774e300)

 Migen git sha1: 3ffd64c
 LiteX git sha1: 080ecad5

--=============== SoC ==================--
CPU:		VexRiscv SMP-LINUX @ 64MHz
BUS:		WISHBONE 32-bit @ 4GiB
CSR:		32-bit data
ROM:		64KiB
SRAM:		2KiB
L2:		2KiB
SDRAM:		131072KiB 16-bit @ 256MT/s (CL-6 CWL-5)

--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Read leveling:
  m0, b0: |00111000| delays: 03+-01
  m0, b1: |00000000| delays: -
  m0, b2: |00000000| delays: -
  m0, b3: |00000000| delays: -
  best: m0, b00 delays: 03+-01
  m1, b0: |00111000| delays: 03+-01
  m1, b1: |00000000| delays: -
  m1, b2: |00000000| delays: -
  m1, b3: |00000000| delays: -
  best: m1, b00 delays: 03+-01
Switching SDRAM to hardware control.
Memtest at 0x40000000 (2MiB)...
  Write: 0x40000000-0x40200000 2MiB     
   Read: 0x40000000-0x40200000 2MiB     
Memtest OK
Memspeed at 0x40000000 (2MiB)...
  Write speed: 16MiB/s
   Read speed: 10MiB/s

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
[LXTERM] Received firmware download request from the device.
[LXTERM] Uploading ./Image to 0x40000000 (7420864 bytes)...
[LXTERM] Upload complete (181.0KB/s).
[LXTERM] Uploading ./rv32.dtb to 0x40ef0000 (2404 bytes)...
[LXTERM] Upload complete (202.6KB/s).
[LXTERM] Uploading ./rootfs.cpio to 0x41000000 (3781632 bytes)...
[LXTERM] Upload complete (172.8KB/s).
[LXTERM] Uploading ./opensbi.bin to 0x40f00000 (49636 bytes)...
[LXTERM] Upload complete (227.9KB/s).
[LXTERM] Booting the device.
[LXTERM] Done.
Executing booted program at 0x40f00000

--============= Liftoff! ===============--

OpenSBI v0.8-2-ga9ce3ad
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name       : LiteX / VexRiscv-SMP
Platform Features   : timer,mfdeleg
Platform HART Count : 8
Boot HART ID        : 0
Boot HART ISA       : rv32imas
BOOT HART Features  : time
BOOT HART PMP Count : 0
Firmware Base       : 0x40f00000
Firmware Size       : 120 KB
Runtime SBI Version : 0.2

MIDELEG : 0x00000222
MEDELEG : 0x0000b101
[    0.000000] Linux version 5.12.0-rc4 (ruinland@ruinland-x1c) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.08-370-gd4877e6f88) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #2 SMP Mon Sep 20 11:13:18 CST 2021
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000040000000-0x0000000047ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040000000-0x0000000047ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x0000000047ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x8
[    0.000000] SBI v0.2 TIME extension detected
[    0.000000] SBI v0.2 IPI extension detected
[    0.000000] SBI v0.2 RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acim
[    0.000000] riscv: ELF capabilities acim
[    0.000000] percpu: Embedded 10 pages/cpu s19148 r0 d21812 u40960
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 32512
[    0.000000] Kernel command line: mem=128M@0x40000000 rootwait console=liteuart earlycon=sbi root=/dev/ram0 init=/sbin/init swiotlb=32
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Sorting __ex_table...
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 113720K/131072K available (5594K kernel code, 576K rwdata, 860K rodata, 211K init, 221K bss, 17352K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] plic: cpu0: parent irq not available
[    0.000000] plic: interrupt-controller@f0c00000: mapped 32 interrupts with 1 handlers for 2 contexts.
[    0.000000] riscv-intc: 32 local interrupts mapped
[    0.000000] random: get_random_bytes called from start_kernel+0x360/0x4d0 with crng_init=0
[    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0xec2a6fa00, max_idle_ns: 440795202120 ns
[    0.000119] sched_clock: 64 bits at 64MHz, resolution 15ns, wraps every 2199023255546ns
[    0.026829] Console: colour dummy device 80x25
[    0.040585] Calibrating delay loop (skipped), value calculated using timer frequency.. 128.00 BogoMIPS (lpj=256000)
[    0.068034] pid_max: default: 32768 minimum: 301
[    0.102046] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.122393] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.319270] ASID allocator using 9 bits (512 entries)
[    0.351630] rcu: Hierarchical SRCU implementation.
[    0.409578] smp: Bringing up secondary CPUs ...
[    0.421674] smp: Brought up 1 node, 1 CPU
[    0.478165] devtmpfs: initialized
[    0.720391] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.746906] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[    0.808814] NET: Registered protocol family 16
[    2.329851] FPGA manager framework
[    2.458798] clocksource: Switched to clocksource riscv_clocksource
[    4.120316] NET: Registered protocol family 2
[    4.222024] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes, linear)
[    4.252992] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    4.280403] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    4.304197] TCP: Hash tables configured (established 1024 bind 1024)
[    4.334340] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    4.360514] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    4.505214] Unpacking initramfs...
[   13.504868] Initramfs unpacking failed: invalid magic at start of compressed archive
[   14.912822] Freeing initrd memory: 8192K
[   15.020777] workingset: timestamp_bits=30 max_order=15 bucket_order=0
[   17.608218] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[   17.629962] io scheduler mq-deadline registered
[   17.645960] io scheduler kyber registered
[   17.780964] LiteX SoC Controller driver initialized: subreg:4, align:4
[   27.928935] f0001000.serial: ttyLXU0 at MMIO 0x0 (irq = 0, base_baud = 0) is a liteuart
[   27.976351] printk: console [liteuart0] enabled
[   27.976351] printk: console [liteuart0] enabled
[   27.992680] printk: bootconsole [sbi0] disabled
[   27.992680] printk: bootconsole [sbi0] disabled
[   28.460324] libphy: Fixed MDIO Bus: probed
[   28.497698] i2c /dev entries driver
[   28.565869] i2c i2c-0: Not I2C compliant: can't read SCL
[   28.573041] i2c i2c-0: Bus may be unreliable
[   28.721886] mmc_spi spi0.0: SD/MMC host mmc0, no WP, no poweroff, cd polling
[   29.108570] NET: Registered protocol family 10
[   29.472782] Segment Routing with IPv6
[   29.489829] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[   29.632967] NET: Registered protocol family 17
[   29.876327] Freeing unused kernel memory: 208K
[   29.884613] Kernel memory protection not selected by kernel config.
[   29.896105] Run /init as init process
[   30.005564] mmc0: host does not support reading read-only switch, assuming write-enable
[   30.020648] mmc0: new SDHC card on SPI
[   30.220442] mmcblk0: mmc0:0000 ASTC 29.1 GiB 
[   30.896845]  mmcblk0: p1
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Saving random seed: [   63.681305] random: dd: uninitialized urandom read (512 bytes read)
OK
Starting network: OK

Welcome to Buildroot
buildroot login: root
                   __   _
                  / /  (_)__  __ ____ __
                 / /__/ / _ \/ // /\ \ /
                /____/_/_//_/\_,_//_\_\
                      / _ \/ _ \
   __   _ __      _  _\___/_//_/         ___  _
  / /  (_) /____ | |/_/__| | / /____ __ / _ \(_)__ _____  __
 / /__/ / __/ -_)>  </___/ |/ / -_) \ // , _/ (_-</ __/ |/ /
/____/_/\__/\__/_/|_|____|___/\__/_\_\/_/|_/_/___/\__/|___/
                  / __/  |/  / _ \
                 _\ \/ /|_/ / ___/
                /___/_/  /_/_/
  32-bit RISC-V Linux running on LiteX / VexRiscv-SMP.

login[70]: root login on 'console'
root@buildroot:~# 
root@buildroot:~# mount /dev/mmcblk0p1 /mnt
root@buildroot:/mnt# cp ./busybox_unstripped ~
root@buildroot:~# ./busybox_unstripped 
BusyBox v1.35.0.git (2021-09-20 12:50:09 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --show SCRIPT
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

	BusyBox is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	[, [[, addgroup, adduser, ar, arch, arp, arping, ash, awk, base32,
	base64, basename, bc, blkid, bunzip2, bzcat, cat, chattr, chgrp, chmod,
	chown, chroot, chrt, cksum, cmp, cp, cpio, crond, crontab, cut, date,
	dc, dd, delgroup, deluser, devmem, df, diff, dirname, dmesg, dnsd,
	dnsdomainname, dos2unix, du, echo, egrep, eject, env, ether-wake, expr,
	factor, fallocate, false, fbset, fdflush, fdformat, fdisk, fgrep, find,
	flock, fold, free, freeramdisk, fsck, fsfreeze, fstrim, fuser, getopt,
	getty, grep, gunzip, gzip, halt, hdparm, head, hexdump, hexedit,
	hostid, hostname, hwclock, i2cdetect, i2cdump, i2cget, i2cset,
	i2ctransfer, id, ifconfig, ifdown, ifup, inetd, init, insmod, install,
	ip, ipaddr, ipcrm, ipcs, iplink, ipneigh, iproute, iprule, iptunnel,
	kill, killall, killall5, klogd, last, less, link, linux32, linux64,
	linuxrc, ln, logger, login, logname, losetup, ls, lsattr, lsmod, lsof,
	lspci, lsscsi, lsusb, lzcat, lzma, lzopcat, makedevs, md5sum, mdev,
	mesg, microcom, mim, mkdir, mkdosfs, mke2fs, mkfifo, mknod, mkpasswd,
	mkswap, mktemp, modprobe, more, mount, mountpoint, mt, mv, nameif,
	netstat, nice, nl, nohup, nologin, nproc, nslookup, nuke, od,
	partprobe, passwd, paste, patch, pidof, ping, pipe_progress,
	pivot_root, poweroff, printenv, printf, ps, pwd, rdate, readlink,
	readprofile, realpath, reboot, renice, resume, rm, rmdir, rmmod, route,
	run-init, run-parts, runlevel, sed, seq, setarch, setfattr, setpriv,
	setserial, setsid, sh, sha1sum, sha256sum, sha3sum, sha512sum, shred,
	sleep, sort, start-stop-daemon, strings, stty, su, sulogin, svc, svok,
	swapoff, swapon, switch_root, sync, sysctl, syslogd, tail, tar, tc,
	tee, telnet, test, tftp, time, top, touch, tr, traceroute, true,
	truncate, ts, tty, ubirename, udhcpc, uevent, umount, uname, uniq,
	unix2dos, unlink, unlzma, unlzop, unxz, unzip, uptime, usleep,
	uudecode, uuencode, vconfig, vi, vlock, w, watch, watchdog, wc, wget,
	which, who, whoami, xargs, xxd, xz, xzcat, yes, zcat

一如预期,这是个可以用的busybox,我们的模拟器与实际硬体是对得上的 :-)


<<:  坚持己见的厉害之处

>>:  [Day19]C# 鸡础观念- 让时间倒转吧~递回

Jackson API

Jackson API ...

[C 语言笔记--Day13] Pointers to Functions

pointers to functions 乍听之下好像有点奇怪, 但一个 function 跟资料...

DAY28:实作专案之内容

今天要来说到专题实作的部分,预想的设计大致都有完整做出来。 第一个是我们设置日历元件 接着介绍一下我...

Day2 Java 基本功(字)

在上一篇我们有提到可以表示字的数据类型有两个 Char 与 String Char代表字元,我们在程...

JS Truthy 与 Falsy DAY55

MDN: https://developer.mozilla.org/zh-CN/docs/Glos...