本文是《在 QEMU 上运行启用 Rust 的 RISC-V Linux 7.0 内核》系列的配套篇,介绍如何用 Buildroot 制作一个可以在 QEMU 中启动的
rootfs.ext2。
环境说明
- 宿主机:WSL2 Ubuntu
- 目标架构:RISC-V 64 位
- 工具:Buildroot(最新 master)
- 输出:
rootfs.ext2(可直接被 QEMU 挂载)
一、获取 Buildroot
bash
git clone https://github.com/buildroot/buildroot.git
cd buildroot
二、处理 WSL PATH 问题(必读)
Buildroot 的 Makefile 会检查 PATH,如果发现含有空格或制表符会直接报错退出:
Your PATH contains spaces, TABs, and/or newline (\n) characters.
This doesn't work. Fix your PATH environment variable.
WSL 默认把 Windows 路径(如 /mnt/c/Program Files/Git/cmd)注入 PATH,这些路径含有空格,是报错根源。
方法一:临时(每次 make 前设置)
bash
export CLEAN_PATH="/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin"
方法二:永久修复(推荐,需重启 WSL)
bash
sudo tee -a /etc/wsl.conf << 'EOF'
[interop]
appendWindowsPath = false
EOF
在 Windows PowerShell 中执行:
powershell
wsl --shutdown
重新打开 WSL 后 PATH 中不再含 Windows 路径。
三、安装编译依赖
bash
sudo apt install -y \
build-essential gcc g++ \
make cmake \
libncurses-dev \
gettext \
wget curl \
cpio \
rsync \
bc \
python3 \
unzip \
file
踩坑 :
cpio极容易被忘记,缺少它会在编译中途报错:
You must install 'cpio' on your build machine
四、配置网络代理(如需要)
Buildroot 编译过程中需要从网络下载大量源码包。如果网络受限:
bash
export http_proxy="http://your-proxy:port"
export https_proxy="http://your-proxy:port"
并在 make 时传入:
bash
env http_proxy="http://your-proxy:port" \
https_proxy="http://your-proxy:port" \
PATH="$CLEAN_PATH" \
make -j$(nproc)
五、配置 Buildroot
bash
# 使用 RISC-V 64 QEMU virt 官方预设配置
make qemu_riscv64_virt_defconfig
这一步会生成 .config,预设了:
- 目标架构:RISC-V 64 位
- C 库:uClibc-ng
- 内核:Buildroot 自带(可选,我们用自己编译的内核)
- rootfs 格式:ext2
如果想用图形界面自定义(比如添加软件包):
bash
sudo apt install libncurses-dev # 如果没装
make menuconfig
常用可选项:
| 菜单路径 | 选项 | 用途 |
|---|---|---|
| Target packages → Networking | dropbear |
SSH 服务 |
| Target packages → Shell | bash |
替换默认 sh |
| Target packages → System tools | htop |
资源监控 |
| Filesystem images | ext2/3/4 size |
调整镜像大小 |
六、编译
bash
env PATH="$CLEAN_PATH" \
http_proxy="http://your-proxy:port" \
https_proxy="http://your-proxy:port" \
make -j$(nproc)
编译时间约 30-60 分钟(首次,需下载源码包)。
编译完成后产物在 output/images/:
output/images/
├── fw_dynamic.elf ← OpenSBI 固件
├── fw_jump.elf
├── Image ← Linux 内核(Buildroot 自带的)
├── rootfs.ext2 ← 根文件系统(我们需要的)
├── rootfs.tar
└── start-qemu.sh ← Buildroot 自动生成的启动脚本
七、用自己编译的内核启动
Buildroot 生成的 start-qemu.sh 使用的是其自带内核。替换为我们自己编译的启用 Rust 的内核:
bash
qemu-system-riscv64 \
-machine virt \
-nographic \
-kernel /path/to/linux/arch/riscv/boot/Image \
-drive file=output/images/rootfs.ext2,format=raw,if=none,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda rw console=ttyS0" \
-m 512M
踩坑 :
-drive必须加if=none,否则报错:
Drive 'hd0' is already in use (did you need 'if=none'?)
启动成功后看到登录提示:
Welcome to Buildroot
buildroot login: root
#
默认 root 无密码,直接回车登录。
八、验证
bash
# 确认架构
uname -m
# riscv64
# 确认内核版本(如果用了自己的内核)
uname -r
# 7.0.0
# 确认 Rust 已编译进内核
zcat /proc/config.gz | grep CONFIG_RUST
# CONFIG_RUST=y
完整踩坑记录
| 错误 | 原因 | 解决 |
|---|---|---|
PATH contains spaces |
WSL 注入 Windows 路径 | env PATH=... 或 appendWindowsPath=false |
You must install 'cpio' |
缺少 cpio | sudo apt install cpio |
Connection timed out 下载失败 |
网络受限 | 设置代理 http_proxy |
Drive 'hd0' is already in use |
QEMU drive 缺少 if=none |
加上 if=none |
| Python pip 与 Python 3.14 不兼容 | pip 版本过旧 | sudo apt install python3-pip --reinstall 或用 venv |