基于QEMU搭建RISC-V的Linux环境
基于QEMU搭建RISC-V的Linux环境
背景
和之前搭建x86的类似(基于QEMU的内核调试环境搭建),只是需要交叉编译即可,重点其实是在交叉编译工具链。
前提:QEMU已安装好!
准备工具链
RISC-V支持GNU工具链和LLVM工具链,目前主流Linux发行版好像都没有预编译的二进制包可以下载安装,只能自己通过源码编译安装。
获取工具链源码
$ git clone https://gitee.com/mirrors/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
注意上面 clone 的主仓库并不包含子仓库的内容,所以需要继续更新子仓库。注意这里首先排除了 qemu 这个子仓库,一来因为 qemu 完整下载太大;二来 qemu 对 toolchain 的编译本身来说其实并不需要。
$ git rm qemu
$ git submodule update --init --recursive
上面的过程可能要点时间,需要耐心等待。。。
编译安装工具链
riscv-gnu-toolchain
工具链分 elf-gcc、linux-gnu-gcc 两个版本,以及对应的32位和64位版本。两个版本的主要区别是:
riscv32-unknown-elf-gcc
、riscv64-unknown-elf-gcc
使用的是riscv-newlib库(面向嵌入式的C库),只支持静态链接,不支持动态链接。riscv32-unknown-linux-gnu-gcc
、riscv64-unknown-linux-gnu-gcc
使用的是glibc标准库,支持动态链接。
这里默认编译64位的linux-gnu-gcc版本。
安装相应依赖包
$ sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev
配置编译
#配置,这里默认构建64位的交叉编译器,安装到/opt/riscv,
#若构建32位,添加--with-arch=rv32gc --with-abi=ilp32d
#若构建同时支持32位和64位,添加--enable-multilib
$ ./configure --prefix=/opt/riscv
#编译linux-gnu-gcc版本
$ sudo make linux -j $(nproc)
导出 toolchain 的安装路径
$ export PATH="$PATH:/opt/riscv/bin"
也可以写入 .bashrc
文件
测试 toolchain 是否安装成功
$ riscv64-unknown-linux-gnu-gcc -v
准备riscv内核
进入内核源码,使用riscv编译链重新配置并交叉编译内核
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j $(nproc)
准备riscv文件系统
这里简单编译个busybox。
#配置
$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make menuconfig
#select `Settings -> Build Options -> Build static binary (no shared libs)`
#编译安装
$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make -j $(nproc)
$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make install
后面的步骤与之前的一样,这里不在赘述。最终生成img文件:riscv-rootfs.img
运行qemu
与之前类似,换成riscv64的qemu,使能虚拟化,换内核和文件系统即可。
$ qemu-system-riscv64 -M virt -m 256M \
-kernel ./RISC-V-Image \
-drive file=riscv-rootfs.img,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0" \
-nographic
启动log如下:
OpenSBI v0.9
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : timer,mfdeleg
Platform HART Count : 1
Firmware Base : 0x80000000
Firmware Size : 100 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 : 0x000000008f000000
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] Linux version 6.8.0-rc7 (zdd@zhaodongdong) (riscv64-unknown-linux-gnu-gcc (GCC) 13.2.0, GNU ld (GNU Binutils) 2.42) #1 SMP Tue Mar 12 10:24:27 CST 2024
[ 0.000000] Machine model: riscv-virtio,qemu
[ 0.000000] SBI specification v0.2 detected
[ 0.000000] SBI implementation ID=0x1 Version=0x9
[ 0.000000] SBI TIME extension detected
[ 0.000000] SBI IPI extension detected
[ 0.000000] SBI RFENCE extension detected
[ 0.000000] efi: UEFI not found.
[ 0.000000] OF: reserved mem: 0x0000000080000000..0x000000008001ffff (128 KiB) map non-reusable mmode_resv0@80000000
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080000000-0x000000008fffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080000000-0x000000008fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000008fffffff]
[ 0.000000] SBI HSM extension detected
[ 0.000000] Falling back to deprecated "riscv,isa"
[ 0.000000] riscv: base ISA extensions acdfim
[ 0.000000] riscv: ELF capabilities acdfim
[ 0.000000] percpu: Embedded 20 pages/cpu s41464 r8192 d32264 u81920
[ 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] Built 1 zonelists, mobility grouping on. Total pages: 64512
[ 0.000000] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] fixmap : 0xff1bfffffea00000 - 0xff1bffffff000000 (6144 kB)
[ 0.000000] pci io : 0xff1bffffff000000 - 0xff1c000000000000 ( 16 MB)
[ 0.000000] vmemmap : 0xff1c000000000000 - 0xff20000000000000 (1024 TB)
[ 0.000000] vmalloc : 0xff20000000000000 - 0xff60000000000000 (16384 TB)
[ 0.000000] modules : 0xffffffff01583000 - 0xffffffff80000000 (2026 MB)
[ 0.000000] lowmem : 0xff60000000000000 - 0xff60000010000000 ( 256 MB)
[ 0.000000] kernel : 0xffffffff80000000 - 0xffffffffffffffff (2047 MB)
[ 0.000000] Memory: 218468K/262144K available (9666K kernel code, 4955K rwdata, 4096K rodata, 2241K init, 491K bss, 43676K 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] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] riscv-intc: 64 local interrupts mapped
[ 0.000000] plic: plic@c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
[ 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.000074] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns
[ 0.004121] Console: colour dummy device 80x25
[ 0.008016] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[ 0.008151] pid_max: default: 32768 minimum: 301
[ 0.009251] LSM: initializing lsm=capability,integrity
[ 0.011286] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.011322] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.039513] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
[ 0.039978] riscv: ELF compat mode unsupported
[ 0.040427] ASID allocator using 16 bits (65536 entries)
[ 0.041448] rcu: Hierarchical SRCU implementation.
[ 0.041482] rcu: Max phase no-delay instances is 1000.
[ 0.044669] EFI services will not be available.
[ 0.046414] smp: Bringing up secondary CPUs ...
[ 0.047003] smp: Brought up 1 node, 1 CPU
[ 0.057361] devtmpfs: initialized
[ 0.065618] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.065860] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[ 0.067674] pinctrl core: initialized pinctrl subsystem
[ 0.073393] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.081280] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[ 0.081527] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[ 0.081789] audit: initializing netlink subsys (disabled)
[ 0.085115] thermal_sys: Registered thermal governor 'step_wise'
[ 0.085772] audit: type=2000 audit(0.076:1): state=initialized audit_enabled=0 res=1
[ 0.086264] cpuidle: using governor menu
[ 0.109076] cpu0: Ratio of byte access time to unaligned word access is 7.31, unaligned accesses are fast
[ 0.121282] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
[ 0.121311] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
[ 0.125746] ACPI: Interpreter disabled.
[ 0.126171] iommu: Default domain type: Translated
[ 0.126203] iommu: DMA domain TLB invalidation policy: strict mode
[ 0.128178] SCSI subsystem initialized
[ 0.130077] usbcore: registered new interface driver usbfs
[ 0.130297] usbcore: registered new interface driver hub
[ 0.130437] usbcore: registered new device driver usb
[ 0.132032] Advanced Linux Sound Architecture Driver Initialized.
[ 0.142630] vgaarb: loaded
[ 0.145363] clocksource: Switched to clocksource riscv_clocksource
[ 0.147855] pnp: PnP ACPI: disabled
[ 0.165540] NET: Registered PF_INET protocol family
[ 0.166439] IP idents hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.170945] tcp_listen_portaddr_hash hash table entries: 128 (order: 0, 4096 bytes, linear)
[ 0.171040] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 0.171092] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.171256] TCP bind hash table entries: 2048 (order: 5, 131072 bytes, linear)
[ 0.171485] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.172496] UDP hash table entries: 256 (order: 2, 24576 bytes, linear)
[ 0.172805] UDP-Lite hash table entries: 256 (order: 2, 24576 bytes, linear)
[ 0.173823] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.176679] RPC: Registered named UNIX socket transport module.
[ 0.176737] RPC: Registered udp transport module.
[ 0.176749] RPC: Registered tcp transport module.
[ 0.176759] RPC: Registered tcp-with-tls transport module.
[ 0.176767] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.176895] PCI: CLS 0 bytes, default 64
[ 0.183249] workingset: timestamp_bits=46 max_order=16 bucket_order=0
[ 0.186700] NFS: Registering the id_resolver key type
[ 0.187526] Key type id_resolver registered
[ 0.187558] Key type id_legacy registered
[ 0.187813] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 0.187891] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[ 0.188447] 9p: Installing v9fs 9p2000 file system support
[ 0.189930] NET: Registered PF_ALG protocol family
[ 0.190189] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
[ 0.190317] io scheduler mq-deadline registered
[ 0.190379] io scheduler kyber registered
[ 0.190470] io scheduler bfq registered
[ 0.193851] pci-host-generic 30000000.pci: host bridge /soc/pci@30000000 ranges:
[ 0.194486] pci-host-generic 30000000.pci: IO 0x0003000000..0x000300ffff -> 0x0000000000
[ 0.194858] pci-host-generic 30000000.pci: MEM 0x0040000000..0x007fffffff -> 0x0040000000
[ 0.194921] pci-host-generic 30000000.pci: MEM 0x0400000000..0x07ffffffff -> 0x0400000000
[ 0.195345] pci-host-generic 30000000.pci: Memory resource size exceeds max for 32 bits
[ 0.195721] pci-host-generic 30000000.pci: ECAM at [mem 0x30000000-0x3fffffff] for [bus 00-ff]
[ 0.197020] pci-host-generic 30000000.pci: PCI host bridge to bus 0000:00
[ 0.197229] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.197300] pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
[ 0.197337] pci_bus 0000:00: root bus resource [mem 0x40000000-0x7fffffff]
[ 0.197347] pci_bus 0000:00: root bus resource [mem 0x400000000-0x7ffffffff]
[ 0.198475] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000 conventional PCI endpoint
[ 0.295449] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 0.305384] printk: legacy console [ttyS0] disabled
[ 0.308167] 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 12, base_baud = 230400) is a 16550A
[ 0.309475] printk: legacy console [ttyS0] enabled
[ 0.330541] SuperH (H)SCI(F) driver initialized
[ 0.344441] loop: module loaded
[ 0.345367] virtio_blk virtio0: 1/0/0 default/read/poll queues
[ 0.348187] virtio_blk virtio0: [vda] 2097152 512-byte logical blocks (1.07 GB/1.00 GiB)
[ 0.369465] e1000e: Intel(R) PRO/1000 Network Driver
[ 0.369629] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[ 0.371734] usbcore: registered new interface driver uas
[ 0.372093] usbcore: registered new interface driver usb-storage
[ 0.373211] mousedev: PS/2 mouse device common for all mice
[ 0.376029] goldfish_rtc 101000.rtc: registered as rtc0
[ 0.376796] goldfish_rtc 101000.rtc: setting system clock to 2024-03-13T01:49:05 UTC (1710294545)
[ 0.380080] cpuidle-riscv-sbi: HSM suspend not available
[ 0.380747] sdhci: Secure Digital Host Controller Interface driver
[ 0.380923] sdhci: Copyright(c) Pierre Ossman
[ 0.381272] Synopsys Designware Multimedia Card Interface Driver
[ 0.381777] sdhci-pltfm: SDHCI platform and OF driver helper
[ 0.382516] usbcore: registered new interface driver usbhid
[ 0.382679] usbhid: USB HID core driver
[ 0.386321] NET: Registered PF_INET6 protocol family
[ 0.392319] Segment Routing with IPv6
[ 0.392739] In-situ OAM (IOAM) with IPv6
[ 0.393206] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[ 0.395810] NET: Registered PF_PACKET protocol family
[ 0.397131] 9pnet: Installing 9P2000 support
[ 0.397612] Key type dns_resolver registered
[ 0.426860] debug_vm_pgtable: [debug_vm_pgtable ]: Validating architecture page table helpers
[ 0.433147] Legacy PMU implementation is available
[ 0.434355] clk: Disabling unused clocks
[ 0.434665] ALSA device list:
[ 0.434783] No soundcards found.
[ 0.482664] EXT4-fs (vda): mounted filesystem 0032faeb-2db8-4c5f-9b58-f4a4889124fe r/w with ordered data mode. Quota mode: disabled.
[ 0.487994] VFS: Mounted root (ext4 filesystem) on device 254:0.
[ 0.490614] devtmpfs: mounted
[ 0.518466] Freeing unused kernel image (initmem) memory: 2240K
[ 0.519154] Run /sbin/init as init process
Please press Enter to activate this console.
~ #
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DD'Notes!
评论