在qemu上启动linux kernel
总述
最终目标还是要在RTL上跑linux系统,但做这个之前第一步先把系统工具链整清楚很重要,所以先在qemu上把相关的工具链,镜像搞定。
为了完全这项任务,我们需要安装几个工具, qemu for riscv, linux kernel, boot loader, toolbox
level | endcoding | Name | Abbreviation |
---|---|---|---|
0 | 00 | User/Application | U |
1 | 01 | Supervisor | S |
2 | 10 | Reserved | |
3 | 11 | Machine | M |
如上图所示, riscv包含3个特权等级,OS运行在Superviosr级上, bootloader和其他固件运行在Machine级上, 用户程序运行在User级上。
工作目录
首先我们建立一个工作目录
mkdir riscv-linux
cd riscv-linux
安装qemu for riscv
我们统一选项只安装64版本, 目录到和riscv toolschian相同目录里
git clone https://github.com/qemu/qemu
cd qemu
git checkout v5.0.0
./configure --target-list=riscv64-softmmu --prefix=${RISCV}
make
make install
编译生成linux kernel
回到工作目录riscv-linux
git clone https://github.com/torvalds/linux
cd linux
git checkout v5.4
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu-
生成的kernel image在arch/riscv/boot/Image
SBI
SBI 是 RISC-V Supervisor Binary Interface的简称, 它是一个中间接口:
- firmware和bootloader, OS之间的接口
- 一个Hypervisor和bootloader或运行在VS-mode下的OS之间的接口
cd opensbi
make PLATFORM=generic CROSS_COMPILE=riscv64-unknown-linux-gnu- PLATFORM_RISCV_XLEN=64 FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image
生成的bin文件在./build/platform/generic/firmware/fw_jump.bin
生成busybox并制作文件系统
git clone https://git.busybox.net/busybox
cd busybox
CROSS_COMPILE=riscv{{bits}}-unknown-linux-gnu- make menuconfig
# 打开配置菜单后进入第一行的 "Settings",在"Build Options"节中,选中 “Build static binary (no shared libs)”,设置好后退出保存配置
CROSS_COMPILE=riscv{{bits}}-unknown-linux-gnu- make
make install
# 源码目录 busyboxsource 下新出现一个 _install 目录 ,可以看到生成的东西
下面我们就要制作最小文件系统
qemu-img create rootfs.img 1g
mkfs.ext4 rootfs.img
mkdir rootfs
sudo mount -o loop rootfs.img rootfs
cd rootfs
sudo cp -r ../busyboxsource/_install/* .
sudo mkdir proc sys dev etc etc/init.d
cd etc/init.d/
sudo touch rcS
sudo vi rcS
编译内容如下:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
然后修改文件权限
sudo mod +x rcS
sudo umount rootfs
至此文件系统就制作完成了
启动
回到riscv-linux目录, 执行下面命令立即就打印相关启动信息
qemu-system-riscv64 -M virt -m 256M -nographic -bios opensbi/build/platform/generic/firmware/fw_jump.bin -kernel ./linux/arch/riscv/boot/Image -drive file=./rootfs.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0"
下面是打印的信息, 暂停时输入回车就进行了熟悉的shell命令行下。
# harriszh @ pc-harriszh2 in /trunk/branch/riscv [20:44:07]
$ qemu-system-riscv64 -M virt -m 256M -nographic -bios opensbi/build/platform/generic/firmware/fw_jump.bin -kernel ./linux/arch/riscv/boot/Image -drive file=./rootfs.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0"
OpenSBI v0.8-58-g781cafd
____ _____ ____ _____
/ __ / ____| _ _ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ / _ '_ ___ | _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
____/| .__/ ___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : timer,mfdeleg
Platform HART Count : 1
Firmware Base : 0x80000000
Firmware Size : 108 KB
Runtime SBI Version : 0.2
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*
Domain0 Region00 : 0x0000000080000000-0x000000008001ffff ()
Domain0 Region01 : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address : 0x0000000080200000
Domain0 Next Arg1 : 0x0000000082200000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART ISA : rv64imafdcsu
Boot HART Features : scounteren,mcounteren,time
Boot HART PMP Count : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count : 0
Boot HART MHPM Count : 0
Boot HART MIDELEG : 0x0000000000000222
Boot HART MEDELEG : 0x000000000000b109
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[ 0.000000] Linux version 5.4.0 (harriszh@pc-harriszh2) (gcc version 10.2.0 (GCC)) #1 SMP Sat Nov 28 13:48:10 CST 2020
[ 0.000000] initrd not found or empty - disabling initrd
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080200000-0x000000008fffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080200000-0x000000008fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000008fffffff]
[ 0.000000] software IO TLB: mapped [mem 0x8bc7a000-0x8fc7a000] (64MB)
[ 0.000000] elf_hwcap is 0x112d
[ 0.000000] percpu: Embedded 17 pages/cpu s30680 r8192 d30760 u69632
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 64135
[ 0.000000] Kernel command line: root=/dev/vda rw console=ttyS0
[ 0.000000] Dentry cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[ 0.000000] Sorting __ex_table...
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 181052K/260096K available (6167K kernel code, 387K rwdata, 1962K rodata, 213K init, 305K bss, 79044K 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: 0, nr_irqs: 0, preallocated irqs: 0
[ 0.000000] plic: mapped 53 interrupts with 1 handlers for 2 contexts.
[ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
[ 0.000084] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns
[ 0.003039] Console: colour dummy device 80x25
[ 0.004051] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[ 0.004169] pid_max: default: 32768 minimum: 301
[ 0.005060] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.005089] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.027241] rcu: Hierarchical SRCU implementation.
[ 0.028802] smp: Bringing up secondary CPUs ...
[ 0.028883] smp: Brought up 1 node, 1 CPU
[ 0.036075] devtmpfs: initialized
[ 0.040712] random: get_random_u32 called from bucket_table_alloc.isra.0+0x4e/0x154 with crng_init=0
[ 0.042384] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.042546] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 0.045024] NET: Registered protocol family 16
[ 0.078034] vgaarb: loaded
[ 0.078849] SCSI subsystem initialized
[ 0.080125] usbcore: registered new interface driver usbfs
[ 0.080352] usbcore: registered new interface driver hub
[ 0.080466] usbcore: registered new device driver usb
[ 0.086693] clocksource: Switched to clocksource riscv_clocksource
[ 0.098120] NET: Registered protocol family 2
[ 0.101335] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.101409] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.101553] TCP bind hash table entries: 2048 (order: 3, 32768 bytes, linear)
[ 0.101679] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.102935] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.103101] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.104159] NET: Registered protocol family 1
[ 0.106058] RPC: Registered named UNIX socket transport module.
[ 0.106109] RPC: Registered udp transport module.
[ 0.106120] RPC: Registered tcp transport module.
[ 0.106130] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.106204] PCI: CLS 0 bytes, default 64
[ 0.111668] workingset: timestamp_bits=62 max_order=16 bucket_order=0
[ 0.120454] NFS: Registering the id_resolver key type
[ 0.121100] Key type id_resolver registered
[ 0.121132] Key type id_legacy registered
[ 0.121218] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 0.121748] 9p: Installing v9fs 9p2000 file system support
[ 0.122715] NET: Registered protocol family 38
[ 0.122915] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[ 0.123007] io scheduler mq-deadline registered
[ 0.123065] io scheduler kyber registered
[ 0.124868] pci-host-generic 30000000.pci: host bridge /soc/pci@30000000 ranges:
[ 0.126286] pci-host-generic 30000000.pci: IO 0x03000000..0x0300ffff -> 0x00000000
[ 0.126630] pci-host-generic 30000000.pci: MEM 0x40000000..0x7fffffff -> 0x40000000
[ 0.128296] pci-host-generic 30000000.pci: ECAM at [mem 0x30000000-0x3fffffff] for [bus 00-ff]
[ 0.128985] pci-host-generic 30000000.pci: PCI host bridge to bus 0000:00
[ 0.129117] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.129205] pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
[ 0.129218] pci_bus 0000:00: root bus resource [mem 0x40000000-0x7fffffff]
[ 0.129911] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
[ 0.176526] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 0.181177] printk: console [ttyS0] disabled
[ 0.181916] 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 10, base_baud = 230400) is a 16550A
[ 0.194577] printk: console [ttyS0] enabled
[ 0.196238] [drm] radeon kernel modesetting enabled.
[ 0.208747] loop: module loaded
[ 0.218802] virtio_blk virtio0: [vda] 2097152 512-byte logical blocks (1.07 GB/1.00 GiB)
[ 0.237502] libphy: Fixed MDIO Bus: probed
[ 0.238225] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[ 0.238402] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[ 0.238741] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.238903] ehci-pci: EHCI PCI platform driver
[ 0.239112] ehci-platform: EHCI generic platform driver
[ 0.239558] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.239747] ohci-pci: OHCI PCI platform driver
[ 0.239967] ohci-platform: OHCI generic platform driver
[ 0.240461] usbcore: registered new interface driver uas
[ 0.240688] usbcore: registered new interface driver usb-storage
[ 0.241550] mousedev: PS/2 mouse device common for all mice
[ 0.242575] usbcore: registered new interface driver usbhid
[ 0.242704] usbhid: USB HID core driver
[ 0.244104] NET: Registered protocol family 10
[ 0.248951] Segment Routing with IPv6
[ 0.250166] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[ 0.253011] NET: Registered protocol family 17
[ 0.254283] 9pnet: Installing 9P2000 support
[ 0.254605] Key type dns_resolver registered
[ 0.289007] EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null)
[ 0.289554] VFS: Mounted root (ext4 filesystem) on device 254:0.
[ 0.292116] devtmpfs: mounted
[ 0.309109] Freeing unused kernel memory: 212K
[ 0.309271] This architecture does not have kernel memory protection.
[ 0.309452] Run /sbin/init as init process
Please press Enter to activate this console.
/ # ls
bin etc lost+found sbin usr
dev linuxrc proc sys
如果要退出系统,输入poweroff
/ # poweroff
/ # umount: devtmpfs busy - remounted read-only
[ 112.461233] EXT4-fs (vda): re-mounted. Opts: (null)
swapoff: can't open '/etc/fstab': No such file or directory
The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Requesting system poweroff
[ 114.487435] reboot: Power down