Ubuntu环境下搭建Qemu + Linux + Busybox仿真环境,运行RISC-V Linux内核

我的博客

参考文档1

参考文档2

搭建仿真环境使用的系统版本如下:

$ 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
posted @ 2025-07-05 21:51  ArvinDu  阅读(42)  评论(0)    收藏  举报