[Linux] 用 Buildroot 为 RISC-V QEMU 构建最小根文件系统

本文是《在 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
相关推荐
小草儿7991 小时前
gbase8s之onatpe备份与恢复性能测试
linux·服务器·网络
不做无法实现的梦~1 小时前
Linux 嵌入式开发完整入门:工具、配置和学习路线
linux·运维·学习
摘星台2 小时前
linux环境对stm32单片机进行程序烧录
linux·stm32·单片机
郝学胜-神的一滴2 小时前
Linux 高并发基石:epoll 核心原理 + LT/ET 触发模式深度剖析
linux·运维·服务器·开发语言·c++·网络协议
‎ദ്ദിᵔ.˛.ᵔ₎2 小时前
Linux 启动
linux·运维·服务器
shy^-^cky2 小时前
服务器高可用(HA)架构对比
运维·服务器·架构·双机热备·双机互备·双机双工
Joseph Cooper2 小时前
STM32MP157 Linux驱动学习笔记(三):系统级驱动框架(UART/PCIe)
linux·stm32·学习
funnycoffee1232 小时前
centos 上没有安装telnet命令 ,如何测试到1个目标IP的 443端口是否open
linux·tcp/ip·centos
威迪斯特2 小时前
Ubuntu的apt命令详解:系统管理的核心工具
运维·服务器·ubuntu·apt·下载·包管理·维护