本文是博主在博客写作中的一次全新尝试,本次尝试通过输入给Claude Sonnet 4.6的prompt来自动生成一篇技术性博客。
Prompt为:
linux 7.0 kernel在 /home/projects/linux/linux,教我编一个启用rust的riscv kernel用于qemu启动
Output如下(未作任何修改):
在 QEMU 上运行启用 Rust 的 RISC-V Linux 7.0 内核
本文记录从零开始,在 WSL2 Ubuntu 环境下交叉编译一个启用 Rust 支持的 RISC-V Linux 7.0 内核,并用 QEMU 启动的完整过程,包括所有踩过的坑。
环境说明
- 宿主机:WSL2 Ubuntu(Resolute)
- 内核版本:Linux 7.0.0
- 目标架构:RISC-V 64 位
- 模拟器:qemu-system-riscv64
- Rust:1.95.0(stable)
一、安装依赖
bash
# 基础编译工具
sudo apt install -y build-essential bc bison flex libncurses-dev \
libssl-dev libelf-dev cpio
# LLVM/Clang(关键:RISC-V 上 Rust 内核强制要求 Clang)
sudo apt install -y clang lld llvm libclang-dev
# RISC-V 交叉编译器(编译内核 C 部分仍需要)
sudo apt install -y gcc-riscv64-linux-gnu
# QEMU
sudo apt install -y qemu-system-riscv64
踩坑:不要只装 GCC。Linux 7.0 的 RISC-V Rust 支持有如下依赖链:
CONFIG_RUST 依赖 HAVE_RUST HAVE_RUST 依赖 RISCV && RUSTC_SUPPORTS_RISCV && CC_IS_CLANG用 GCC(
CC_IS_CLANG=n)会导致CONFIG_RUST在 menuconfig 中永远灰掉。
二、配置 Rust 工具链
bash
# 安装 rust-src(内核编译需要)
rustup component add rust-src
# 安装 bindgen(生成 C 绑定)
cargo install --locked bindgen-cli
# 添加到 PATH
export PATH="$HOME/.cargo/bin:$PATH"
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
三、处理 WSL PATH 问题
WSL 默认把 Windows 路径(含空格,如 /mnt/c/Program primecode.)注入到 PATH,这会导致内核 Makefile 直接报错退出。
永久修复(需重启 WSL):
bash
sudo tee -a /etc/wsl.conf << 'EOF'
[interop]
appendWindowsPath = false
EOF
在 Windows PowerShell 执行:
powershell
wsl --shutdown
重新打开 WSL 后生效。在此之前,每次 make 前用干净的 PATH:
bash
export CLEAN_PATH="$HOME/.cargo/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
四、验证 Rust 支持
bash
cd /path/to/linux # Linux 7.0 源码目录
env PATH="$CLEAN_PATH" make ARCH=riscv LLVM=1 rustavailable
无任何输出、无报错才算通过。常见报错及解决:
| 报错 | 原因 | 解决 |
|---|---|---|
rustc could not be found |
rustc 不在 PATH | export PATH="$HOME/.cargo/bin:$PATH" |
bindgen failed, libclang not found |
缺少 libclang | sudo apt install libclang-dev |
Rust version too old |
rustc 版本过低 | rustup update stable |
五、配置内核
bash
# 生成 RISC-V 默认配置
env PATH="$CLEAN_PATH" make ARCH=riscv LLVM=1 defconfig
# 启用 Rust 支持
scripts/config --enable CONFIG_RUST
# 可选:启用后可在启动的内核中读取配置
scripts/config --enable CONFIG_IKCONFIG
scripts/config --enable CONFIG_IKCONFIG_PROC
# 同步配置(接受所有新增选项的默认值)
env PATH="$CLEAN_PATH" make ARCH=riscv LLVM=1 olddefconfig
# 确认 Rust 已启用
grep "CONFIG_RUST=" .config
# 应输出:CONFIG_RUST=y
想用图形界面调整配置:
bash
sudo apt install libncurses-dev # 如果没装
env PATH="$CLEAN_PATH" make ARCH=riscv LLVM=1 menuconfig
# 路径:General setup → Rust support
六、编译内核
bash
env PATH="$CLEAN_PATH" make ARCH=riscv LLVM=1 -j$(nproc)
编译时间约 20-40 分钟(取决于机器配置)。完成后产物:
arch/riscv/boot/Image ← 内核镜像
七、准备根文件系统
用 buildroot 生成最小 rootfs:
bash
git clone https://github.com/buildroot/buildroot.git
cd buildroot
# 配置为 RISC-V QEMU 目标
make qemu_riscv64_virt_defconfig
# 编译(同样需要干净的 PATH)
env PATH="$CLEAN_PATH" make -j$(nproc)
生成的 rootfs 位于:output/images/rootfs.ext2
踩坑 :buildroot 编译同样受 WSL PATH 空格问题影响,务必用
env PATH=...或修复 wsl.conf。
八、QEMU 启动
bash
qemu-system-riscv64 \
-machine virt \
-nographic \
-kernel /path/to/linux/arch/riscv/boot/Image \
-drive file=/path/to/buildroot/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。
九、验证 Rust 已启用
登录后在 QEMU 内执行:
bash
# 查看内核版本
cat /proc/version
# 确认 Rust 编译进内核
zcat /proc/config.gz | grep CONFIG_RUST
# 应输出:CONFIG_RUST=y
退出 QEMU:Ctrl+A 然后按 X
完整踩坑记录
| 错误 | 原因 | 解决方案 |
|---|---|---|
HAVE_RUST=n,无法启用 Rust |
RISC-V Rust 需要 Clang | 改用 LLVM=1 |
bindgen failed: libclang not found |
缺少 libclang | sudo apt install libclang-dev |
PATH contains spaces |
WSL 注入 Windows 路径 | env PATH=... 或 appendWindowsPath=false |
Drive 'hd0' is already in use |
QEMU drive 选项缺少 if=none |
加上 if=none |
missing MODULE_LICENSE in Rust 模块 |
单独 make foo.ko 绕过 modpost |
必须跑完整 make |
| ncurses/openssl/libelf 报错 | 缺少头文件 | 对应 apt install |
经验证,可以正常boot。
本文总写作时间为5分钟,主要工作为copy-paste + 添加文章头。
验证时间为1小时30分钟左右,文章经过两次撤掉重构。