Ubuntu环境下搭建Qemu + Linux + Busybox仿真环境,运行RISC-V Linux内核
搭建仿真环境使用的系统版本如下:
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.3 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
保证环境平台的内存、硬盘空间足够,我的内存16GB、硬盘空闲200GB绰绰有余。
编译环境搭建
安装依赖工具:
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
安装交叉编译工具链:
sudo apt-get install gcc-riscv64-linux-gnu
获取源码
首先创建源码放置文件夹,并进入该文件夹:
mkdir riscv
cd riscv
分别拉取最新的Linux、Busybox、Qemu代码:
git clone https://github.com/torvalds/linux.git
git clone https://git.busybox.net/busybox
git clone https://github.com/qemu/qemu
编译源码
编译Linux内核
使用Linux内核默认配置:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
也可自定义配置:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig
编译内核:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j $(nproc)
编译Busybox
使用默认配置:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
自定义配置Busybox配置项,比如修改busybox引用的Linux include目录、开关某功能:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig
# 配置开启Build static binary (no shared libs)
# 配置Path to sysroot,引用实际使用的Linux内核版本的头文件路径
编译Busybox:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j $(nproc)
打包Busybox:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- install
编译并安装Qemu
./configure --target-list=riscv64-softmmu
make -j $(nproc)
sudo make install
# 实际上直接从Ubuntu仓库安装即可
制作根文件系统
创建如下根文件系统目录:
mkdir initramfs
cd initramfs
mkdir -p {bin,sbin,dev,etc,home,mnt,proc,sys,usr,tmp}
mkdir -p usr/{bin,sbin}
mkdir -p proc/sys/kernel
cd dev
sudo mknod sda b 8 0
sudo mknod console c 5 1
cd ..
将busybox打包生成的产物拷贝到根文件系统中:
cp ../busybox/busybox ./bin/
创建启动文件:
vim init
编辑init文件内容如下:
#!/bin/busybox sh
# Make symlinks
/bin/busybox --install -s
# Mount system
mount -t devtmpfs devtmpfs /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /tmp
# Busybox TTY fix
setsid cttyhack sh
# https://git.busybox.net/busybox/tree/docs/mdev.txt?h=1_32_stable
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
sh
给该文件添加执行权限:
chmod +x init
此时initramfs文件树如下:
$ tree
.
├── bin
│ └── busybox
├── dev
│ ├── console
│ └── sda
├── etc
├── home
├── init
├── mnt
├── proc
│ └── sys
│ └── kernel
├── sbin
├── sys
├── tmp
└── usr
├── bin
└── sbin
将其打包成压缩文件:
find . -print0 | cpio --null -ov --format=newc | gzip -9 > initramfs.cpio.gz
启动内核
运行如下命令启动内核:
qemu-system-riscv64 -nographic -machine virt \
-kernel linux/arch/riscv/boot/Image \
-initrd initramfs/initramfs.cpio.gz \
-append "console=ttyS0"
执行结果:
OpenSBI v1.3
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|___/_____|
| |
|_|
在这一命令行窗口下,要退出时首先按下Ctrl + A组合键,松手之后按下X按键,退出QEMU仿真。
Hello world
在宿主机中编写如下Makefile文件:
all:
riscv64-linux-gnu-gcc -static -o test test.c -Wall
clean:
rm -f test
并编写如下test.c文件:
#include <stdio.h>
int main(void)
{
printf("hello world\r\n");
return 0;
}
执行make指令,编译测试源程序:
make
将编译产物test拷贝到根文件系统中,并按照根文件系统制作方法重新制作根文件系统,之后使用Qemu引导进入系统,在系统下可执行:
/home # ls
test
/home # ./test
hello world
浙公网安备 33010602011771号