阅读本文前,请先查看 《SPIKE源码编译与使用(一)》。
1 介绍
本文主要介绍,SPIKE模拟器运行Linux Kernel,也就是spike+bbl的情况。
通常启动流程为:Bootloader+Kernel+File System。
- BBL,就相当于是Bootloader。
- Kernel和File System,既可以为2个独立的可执行文件,也可以集成为一个文件。本例这里,要求集成为一个文件。
- 此外,Kernel和File System集成的单文件,最终还要被包含在BBL中,可以在riscv-pk编译时,进行指定。
因此,最后BBL文件内的,组成结构,大概如下所示:
接下来,主要有三个部分需要介绍:制作文件系统、编译linux kernel、编译riscv-pk,最后组合成一个单文件bbl,就可以在SPIKE上运行。
2 制作文件系统
2.1 编译busybox
下载busybox源码
git clone https://git.busybox.net/busybox
cd busybox
打开busybox配置界面
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
这里下载riscv64-unknown-linux-gnu交叉编译器。
安装过程,可参考《TinyEMU之Linux Kernel编译》。
配置为生成静态二进制可执行程序,选择“Build static binary (no shared libs)”
执行编译与安装
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j`nproc`
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- install -j`nproc`
cd ..
源码目录下,生成了二进制文件: busybox。
2.2 创建文件系统目录结构
创建主要目录
mkdir root && cd root
mkdir -p bin etc etc/init.d dev lib proc opt sbin sys tmp usr usr/bin usr/lib usr/sbin
创建初始化脚本
vim etc/init.d/rcS
在rcS中填入如下内容
#!/bin/sh
busybox ln -s /bin/busybox /bin/ln
ln -s /bin/busybox /bin/mount
ln -s /bin/busybox /bin/ls
ln -s /bin/busybox /bin/mknod
ln -s /bin/busybox /bin/chmod
mount -t proc none /proc
mount -t sysfs none /sys
mknod /dev/null c 1 3
chmod 666 /dev/null
ln -s /dev/null /dev/tty2
ln -s /dev/null /dev/tty3
ln -s /dev/null /dev/tty4
在这个脚本中,添加所有用于初始化的符号链接。
所有标准的Linux命令都在busybox文件中,因此要访问它们,我们需要在命令之前使用busybox。为了消除这种情况,有必要添加符号链接,例如ln -s /bin/busybox /bin/ls。
将busybox文件复制到bin路径中,并生成指向init文件的符号链接
cp /path/to/busybox/busybox bin/busybox
ln -s ../bin/busybox sbin/init
ln -s sbin/init init
cd bin/
ln -s busybox sh
cd ..
sudo mknod dev/console c 5 1
此时root目录结构,如下所示:
将root目录,合并成一个文件。
find . | cpio --quiet -o -H newc > ../rootfs.cpio
cd ..
生成了rootfs.cpio文件。
3 编译linux kernel
下载最新版linux kernel源码
git clone https://github.com/torvalds/linux.git
拷贝rootfs.cpio到linux kernel源码目录
cp rootfs.cpio linux/rootfs.cpio
cd linux
打开linux kernel配置界面
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
将General setup->Initial RAM filesystem and RAM disk (initramfs/initrd) support->Initramfs source file(s),配置为rootfs.cpio
表示,将文件系统rootfs.cpio,编译到kernel中。
执行编译
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j`nproc` vmlinux
生成了vmlinux。
4 编译riscv-pk
下载riscv-pk源码
git clone https://github.com/riscv/riscv-pk.git
mkdir riscv-pk/build && cd riscv-pk/build
用生成的Linux内核映像编译制作pk和bbl
../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu --with-payload=/path/to/Linux/Kernel/vmlinux
make -j`nproc`
make install
在riscv-pk/build目录下,生成了bbl,这里将kernel编译进了bbl中。
5 spike运行kernel
运行bbl
./spike bbl
运行效果,如下:
可以看到进入了kernel,但是我在做实验时,并不能进入命令终端,最后卡在了kernel的某个位置(cpuidle: using governor menu
),可能是linux kernel配置问题。但是spike运行kernel的步骤,就是上述内容。
这里,贴出完整linux kernel日志:
[ 0.000000] Linux version 6.9.0-rc6-00022-g98369dccd2f8 (root@Linux) (riscv64-unknown-linux-gnu-gcc (g2ee5e430018) 12.2.0, GNU ld (GNU Binutils) 2.39) #1 SMP Tue Apr 30 18:06:22 CST 2024
[ 0.000000] Machine model: ucbbar,spike-bare
[ 0.000000] SBI specification v0.1 detected
[ 0.000000] earlycon: ns16550a0 at MMIO 0x0000000010000000 (options '')
[ 0.000000] printk: legacy bootconsole [ns16550a0] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080000000-0x00000000ffffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080000000-0x00000000ffffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000ffffffff]
[ 0.000000] Falling back to deprecated "riscv,isa"
[ 0.000000] riscv: base ISA extensions acdfim
[ 0.000000] riscv: ELF capabilities acdfim
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] percpu: Embedded 22 pages/cpu s49400 r8192 d32520 u90112
[ 0.000000] Kernel command line: console=ttyS0 earlycon
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 516096
[ 0.000000] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] fixmap : 0xffffffc6fea00000 - 0xffffffc6ff000000 (6144 kB)
[ 0.000000] pci io : 0xffffffc6ff000000 - 0xffffffc700000000 ( 16 MB)
[ 0.000000] vmemmap : 0xffffffc700000000 - 0xffffffc800000000 (4096 MB)
[ 0.000000] vmalloc : 0xffffffc800000000 - 0xffffffd800000000 ( 64 GB)
[ 0.000000] modules : 0xffffffff01586000 - 0xffffffff80000000 (2026 MB)
[ 0.000000] lowmem : 0xffffffd800000000 - 0xffffffd880000000 (2048 MB)
[ 0.000000] kernel : 0xffffffff80000000 - 0xffffffffffffffff (2047 MB)
[ 0.000000] Memory: 2022272K/2097152K available (9598K kernel code, 4329K rwdata, 4096K rodata, 2873K init, 499K bss, 74880K 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=64 to nr_cpu_ids=1.
[ 0.000000] rcu: RCU debug extended QS entry/exit.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 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] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] remote fence extension is not available in SBI v0.1
[ 0.000000] riscv-intc: 64 local interrupts mapped
[ 0.000000] riscv: providing IPIs using SBI IPI extension
[ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
[ 0.000000] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns
[ 0.000015] Timer extension is not available in SBI v0.1
[ 0.000030] Timer extension is not available in SBI v0.1
[ 0.000045] Timer extension is not available in SBI v0.1
[ 0.000155] Console: colour dummy device 80x25
[ 0.000180] remote fence extension is not available in SBI v0.1
[ 0.000195] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[ 0.000215] pid_max: default: 32768 minimum: 301
[ 0.000270] LSM: initializing lsm=capability
[ 0.000335] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.000360] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.000940] remote fence extension is not available in SBI v0.1
[ 0.001000] remote fence extension is not available in SBI v0.1
[ 0.001065] remote fence extension is not available in SBI v0.1
[ 0.001135] remote fence extension is not available in SBI v0.1
[ 0.001205] remote fence extension is not available in SBI v0.1
[ 0.001275] remote fence extension is not available in SBI v0.1
[ 0.001350] remote fence extension is not available in SBI v0.1
[ 0.001425] remote fence extension is not available in SBI v0.1
[ 0.001480] remote fence extension is not available in SBI v0.1
[ 0.001565] remote fence extension is not available in SBI v0.1
[ 0.001640] remote fence extension is not available in SBI v0.1
[ 0.001720] remote fence extension is not available in SBI v0.1
[ 0.001775] riscv: ELF compat mode unsupported
[ 0.001780] remote fence extension is not available in SBI v0.1
[ 0.001805] remote fence extension is not available in SBI v0.1
[ 0.001820] remote fence extension is not available in SBI v0.1
[ 0.001830] remote fence extension is not available in SBI v0.1
[ 0.001845] remote fence extension is not available in SBI v0.1
[ 0.001860] remote fence extension is not available in SBI v0.1
[ 0.001875] ASID allocator using 16 bits (65536 entries)
[ 0.001980] remote fence extension is not available in SBI v0.1
[ 0.002050] rcu: Hierarchical SRCU implementation.
[ 0.002060] rcu: Max phase no-delay instances is 1000.
[ 0.002090] remote fence extension is not available in SBI v0.1
[ 0.002155] remote fence extension is not available in SBI v0.1
[ 0.002225] remote fence extension is not available in SBI v0.1
[ 0.002295] remote fence extension is not available in SBI v0.1
[ 0.002375] EFI services will not be available.
[ 0.002415] remote fence extension is not available in SBI v0.1
[ 0.002475] smp: Bringing up secondary CPUs ...
[ 0.002490] smp: Brought up 1 node, 1 CPU
[ 0.002820] remote fence extension is not available in SBI v0.1
[ 0.002915] devtmpfs: initialized
[ 0.003550] remote fence extension is not available in SBI v0.1
[ 0.003730] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.003755] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 0.003855] pinctrl core: initialized pinctrl subsystem
[ 0.004820] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.005060] remote fence extension is not available in SBI v0.1
[ 0.005075] remote fence extension is not available in SBI v0.1
[ 0.005090] DMA: preallocated 256 KiB GFP_KERNEL pool for atomic allocations
[ 0.005115] remote fence extension is not available in SBI v0.1
[ 0.005135] remote fence extension is not available in SBI v0.1
[ 0.005150] DMA: preallocated 256 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[ 0.005180] audit: initializing netlink subsys (disabled)
[ 0.005225] remote fence extension is not available in SBI v0.1
[ 0.005275] remote fence extension is not available in SBI v0.1
[ 0.005685] thermal_sys: Registered thermal governor 'step_wise'
[ 0.005700] audit: type=2000 audit(0.000:1): state=initialized audit_enabled=0 res=1
[ 0.005735] cpuidle: using governor menu
参考链接: