iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Software Development

Port Alpine Linux to open source RISC-V platform系列 第 11

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,我們的模擬器與實際硬體是對得上的 :-)


上一篇
LiteX/VexRiscv 簡介與使用 (二點五) 天地分隔
下一篇
Alpine Linux Porting (一)
系列文
Port Alpine Linux to open source RISC-V platform30

尚未有邦友留言

立即登入留言