最近这段时间我在研究 RISC-V 内核。作为计划的开始,首先要将它运行起来。配置过程有点复杂,在此做详细介绍。
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
git clone https://github.com/qemu/qemu
git clone https://github.com/torvalds/linux
git clone https://github.com/riscv/riscv-pk
git clone https://github.com/michaeljclark/busybear-linux
顺带一提,为了构建过程顺利,请先试着安装以下依赖:
sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev git
首先,我们的主机环境需要有 RISC-V 的全套工具链,用于编译、链接、调试基于 RISC-V 架构的程序语言。一般来说,常见的主机环境都是 AMD-64 架构,Linux 操作系统自带的 gcc gdb等是无法编译 RISC-V 程序的。
cd riscv-gnu-toolchain
# pick an install path, e.g. /opt/riscv64
./configure --prefix=/opt/riscv64
make newlib -j $(nproc)
make linux -j $(nproc)
# export variables
export PATH="$PATH:/opt/riscv64/bin"
export RISCV="/opt/riscv64"
由于网络问题,RISC-V 工具链难以全部下载完成,大家需要通过各种渠道获取: )
。
然后,就是对大名鼎鼎的虚拟机 QEMU 进行构建了, 针对非常多不同的架构,QEMU 有相应的虚拟机,所以 configure 的时候需要自己指定,--target-list
就是在指定架构。riscv64-linux-user 为用户模式,可以运行基于RISC-V 指令集编译的程序文件,softmmu 为镜像模拟器,可以运行基于 RISC-V 指令集编译的 Linux 镜像。
cd qemu
git checkout v3.0.0
./configure --target-list=riscv64-softmmu, riscv64-linux-user
make -j $(nproc)
sudo make install
接下来构建 Linux 。将下载下来的 Linux 内核(我这边使用的是 Linux-5.7.9)进行编译构建。但是要注意到,因为在 QEMU 上跑该内核时,我们计划用 busybear 文件系统镜像,因此 config 最好与 busybear 一致。
cd linux-5.7.9
cp ../busybear-linux/conf/linux.config .config # 直接拷贝 busybear 的 linux config
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- olddefconfig
# make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- nconfig # 配置内核 直接退出即可
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- vmlinux -j $(nproc)
上面最后一句话是在构建 vmlinux ,这里需要等待一些时间。
vmlinux is a statically linked executable file format based file which is the uncompressed version of kernel image which can be used for debugging.
BBL 是何物?全称为 Berkeley Boot Loader 。作为一个 boot 启动,装载内核。
This package also contains the Berkeley Boot Loader,
bbl
, which is a supervisor execution environment for tethered RISC-V systems. It is designed to host the RISC-V Linux port.
cd riscv-pk
mkdir build && cd build
../configure --enable-logo --host=riscv64-unknown-elf --with-payload=../../linux/vmlinux
make -j $(nproc)
Busybear 又是什么东西?简而言之,是一个 RISC-V Linux 的文件系统镜像,而且是针对 virt 虚拟机使用的。
busybear-linux is a tiny RISC-V Linux root filesystem image that targets the
virt
machine in riscv-qemu. As the name suggests, busybear-linux is a riscv-linux root image comprised of busybox and dropbear.The root image is intended to demonstrate virtio-net and virtio-block in riscv-qemu and features a dropbear ssh server which allows out-of-the-box ssh access to a RISC-V virtual machine.
cd busybear-linux
make -j $(nproc)
在构建期间,可能会遇到如下问题:
/opt/riscv/sysroot/usr/include/gnu/stubs.h:14:11: fatal error: gnu/stubs-lp64.h: No such file or directory ...
解决该问题,只需要打开 conf/busybear.config ,把 CROSS_COMPILE = riscv64-unknown-linux-gnu- 修改为CROSS_COMPILE = riscv64-unknown-elf-。
接下来就是激动人心的运行时间了!到你的主目录下,运行:
sudo qemu-system-riscv64 -nographic -machine virt \
-kernel riscv-pk/build/bbl -append "root=/dev/vda ro console=ttyS0" \
-drive file=busybear-linux/busybear.bin,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0
QEMU 会让你输入用户名和密码,如果你仔细看的话,busybear.config 里面有一个叫 ROOT_PASSWORD 的项。所以你的用户名密码就是:
username: root
password: busybear
然后,让我来一一解释一下这么长的命令行在干什么。
sudo qemu-system-riscv64 -nographic -machine virt
这句话就是启动 QEMU 虚拟机,设置为不显示图形界面模式 -nographic
,并指定机器为 -machine virt
-kernel riscv-pk/build/bbl -append "root=/dev/vda ro console=ttyS0"
QEMU 指定 kernel 镜像为 bbl , -append
指定了 kernel 命令行,指示 Linux Kernel 从这里启动。
Use
-kernel
to provide the Linux kernel image and-append
to give the kernel command line arguments. The-initrd
option can be used to provide an INITRD image.
-drive file=busybear-linux/busybear.bin,format=raw,id=hd0 \
这里指定了文件系统镜像的路径、格式、以及它的 id 。
-device virtio-blk-device,drive=hd0
注意到 busybear 的说明,其目的是验证virtio-blk-device
。
出现下图所示的情况,构建就算成功了!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oo6sC1xn-1632397296482)(https://risc-v-getting-started-guide.readthedocs.io/en/latest/_images/linux64-qemu.gif)]