booting-test-kernel-in-qemu-using-uboot-and-rustsbi.md 7.2 KB

使用RustSBI & U-Boot SPL在QEMU中启动Test Kernel

本教程给出了使用RustSBI和U-Boot在QEMU中启动Test Kernel的基本流程。

其中启动流程分为两种类型:

  1. 只使用U-Boot SPL的启动流程
  2. 同时使用U-Boot SPL和U-Boot的启动流程。

请读者在其主机上安装必要的软件来尝试本教程的脚本。本教程是在Arch Linux上开发的。

环境配置小节给出了本教程的环境配置方法,用户在使用本教程时需要先完成环境配置小节内容。

使用U-Boot SPL启动Test Kernel小节给出了只使用U-Boot SPL的启动流程。

使用U-Boot SPL和U-Boot启动Test Kernel小节给出了同时使用U-Boot SPL和U-Boot的启动流程。

本教程使用软件版本如下:

软件 版本
riscv64-linux-gnu-gcc 14.1.0
qemu-system-riscv64 9.0.1
RustSBI Prototyper 0.0.0
U-Boot 2024.04
Linux Kernel 6.2
busybox 1.36.0

环境配置

安装交叉编译器、QEMU和相关依赖

For Arch Linux:

$ sudo pacman -S git riscv64-linux-gnu-gcc qemu-system-riscv uboot-tools

For Ubuntu:

$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install git qemu-system-misc gcc-riscv64-linux-gnu u-boot-tools

测试是否成功安装

For riscv64-linux-gnu-gcc:

$ riscv64-linux-gnu-gcc --version

它将输出以下版本信息

riscv64-linux-gnu-gcc (GCC) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

For QEMU:

$ qemu-system-riscv64 --version

它将输出以下版本信息

QEMU emulator version 9.0.1
Copyright (c) 2003-2024 Fabrice Bellard and the QEMU Project developers

准备RustSBI Prototyper, Test Kernel, U-Boot源码

创建工作目录并进入该目录

$ mkdir workshop && cd workshop

Clone RustSBI Prototyper

$ git clone https://github.com/rustsbi/prototyper.git && cd prototyper && git checkout main && cd ..

Clone U-Boot

$ git clone https://github.com/u-boot/u-boot.git && cd u-boot && git checkout v2024.04 && cd ..

使用U-Boot SPL启动Test Kernel

编译RustSBI Prototyper和Test Kernel

进入prototyper目录

$ cd prototyper

编译RustSBI Prototyper和Test Kernel

$ cargo prototyper
$ cargo test-kernel --pack

本小节将使用二进制文件 ./target/riscv64imac-unknown-none-elf/release/rustsbi-test-kernel.itb

编译U-Boot SPL

进入U-Boot目录

$ cd u-boot

导出环境变量

$ export ARCH=riscv
$ export CROSS_COMPILE=riscv64-linux-gnu-
$ export OPENSBI=../prototyper/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper.bin

生成.config文件

# To generate .config file out of board configuration file
$ make qemu-riscv64_spl_defconfig
# add bootcmd value
$ make menuconfig

编译U-Boot

# To build U-Boot
$ make -j$(nproc)

本小节将使用二进制文件 ./spl/u-boot-spl

使用RustSBI原型系统和U-Boot启动Linux Kernel

进入workshop目录

$ cd workshop

运行下面命令

$ qemu-system-riscv64 -M virt -smp 1 -m 256M -nographic \
          -bios ./u-boot/spl/u-boot-spl \
          -device loader,file=./prototyper/target/riscv64imac-unknown-none-elf/release/rustsbi-test-kernel.itb,addr=0x80200000

使用U-Boot SPL和U-Boot启动Test Kernel

编译RustSBI Prototyper和Test Kernel

进入prototyper目录

$ cd prototyper

编译RustSBI Prototyper和Test Kernel

$ cargo make prototyper
$ cargo make test-kernel

本小节将使用二进制文件 ./target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper.bin./target/riscv64imac-unknown-none-elf/release/rustsbi-test-kernel.bin

编译U-Boot SPL

进入U-Boot目录

$ cd u-boot

导出环境变量

$ export ARCH=riscv
$ export CROSS_COMPILE=riscv64-linux-gnu-
$ export OPENSBI=../prototyper/target/riscv64imac-unknown-none-elf/release/rustsbi-prototyper.bin

生成.config文件

# To generate .config file out of board configuration file
$ make qemu-riscv64_spl_defconfig
# add bootcmd value
$ make menuconfig

U-Boot 配置选项将加载到终端。导航到 Boot options $\rightarrow$ bootcmd value 并将以下内容写入 bootcmd 值:

ext4load virtio 0:1 84000000 rustsbi-test-kernel.bin; booti 0x84000000 - ${fdtcontroladdr}

编译U-Boot

# To build U-Boot
$ make -j$(nproc)

本小节将使用二进制文件 ./spl/u-boot-spl./u-boot.itb

创建启动盘

workshop目录运行以下命令来创建一个256 MB的磁盘镜像

# Create a 256 MB disk image
$ qemu-img create test-kernel.img 256m

创建分区

将在磁盘映像test-kernel.img上创建1个分区,这个分区是可引导的。

parted命令将用于在镜像test-kernel.img中创建分区。在镜像中创建分区表:

$ sudo parted test-kernel.img mklabel gpt

现在test-kernel.img中有一个分区表。将test-kernel.img挂载为loop device,以便它可以用作块设备。将test-kernel.img挂载为块设备将允许在其中创建分区。

# Attach test-kernel.img with the first available loop device
$ sudo losetup --find --show test-kernel.img
  • find:查找第一个未使用的loop device
  • show:显示test-kernel.img附加到的loop device的名称

记下循环设备的完整路径。在本教程中它是/dev/loop0。对/dev/loop0的操作将会对test-kernel.img进行操作。

/dev/loop0分区

# Create a couple of primary partitions
$ sudo parted --align minimal /dev/loop0 mkpart primary ext4 0 100%

$ sudo parted /dev/loop0 print

格式化分区

通过以下命令查看分区:

$ ls -l /dev/loop0*

在本教程中,分区为/dev/loop0p1

格式化分区并创建ext4文件系统,同时将分区设置为可引导分区。

$ sudo mkfs.ext4 /dev/loop0p1

# Mark first partition as bootable
$ sudo parted /dev/loop0 set 1 boot on

将Linux Kernel和根文件系统拷贝进启动盘

# Mount the 1st partition
$ sudo mkdir test-kernel
$ sudo mount /dev/loop0p1 test-kernel
$ cd test-kernel

拷贝Linux Kernel镜像

$ sudo cp ../prototyper/target/riscv64imac-unknown-none-elf/release/rustsbi-test-kernel.bin .

卸载test-kernel

$ cd workshop
$ sudo umount test-kernel

/dev/loop0分离

$ sudo losetup -d /dev/loop0

使用RustSBI 原型系统和U-Boot启动Linux Kernel

进入workshop目录

$ cd workshop

运行下面命令

$ qemu-system-riscv64 -M virt -smp 1 -m 256M -nographic \
          -bios ./u-boot/spl/u-boot-spl \
          -device loader,file=./u-boot/u-boot.itb,addr=0x80200000 \
          -blockdev driver=file,filename=./test-kernel.img,node-name=hd0 \
          -device virtio-blk-device,drive=hd0