Analysis of QEMU startup method: Introduction to QEMU and RISC-V startup process

Author: YJMSTR jay1273062855@outlook.com

Date: 2022/08/16

Revisor: Bin Meng, Falcon

Project: Anatomy of the RISC-V Linux Kernel

Sponsor: PLCT Lab, ISCAS

Analysis of QEMU startup method (1): Introduction to QEMU and RISC-V startup process

The software versions used are as follows:

QEMU: v7.0.0

OpenSBI: v1.1

U-Boot: v2022.04

Linux Kernel: v5.18

Introduction to QEMU

What is QEMU

QEMU (Quick Emulator) is an open source general-purpose machine emulator and virtualization tool that mainly supports the following usage methods:

  • User Mode Emulation: In this emulation mode, QEMU can run programs compiled for a CPU of one architecture on a CPU of another architecture.
  • System Emulation: In this emulation mode, QEMU provides the complete environment required to run the client, including CPU, memory, and peripherals.

When using QEMU to simulate the RISC-V architecture, QEMU can provide a virt virtual development board, which does not correspond to any hardware in reality, but it supports simulating a variety of hardware devices. When analyzing the startup method of QEMU next, this series of articles uses the QEMU 'virt' machine as the experimental platform. Linux Lab also provides two virtual development boards, riscv32/virt and riscv64/virt, which can be used for RISC-V learning.

QEMU RISC-V environment build

QEMU is integrated in Linux Lab, which supports one-key automatic compilation and other functions. For details, please refer to Linux Lab Official Manual , the current Linux Lab version is v1.0.

The process to download and build QEMU with RISC-V support is as follows:

$ wget https://download.qemu.org/qemu-7.0.0.tar.xz
$ tar xvJf qemu-7.0.0.tar.xz
$ cd qemu-7.0.0
$ ./configure --target-list="riscv32-softmmu riscv64-softmmu"
$ make -j $(nproc)
$ make install

After the installation is complete, enter qemu-system-riscv64 --version in the terminal. If the following text is displayed, the installation is successful:

QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers

Introduction to the RISC-V startup process

As shown in the figure below, the RISC-V boot process is divided into multiple stages, and we focus on OpenSBI and U-Boot.


)

ZSBL

ZSBL (Zero Stage Boot Loader) gets the core code from ROM.

FSBL:U-Boot SPL

FSBL (First Stage Boot Loader) is specified by Soc and may be CoreBoot or U-Boot SPL. This stage will complete the initialization of the DDR and load the runtime and bootloader.

Among them, U-Boot SPL is a very small loader program whose main function is to load the real U-Boot and run it. The specific loading process can refer to RISC-V UEFI Architecture Support Explained, Part 1 - Introduction to OpenSBI/U-Boot/UEFI - Tinylab.org in the U-Boot related section. OpenSBI needs to be compiled before compiling U-Boot.

Runtime:OpenSBI

The Runtime of RISC-V is usually OpenSBI, which is a program running in M ​​mode, but can provide some specific services for S mode, which are defined by the SBI (Supervisor Binary Interface) specification.

SBI refers to Supervisor Binary Interface, which is a program running in M ​​mode. The operating system calls the hardware resources of M mode through SBI. OpenSBI refers to an open source SBI implementation developed by Western Digital. RISC-V OpenSBI Quick Start - Tinylab.org This article gives a tutorial on compiling and running OpenSBI in Linux Lab.

OpenSBI has three kinds of Firmware:

  • FW_PAYLOAD : The next boot stage is packaged as a payload, usually U-Boot or Linux. This is the default firmware used by Linux-compatible RISC-V hardware.
  • FW_JUMP : Jump to a fixed address where the next loader needs to be stored. Earlier versions of QEMU used to use it.
  • FW_DYNAMIC : Load the next stage based on the information passed in from the previous stage. Usually U-Boot SPL uses it. QEMU now uses FW_DYNAMIC by default.

The process of downloading and compiling OpenSBI is as follows:

$ git clone https://gitee.com/tinylab/qemu-opensbi.git
$ cd qemu-opensbi/
$ export CROSS_COMPILE=riscv64-linux-gnu-
$ make all PLATFORM=generic PLATFORM_RISCV_XLEN=64

where PLATFORM selects the generic platform required by qemu_virt.

Bootloader:U-Boot

Bootloader is a relatively early code executed after the embedded system is powered on. This program will complete the hardware initialization and environment settings, and then load the operating system image or embedded application into the memory, and then jump to the operation The space where the system is located, start the operating system.

U-Boot refers to Universal Boot Loader, which is a popular boot loader for embedded Linux systems. It is divided into two parts: U-Boot SPL and U-Boot, where SPL refers to the second-stage program loader (Secondary Program Loader).

U-Boot SPL has been introduced in the previous "FSBL/U-Boot SPL" section, here we mainly talk about U-Boot itself. After it is loaded into memory by U-Boot SPL, it will play the role of Bootloader. exist This article There is an analysis of the U-Boot loading process and code.

Download U-Boot:

$ git clone https://gitee.com/mirrors/u-boot.git
$ cd u-boot
$ git checkout v2022.04

In order to boot the RISC-V 64 architecture Linux through U-Boot, we need to select the cross-compilation toolchain riscv64-linux-gnu-gcc when compiling. Execute the following commands in the u-boot directory:

$ export CROSS_COMPILE=riscv64-linux-gnu-
$ make qemu-riscv64_smode_defconfig
$ make -j $(nproc)

If you want to boot the U-Boot image in S mode directly, use the following command:

$ qemu-system-riscv64 -M virt -smp 4 -m 2G \
    -display none -serial stdio \
    -kernel /path/to/u-boot.bin

Where /path/to/u-boot.bin refers to the path where the previously compiled u-boot.bin is located.

To start U-Boot or Linux, you need to specify the U-Boot or Linux payload path when compiling OpenSBI. Take U-Boot as an example, switch to the OpenSBI directory, and compile the command as follows:

$ export CROSS_COMPILE=riscv64-linux-gnu-
$ make PLATFORM=generic FW_PAYLOAD_PATH=<uboot_build_directory>/u-boot.bin

run:

$ qemu-system-riscv64 -M virt -m 256M -nographic \
	-bios build/platform/generic/firmware/fw_payload.elf

Or run with the following command:

$ qemu-system-riscv64 -M virt -m 256M -nographic \
	-bios build/platform/generic/firmware/fw_jump.bin \
	-kernel <uboot_build_directory>/u-boot.bin

If you want to use U-Boot SPL, use the following command:

$ export CROSS_COMPILE=riscv64-linux-gnu- 
$ cd /path/to/u-boot
$ export OPENSBI=/path/to/opensbi/build/platform/generic/firmware/fw_dynamic.bin
$ make qemu-riscv64_spl_defconfig
$ make -j $(nproc) 
$ qemu-system-riscv64 -M virt -smp 4 -m 2G \
    -display none -serial stdio \
    -bios /path/to/u-boot-spl \
    -device loader,file=/path/to/u-boot.itb,addr=0x80200000

OS:Linux

Compiling the kernel requires the use of a cross-compilation toolchain.

Execute the following command in the terminal:

$ mkdir linux-kernel
$ cd linux-kernel
$ git init
$ git fetch git@gitee.com:mirrors/linux_old1.git
// If it breaks, you can execute git fetch multiple times in order to resume the upload
$ git checkout v5.18

Then configure and compile the kernel:

$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j $(nproc)

The compiled kernel image is located in arch/riscv/boot/Image.

Then we use busybox to build the root file system rootfs, first download and compile busybox:

$ git clone https://gitee.com/mirrors/busyboxsource
$ cd busyboxsource
$ export CROSS_COMPILE=riscv64-linux-gnu-
$ make defconfig
$ make menuconfig
# The Build static binary (no shared libs) option in Settings-->Build Options is enabled here
$ make -j $(nproc)
$ make install

Make a filesystem and create a new startup script:

$ cd ~ 
$ 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

Edit the contents of the startup script rcS as follows:

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s

and modify the file permissions:

$ sudo chmod +x rcS
$ cd ~
$ sudo umount rootfs

Then try to boot the kernel directly:

$ qemu-system-riscv64 -M virt -m 256M -nographic \
	-kernel linux-kernel/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"

The startup log is as follows:

OpenSBI v1.0
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : riscv-virtio,qemu
Platform Features         : medeleg
Platform HART Count       : 1
Platform IPI Device       : aclint-mswi
Platform Timer Device     : aclint-mtimer @ 10000000Hz
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform Reboot Device    : sifive_test
Platform Shutdown Device  : sifive_test
Firmware Base             : 0x80000000
Firmware Size             : 252 KB
Runtime SBI Version       : 0.3

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000002000000-0x000000000200ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02          : 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             : rv64imafdcsuh
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 MIDELEG         : 0x0000000000001666
Boot HART MEDELEG         : 0x0000000000f0b509
[    0.000000] Linux version 5.18.0 (yjmstr@yjmstr) (riscv64-linux-gnu-gcc (Ubuntu 11.2.0-16ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #2 SMP Sun Aug 14 13:14:26 CST 2022
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] efi: UEFI not found.
[    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] SBI specification v0.3 detected
[    0.000000] SBI implementation ID=0x1 Version=0x10000
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI SRST extension detected
[    0.000000] SBI HSM extension detected
[    0.000000] riscv: base ISA extensions acdfhim
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 18 pages/cpu s34040 r8192 d31496 u73728
[    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] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0xff1bfffffee00000 - 0xff1bffffff000000   (2048 kB)
[    0.000000]       pci io : 0xff1bffffff000000 - 0xff1c000000000000   (  16 MB)
[    0.000000]      vmemmap : 0xff1c000000000000 - 0xff20000000000000   (1073741824 MB)
[    0.000000]      vmalloc : 0xff20000000000000 - 0xff60000000000000   (17179869184 MB)
[    0.000000]       lowmem : 0xff60000000000000 - 0xff6000000fe00000   ( 254 MB)
[    0.000000]       kernel : 0xffffffff80000000 - 0xffffffffffffffff   (2047 MB)
[    0.000000] Memory: 237564K/260096K available (6460K kernel code, 4865K rwdata, 2048K rodata, 2165K init, 334K bss, 22532K 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 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] random: get_random_bytes called from start_kernel+0x4be/0x71a 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: 0x24e6a1710, max_idle_ns: 440795202120 ns
[    0.000110] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns
[    0.005548] Console: colour dummy device 80x25
[    0.010694] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[    0.010903] pid_max: default: 32768 minimum: 301
[    0.014081] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.014137] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.045919] cblist_init_generic: Setting adjustable number of callback queues.
[    0.046122] cblist_init_generic: Setting shift to 0 and lim to 1.
[    0.046833] ASID allocator using 16 bits (65536 entries)
[    0.048191] rcu: Hierarchical SRCU implementation.
[    0.050214] EFI services will not be available.
[    0.052914] smp: Bringing up secondary CPUs ...
[    0.053035] smp: Brought up 1 node, 1 CPU
[    0.064892] devtmpfs: initialized
[    0.072338] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.072854] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[    0.078634] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.084802] cpuidle: using governor menu
[    0.116094] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.121303] iommu: Default domain type: Translated 
[    0.121359] iommu: DMA domain TLB invalidation policy: strict mode 
[    0.122808] SCSI subsystem initialized
[    0.124731] usbcore: registered new interface driver usbfs
[    0.125085] usbcore: registered new interface driver hub
[    0.125244] usbcore: registered new device driver usb
[    0.139845] vgaarb: loaded
[    0.141481] clocksource: Switched to clocksource riscv_clocksource
[    0.160052] NET: Registered PF_INET protocol family
[    0.161357] IP idents hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.165568] tcp_listen_portaddr_hash hash table entries: 128 (order: 0, 5120 bytes, linear)
[    0.165859] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.166095] TCP bind hash table entries: 2048 (order: 4, 65536 bytes, linear)
[    0.166331] TCP: Hash tables configured (established 2048 bind 2048)
[    0.168312] UDP hash table entries: 256 (order: 2, 24576 bytes, linear)
[    0.168666] UDP-Lite hash table entries: 256 (order: 2, 24576 bytes, linear)
[    0.170129] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.173256] RPC: Registered named UNIX socket transport module.
[    0.173403] RPC: Registered udp transport module.
[    0.173427] RPC: Registered tcp transport module.
[    0.173453] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.173613] PCI: CLS 0 bytes, default 64
[    0.180799] workingset: timestamp_bits=62 max_order=16 bucket_order=0
[    0.195702] NFS: Registering the id_resolver key type
[    0.196803] Key type id_resolver registered
[    0.196859] Key type id_legacy registered
[    0.197434] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.197557] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[    0.198259] 9p: Installing v9fs 9p2000 file system support
[    0.199780] NET: Registered PF_ALG protocol family
[    0.200339] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250)
[    0.200507] io scheduler mq-deadline registered
[    0.200597] io scheduler kyber registered
[    0.210780] pci-host-generic 30000000.pci: host bridge /soc/pci@30000000 ranges:
[    0.211790] pci-host-generic 30000000.pci:       IO 0x0003000000..0x000300ffff -> 0x0000000000
[    0.212339] pci-host-generic 30000000.pci:      MEM 0x0040000000..0x007fffffff -> 0x0040000000
[    0.212418] pci-host-generic 30000000.pci:      MEM 0x0400000000..0x07ffffffff -> 0x0400000000
[    0.213009] pci-host-generic 30000000.pci: Memory resource size exceeds max for 32 bits
[    0.214178] pci-host-generic 30000000.pci: ECAM at [mem 0x30000000-0x3fffffff] for [bus 00-ff]
[    0.215635] pci-host-generic 30000000.pci: PCI host bridge to bus 0000:00
[    0.215922] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.216027] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    0.216104] pci_bus 0000:00: root bus resource [mem 0x40000000-0x7fffffff]
[    0.216122] pci_bus 0000:00: root bus resource [mem 0x400000000-0x7ffffffff]
[    0.217645] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
[    0.293879] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.302601] printk: console [ttyS0] disabled
[    0.304582] 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 2, base_baud = 230400) is a 16550A
[    0.327092] printk: console [ttyS0] enabled
[    0.343852] loop: module loaded
[    0.347926] virtio_blk virtio0: [vda] 2097152 512-byte logical blocks (1.07 GB/1.00 GiB)
[    0.372012] e1000e: Intel(R) PRO/1000 Network Driver
[    0.372155] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    0.372587] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.372811] ehci-pci: EHCI PCI platform driver
[    0.373121] ehci-platform: EHCI generic platform driver
[    0.373489] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.373714] ohci-pci: OHCI PCI platform driver
[    0.374048] ohci-platform: OHCI generic platform driver
[    0.375168] usbcore: registered new interface driver uas
[    0.375509] usbcore: registered new interface driver usb-storage
[    0.376576] mousedev: PS/2 mouse device common for all mice
[    0.380046] goldfish_rtc 101000.rtc: registered as rtc0
[    0.380819] goldfish_rtc 101000.rtc: setting system clock to 2022-08-19T12:22:18 UTC (1660911738)
[    0.383918] syscon-poweroff soc:poweroff: pm_power_off already claimed for sbi_srst_power_off
[    0.384279] syscon-poweroff: probe of soc:poweroff failed with error -16
[    0.385888] sdhci: Secure Digital Host Controller Interface driver
[    0.386097] sdhci: Copyright(c) Pierre Ossman
[    0.386425] sdhci-pltfm: SDHCI platform and OF driver helper
[    0.387522] usbcore: registered new interface driver usbhid
[    0.387713] usbhid: USB HID core driver
[    0.388131] riscv-pmu-sbi: SBI PMU extension is available
[    0.388784] riscv-pmu-sbi: 15 firmware and 2 hardware counters
[    0.389008] riscv-pmu-sbi: Perf sampling/filtering is not supported as sscof extension is not available
[    0.393847] NET: Registered PF_INET6 protocol family
[    0.400899] Segment Routing with IPv6
[    0.401209] In-situ OAM (IOAM) with IPv6
[    0.401878] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    0.405085] NET: Registered PF_PACKET protocol family
[    0.406670] 9pnet: Installing 9P2000 support
[    0.407129] Key type dns_resolver registered
[    0.409166] debug_vm_pgtable: [debug_vm_pgtable         ]: Validating architecture page table helpers
[    0.473625] EXT4-fs (vda): mounted filesystem with ordered data mode. Quota mode: disabled.
[    0.474143] VFS: Mounted root (ext4 filesystem) on device 254:0.
[    0.477311] devtmpfs: mounted
[    0.507212] Freeing unused kernel image (initmem) memory: 2164K
[    0.508186] Run /sbin/init as init process

Please press Enter to activate this console. 

You can see that the OpenSBI version in the printed startup information is v1.0, which is the OpenSBI version that comes with QEMU v7.0.0. According to the official QEMU documentation, when the -bios boot parameter is not present, QEMU will load its own OpenSBI firmware. When using -bios none as the boot parameter, QEMU will not automatically load any firmware. When using -bios <file> to specify a specific file as firmware, QEMU will load the firmware we specified.

The command to boot the kernel with our own compiled OpenSBI is as follows:

$ qemu-system-riscv64 -M virt -m 256M -nographic \
	-bios qemu-opensbi/build/platform/generic/firmware/fw_jump.bin \
	-kernel linux-kernel/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"

Here, the fw_jump type firmware compiled by OpenSBI is specified by the -bios parameter. The startup log is as follows:

OpenSBI v1.1
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : riscv-virtio,qemu
Platform Features         : medeleg
Platform HART Count       : 1
Platform IPI Device       : aclint-mswi
Platform Timer Device     : aclint-mtimer @ 10000000Hz
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform Reboot Device    : sifive_test
Platform Shutdown Device  : sifive_test
Firmware Base             : 0x80000000
Firmware Size             : 288 KB
Runtime SBI Version       : 1.0

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000002000000-0x000000000200ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008007ffff ()
Domain0 Region02          : 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 Priv Version    : v1.10
Boot HART Base ISA        : rv64imafdch
Boot HART ISA Extensions  : time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 0
Boot HART MIDELEG         : 0x0000000000001666
Boot HART MEDELEG         : 0x0000000000f0b509
[    0.000000] Linux version 5.18.0 (yjmstr@yjmstr) (riscv64-linux-gnu-gcc (Ubuntu 11.2.0-16ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #2 SMP Sun Aug 14 13:14:26 CST 2022
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] efi: UEFI not found.
[    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] SBI specification v1.0 detected
[    0.000000] SBI implementation ID=0x1 Version=0x10001
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI SRST extension detected
[    0.000000] SBI HSM extension detected
[    0.000000] riscv: base ISA extensions acdfhim
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 18 pages/cpu s34040 r8192 d31496 u73728
[    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] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0xff1bfffffee00000 - 0xff1bffffff000000   (2048 kB)
[    0.000000]       pci io : 0xff1bffffff000000 - 0xff1c000000000000   (  16 MB)
[    0.000000]      vmemmap : 0xff1c000000000000 - 0xff20000000000000   (1073741824 MB)
[    0.000000]      vmalloc : 0xff20000000000000 - 0xff60000000000000   (17179869184 MB)
[    0.000000]       lowmem : 0xff60000000000000 - 0xff6000000fe00000   ( 254 MB)
[    0.000000]       kernel : 0xffffffff80000000 - 0xffffffffffffffff   (2047 MB)
[    0.000000] Memory: 237564K/260096K available (6460K kernel code, 4865K rwdata, 2048K rodata, 2165K init, 334K bss, 22532K 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 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] random: get_random_bytes called from start_kernel+0x4be/0x71a 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: 0x24e6a1710, max_idle_ns: 440795202120 ns
[    0.000111] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps every 4398046511100ns
[    0.005518] Console: colour dummy device 80x25
[    0.010392] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[    0.010596] pid_max: default: 32768 minimum: 301
[    0.013666] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.013719] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.045715] cblist_init_generic: Setting adjustable number of callback queues.
[    0.045930] cblist_init_generic: Setting shift to 0 and lim to 1.
[    0.046678] ASID allocator using 16 bits (65536 entries)
[    0.047947] rcu: Hierarchical SRCU implementation.
[    0.050035] EFI services will not be available.
[    0.052640] smp: Bringing up secondary CPUs ...
[    0.052761] smp: Brought up 1 node, 1 CPU
[    0.064569] devtmpfs: initialized
[    0.072062] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.072424] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[    0.078307] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.084426] cpuidle: using governor menu
[    0.114553] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.120275] iommu: Default domain type: Translated 
[    0.120336] iommu: DMA domain TLB invalidation policy: strict mode 
[    0.121627] SCSI subsystem initialized
[    0.123678] usbcore: registered new interface driver usbfs
[    0.124019] usbcore: registered new interface driver hub
[    0.124451] usbcore: registered new device driver usb
[    0.138626] vgaarb: loaded
[    0.140390] clocksource: Switched to clocksource riscv_clocksource
[    0.159138] NET: Registered PF_INET protocol family
[    0.160529] IP idents hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.164755] tcp_listen_portaddr_hash hash table entries: 128 (order: 0, 5120 bytes, linear)
[    0.165042] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.165279] TCP bind hash table entries: 2048 (order: 4, 65536 bytes, linear)
[    0.165513] TCP: Hash tables configured (established 2048 bind 2048)
[    0.167469] UDP hash table entries: 256 (order: 2, 24576 bytes, linear)
[    0.167823] UDP-Lite hash table entries: 256 (order: 2, 24576 bytes, linear)
[    0.169282] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.172534] RPC: Registered named UNIX socket transport module.
[    0.172606] RPC: Registered udp transport module.
[    0.172627] RPC: Registered tcp transport module.
[    0.172642] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.172794] PCI: CLS 0 bytes, default 64
[    0.180445] workingset: timestamp_bits=62 max_order=16 bucket_order=0
[    0.194614] NFS: Registering the id_resolver key type
[    0.195717] Key type id_resolver registered
[    0.195772] Key type id_legacy registered
[    0.196382] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.196504] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[    0.197282] 9p: Installing v9fs 9p2000 file system support
[    0.198830] NET: Registered PF_ALG protocol family
[    0.199384] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250)
[    0.199551] io scheduler mq-deadline registered
[    0.199638] io scheduler kyber registered
[    0.211458] pci-host-generic 30000000.pci: host bridge /soc/pci@30000000 ranges:
[    0.212538] pci-host-generic 30000000.pci:       IO 0x0003000000..0x000300ffff -> 0x0000000000
[    0.213088] pci-host-generic 30000000.pci:      MEM 0x0040000000..0x007fffffff -> 0x0040000000
[    0.213169] pci-host-generic 30000000.pci:      MEM 0x0400000000..0x07ffffffff -> 0x0400000000
[    0.213761] pci-host-generic 30000000.pci: Memory resource size exceeds max for 32 bits
[    0.214890] pci-host-generic 30000000.pci: ECAM at [mem 0x30000000-0x3fffffff] for [bus 00-ff]
[    0.216401] pci-host-generic 30000000.pci: PCI host bridge to bus 0000:00
[    0.216695] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.216802] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    0.216882] pci_bus 0000:00: root bus resource [mem 0x40000000-0x7fffffff]
[    0.216900] pci_bus 0000:00: root bus resource [mem 0x400000000-0x7ffffffff]
[    0.218331] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
[    0.294377] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.303136] printk: console [ttyS0] disabled
[    0.305194] 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 2, base_baud = 230400) is a 16550A
[    0.331363] printk: console [ttyS0] enabled
[    0.348432] loop: module loaded
[    0.352537] virtio_blk virtio0: [vda] 2097152 512-byte logical blocks (1.07 GB/1.00 GiB)
[    0.376684] e1000e: Intel(R) PRO/1000 Network Driver
[    0.376828] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    0.377400] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.377758] ehci-pci: EHCI PCI platform driver
[    0.378200] ehci-platform: EHCI generic platform driver
[    0.378530] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.378801] ohci-pci: OHCI PCI platform driver
[    0.379167] ohci-platform: OHCI generic platform driver
[    0.380468] usbcore: registered new interface driver uas
[    0.380919] usbcore: registered new interface driver usb-storage
[    0.382100] mousedev: PS/2 mouse device common for all mice
[    0.385879] goldfish_rtc 101000.rtc: registered as rtc0
[    0.386647] goldfish_rtc 101000.rtc: setting system clock to 2022-08-19T12:20:44 UTC (1660911644)
[    0.389614] syscon-poweroff soc:poweroff: pm_power_off already claimed for sbi_srst_power_off
[    0.389962] syscon-poweroff: probe of soc:poweroff failed with error -16
[    0.391492] sdhci: Secure Digital Host Controller Interface driver
[    0.391720] sdhci: Copyright(c) Pierre Ossman
[    0.392087] sdhci-pltfm: SDHCI platform and OF driver helper
[    0.393373] usbcore: registered new interface driver usbhid
[    0.393604] usbhid: USB HID core driver
[    0.394074] riscv-pmu-sbi: SBI PMU extension is available
[    0.394764] riscv-pmu-sbi: 16 firmware and 2 hardware counters
[    0.395033] riscv-pmu-sbi: Perf sampling/filtering is not supported as sscof extension is not available
[    0.399865] NET: Registered PF_INET6 protocol family
[    0.407267] Segment Routing with IPv6
[    0.407649] In-situ OAM (IOAM) with IPv6
[    0.408329] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    0.411565] NET: Registered PF_PACKET protocol family
[    0.413200] 9pnet: Installing 9P2000 support
[    0.413775] Key type dns_resolver registered
[    0.415916] debug_vm_pgtable: [debug_vm_pgtable         ]: Validating architecture page table helpers
[    0.504662] EXT4-fs (vda): mounted filesystem with ordered data mode. Quota mode: disabled.
[    0.505310] VFS: Mounted root (ext4 filesystem) on device 254:0.
[    0.529887] devtmpfs: mounted
[    0.559745] Freeing unused kernel image (initmem) memory: 2164K
[    0.560852] Run /sbin/init as init process

Please press Enter to activate this console. 

You can see that the OpenSBI version in the printed startup information is v1.1, which is the OpenSBI version we compiled by ourselves.

Summarize

This paper briefly introduces the startup process of RISC-V, the simple use of OpenSBI and U-Boot under QEMU'virt'platform, the fabrication of root file system and the guidance of Linux kernel, and analyses the different Behaviors when QEMU startup parameters are -bios or not. In the next article we will explore how to boot and load the Linux kernel through U-Boot, and analyze the behavior of the ZSBL stage in conjunction with QEMU'virt'.

References

  1. Linux Lab Official Manual
  2. RISC-V UEFI Architecture Support Explained, Part 1 - Introduction to OpenSBI/U-Boot/UEFI
  3. RISC-V OpenSBI Quick Start
  4. QEMU official documentation
  5. Build QEMU and boot openEuler for RISC-V in Taixiao Linux experimental disk
  6. Running RISC-V 64-bit version of Linux on QEMU
  7. RISC-V startup process
  8. RISC-V SBI official documentation
  9. OpenSBI Gitee Mirror
  10. Boot riscv-linux kernel with U-boot
  11. QEMU 6.1.0 running RISCV64 OpenSBI + U-Boot + Linux
  12. Booting RISC-V on QEMU
  13. Build a linux system running on riscv

Tags: risc-v U-boot qemu

Posted by atwyman on Thu, 15 Sep 2022 22:23:19 +0530