2、开发环境搭建:RISC-V GNU工具链编译、QEMU模拟器安装、Spike模拟器使用、Hello World程序验证
说实话,搭建开发环境这件事,很多初学者觉得枯燥。但我得说一句——环境搭不好,后面全是坑。我自己带过不少新人,十有八九的问题都出在工具链没配对上。所以这一章,咱们把RISC-V的四大件捋清楚:GNU工具链、QEMU、Spike,最后跑个Hello World验证一下。
2.1 RISC-V GNU工具链编译
GNU工具链,说白了就是编译器、汇编器、链接器那一套。RISC-V官方维护了一套叫riscv-gnu-toolchain的项目,支持RV32和RV64,也支持多种ABI。
我个人习惯用源码编译,虽然慢点,但可控。你如果图省事,也可以直接用apt装预编译包,但版本可能比较老。
2.1.1 下载源码
git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git
cd riscv-gnu-toolchain
git submodule update --init --recursive
嗯,这里要注意——submodule更新这一步很关键。我曾经因为网络问题没拉全子模块,编译到一半报错,折腾了大半天。建议用代理或者换个时间段再试。
2.1.2 配置与编译
假设你要编译一个64位Linux版本的交叉工具链:
mkdir build && cd build
../configure --prefix=/opt/riscv --enable-multilib
make linux -j$(nproc)
这里--prefix指定安装路径,--enable-multilib表示同时支持RV32和RV64。编译时间取决于机器性能,我笔记本上大概跑了40分钟。
make newlib,编译速度会快不少。
2.1.3 验证安装
/opt/riscv/bin/riscv64-unknown-linux-gnu-gcc --version
看到版本号输出,说明工具链装好了。你想想看,这一步要是卡住,后面所有实验都跑不了。所以务必确认。
2.2 QEMU模拟器安装
QEMU是个全能型模拟器,能模拟完整的RISC-V系统。我在项目中遇到过需要验证Linux内核的场景,QEMU就是首选。
2.2.1 安装方式
两种方式:
- apt安装(推荐新手):
sudo apt install qemu-system-riscv64 - 源码编译(推荐进阶):
git clone https://github.com/qemu/qemu.git
cd qemu
./configure --target-list=riscv64-softmmu
make -j$(nproc)
sudo make install
我个人倾向源码编译,因为可以开启KVM加速,跑起来快很多。不过如果你只是跑个小程序,apt版完全够用。
2.2.2 快速测试
qemu-system-riscv64 -machine virt -nographic -m 256M -kernel /path/to/fw_jump.elf
这里-machine virt是QEMU自带的RISC-V虚拟开发板,-nographic表示不用图形界面。如果看到OpenSBI的启动信息,说明QEMU工作正常。
2.3 Spike模拟器使用
Spike是RISC-V官方的ISA模拟器,比QEMU轻量得多。它不模拟外设,只模拟CPU核心。说白了,就是用来跑裸机程序和做指令集验证的。
2.3.1 安装Spike
git clone https://github.com/riscv-software-src/riscv-isa-sim.git
cd riscv-isa-sim
mkdir build && cd build
../configure --prefix=/opt/spike
make -j$(nproc)
sudo make install
安装完后,记得把/opt/spike/bin加到PATH里。
2.3.2 运行一个程序
spike pk hello.elf
pk是代理内核(Proxy Kernel),它负责处理系统调用。Spike本身不提供操作系统服务,所以需要pk来桥接。
我曾经犯过一个低级错误——直接用spike跑一个Linux编译出来的ELF,结果报错说找不到入口。后来才意识到,Spike只能跑裸机或者pk格式的程序。
2.4 Hello World程序验证
好了,工具链和模拟器都装好了,咱们写个Hello World验证一下。
2.4.1 编写代码
// hello.c
#include <stdio.h>
int main() {
printf("Hello, RISC-V World!\n");
return 0;
}
2.4.2 编译
/opt/riscv/bin/riscv64-unknown-linux-gnu-gcc -o hello.elf hello.c
这里用的是Linux版本的交叉编译器。如果你装的是newlib版,编译器名字会变成riscv64-unknown-elf-gcc。
2.4.3 在QEMU上运行
qemu-system-riscv64 -machine virt -nographic -m 256M -kernel hello.elf
等等,这样直接跑不行。因为QEMU需要完整的启动流程,包括OpenSBI和内核。对于单个ELF,我们需要用-append参数或者制作一个根文件系统。
更简单的办法:用Spike来跑。
spike pk hello.elf
如果看到输出:
bbl loader
Hello, RISC-V World!
恭喜你,环境搭建成功了!
- 工具链编译时注意submodule完整性
- QEMU适合跑完整系统,Spike适合跑裸机程序
- 验证环境时,先用Spike跑pk格式,再用QEMU跑完整系统
2.5 本章知识体系
下面这张图,是我画的环境搭建整体流程。你跟着这个路线走,基本不会迷路。
这张图很直观:工具链是基础,编译出ELF后,你可以选择Spike做快速验证,或者QEMU做完整系统测试。两条路最终都汇聚到Hello World输出。
好了,环境搭好,后面就可以愉快地写RISC-V汇编和C代码了。记住,工具链版本和模拟器版本一定要对齐,这是血的教训。