3. QEMU RISC-V Virt机器启动
任务说明
本案例使用QEMU的virt机器模拟RISC-V 64位处理器,目标是启动Linux内核并进入用户空间shell。我们将使用QEMU内置的virt机器定义,配合上游Linux内核的默认配置,完成从QEMU启动到Linux shell可交互的完整链路。
环境准备
需要以下组件:
- QEMU(版本≥7.0,支持RISC-V virt机器)
- Linux内核源码(版本≥5.15,推荐6.x)
- 交叉编译工具链:riscv64-linux-gnu-(Debian/Ubuntu下安装包为gcc-riscv64-linux-gnu和binutils-riscv64-linux-gnu)
- BusyBox(用于制作initramfs根文件系统)
实现步骤
1. 编译Linux内核
获取内核源码并配置RISC-V架构:
# 下载内核(以6.6版本为例)
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz
tar -xf linux-6.6.tar.xz
cd linux-6.6
# 设置交叉编译环境
export ARCH=riscv
export CROSS_COMPILE=riscv64-linux-gnu-
# 使用默认的virt配置
make defconfig
# 启用initramfs支持(后续步骤会生成initramfs)
# 编辑.config,确认以下选项已启用:
# CONFIG_BLK_DEV_INITRD=y
# CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT=y
# 编译内核(使用多线程加速)
make -j$(nproc)
编译完成后生成arch/riscv/boot/Image内核镜像。
2. 制作initramfs根文件系统
使用BusyBox构建最小根文件系统:
# 下载并编译BusyBox
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
# 静态编译配置
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc)
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- install
# 构建initramfs目录结构
mkdir -p initramfs/{bin,sbin,etc,proc,sys,dev}
cp -r _install/* initramfs/
# 创建init脚本
cat > initramfs/init << 'EOF'
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs devtmpfs /dev
echo "=== RISC-V Linux Boot Successful ==="
echo "Welcome to QEMU RISC-V virt machine"
exec /bin/sh
EOF
chmod +x initramfs/init
# 打包initramfs
cd initramfs
find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz
cd ..
3. 启动QEMU
使用virt机器启动Linux:
qemu-system-riscv64 \
-machine virt \
-cpu rv64 \
-smp 4 \
-m 2G \
-kernel /path/to/linux-6.6/arch/riscv/boot/Image \
-initrd /path/to/initramfs.cpio.gz \
-append "console=ttyS0 root=/dev/ram rdinit=/init" \
-nographic
验证方法
启动后观察串口输出,预期看到以下关键信息:
Linux version 6.6.0 (user@host) (riscv64-linux-gnu-gcc-12 ...)
[ 0.000000] Linux version 6.6.0 ...
[ 0.000000] CPU: rv64
[ 0.000000] Machine model: riscv-virtio,qemu
...
[ 1.234567] Freeing unused kernel image (initmem) memory: 252K
[ 1.234567] Run /init as init process
=== RISC-V Linux Boot Successful ===
Welcome to QEMU RISC-V virt machine
/ #
判定标准:
- 出现
Machine model: riscv-virtio,qemu,确认virt机器被正确识别; - 出现
Run /init as init process,确认initramfs被正确加载; - 出现
/ #提示符,可输入命令(如uname -a、cat /proc/cpuinfo),确认Linux用户空间shell可用。
常见问题排查
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 启动后无输出 | 串口参数错误 | 确认-append包含console=ttyS0 |
提示Kernel panic - not syncing: VFS: Unable to mount root fs | initramfs未正确加载 | 检查-initrd路径,确认cpio.gz格式正确 |
编译内核时报binutils版本过旧 | 交叉工具链版本低 | 升级gcc-riscv64-linux-gnu至12.x以上 |
QEMU提示virt machine does not support this CPU | CPU类型不匹配 | 使用-cpu rv64或省略该参数 |
本案例通过QEMU的virt机器成功模拟RISC-V 64位处理器并启动Linux,验证了从内核编译、initramfs构建到QEMU启动的完整工具链。该环境可用于后续内核开发、驱动调试和系统级实验。