2、开发环境搭建:交叉编译工具链安装、QEMU模拟器配置、RISC-V开发板选型与准备

好,咱们正式开始动手了。这一章我带你搭环境。

很多人觉得搭环境是体力活,没什么技术含量。我一开始也这么想,直到有一次在项目里因为工具链版本不对,排查了整整两天……嗯,从那以后我再也不敢小看这一步了。环境搭得稳,后面移植模型才能顺风顺水。

2.1 交叉编译工具链安装

先说说什么是交叉编译。说白了,就是在你的x86电脑上,编译出能在RISC-V芯片上跑的程序。你想想看,RISC-V开发板通常资源有限,不可能在上面直接跑gcc。所以我们需要一套交叉编译工具链。

我个人习惯用官方的RISC-V GNU工具链。它最稳定,社区支持也最好。安装方式有两种:源码编译和直接下载预编译包。

2.1.1 源码编译(推荐,但耗时)

如果你时间充裕,我建议你走源码编译。为什么?因为你可以自己控制编译选项,比如选择支持哪些扩展指令集。我在项目中遇到过,预编译包不支持向量扩展,导致模型推理性能上不去,最后只能自己编译。

步骤如下:

# 安装依赖
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip \
    libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex \
    texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev

# 克隆仓库
git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain

# 配置,这里我选择64位架构,支持ILP32D和LP64D
./configure --prefix=/opt/riscv --with-arch=rv64gc --with-abi=lp64d

# 编译,-j后面的数字根据你CPU核心数来
make -j$(nproc)

编译完成后,把工具链加入PATH:

export PATH=/opt/riscv/bin:$PATH

你可以把它写到 ~/.bashrc 里,省得每次都要手动敲。

我的小技巧: 编译时加上 --enable-multilib 参数,可以同时支持32位和64位。虽然编译时间会长一些,但后面调试不同架构的模型时会方便很多。

2.1.2 使用预编译包(省事)

如果你不想等几个小时编译,直接用预编译包也行。我建议从SiFive或者Bootlin的官方源下载。

# 以Bootlin为例
wget https://toolchains.bootlin.com/downloads/releases/toolchains/riscv64-lp64d/releases/riscv64-lp64d--glibc--stable-2024.02-1.tar.bz2
tar -xjf riscv64-lp64d--glibc--stable-2024.02-1.tar.bz2 -C /opt/
export PATH=/opt/riscv64-lp64d--glibc--stable-2024.02-1/bin:$PATH

验证是否安装成功:

riscv64-unknown-linux-gnu-gcc --version

看到版本信息,就说明工具链能用了。

注意: 预编译包可能不支持最新的RISC-V扩展指令集。如果你要移植的AI模型用到了V扩展(向量指令),建议还是走源码编译,自己加上 --with-arch=rv64gcv

2.2 QEMU模拟器配置

不是每个人都有RISC-V开发板。就算有,调试起来也麻烦。这时候QEMU就派上用场了。它可以在你的电脑上模拟一个RISC-V环境,跑你编译好的程序。

我个人习惯在QEMU上先做模型推理的功能验证,确认没问题了再烧到板子上。这样能省下大量反复烧录的时间。

2.2.1 安装QEMU

建议从源码编译,这样能确保支持最新的RISC-V特性。

# 安装依赖
sudo apt-get install ninja-build pkg-config libglib2.0-dev libpixman-1-dev

# 克隆QEMU
git clone https://github.com/qemu/qemu
cd qemu

# 配置,只编译RISC-V相关
./configure --target-list=riscv64-softmmu,riscv64-linux-user \
    --enable-debug --enable-kvm

# 编译
make -j$(nproc)

这里我解释一下两个target的区别:

  • riscv64-softmmu:完整系统模拟,可以启动一个完整的Linux系统
  • riscv64-linux-user:用户态模拟,只运行单个程序,启动快

做AI模型移植时,我通常先用 linux-user 模式快速验证模型推理结果是否正确,再用 softmmu 模式测试完整的系统级流程。

2.2.2 启动一个RISC-V Linux系统

你需要三个东西:内核镜像、根文件系统、设备树文件。我推荐用OpenSBI + Linux内核的组合。

# 下载预编译好的镜像(来自Fedora RISC-V项目)
wget https://dl.fedoraproject.org/pub/alt/risc-v/releases/virt-builder/images/Fedora-Developer-RISC-V-38-20230523.n.0-sda.raw.xz
unxz Fedora-Developer-RISC-V-38-20230523.n.0-sda.raw.xz

# 启动QEMU
qemu-system-riscv64 \
    -machine virt \
    -cpu rv64,v=true,vext_spec=v1.0 \
    -m 4G \
    -smp 4 \
    -kernel fw_payload.elf \
    -drive file=Fedora-Developer-RISC-V-38-20230523.n.0-sda.raw,format=raw,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -netdev user,id=net0 \
    -device virtio-net-device,netdev=net0 \
    -nographic

关键参数说明:

  • -cpu rv64,v=true,vext_spec=v1.0:启用向量扩展,这对AI模型推理至关重要
  • -m 4G:分配4GB内存,模型推理时内存不够会直接OOM
  • -smp 4:4核CPU,模拟多核并行推理

启动后,你会看到一个完整的Linux终端。用 uname -a 确认一下架构:

[root@fedora-riscv ~]# uname -a
Linux fedora-riscv 6.4.0-0.rc5.20230602git0dd3ee311f08.38.fc39.riscv64 #1 SMP Fri Jun 2 17:00:00 UTC 2023 riscv64 GNU/Linux

看到 riscv64 就对了。

我曾经踩过的坑: 一开始我用默认的CPU参数,没加 v=true,结果模型推理时向量指令全部报非法指令错误。排查了半天才发现是QEMU没开启向量扩展支持。所以,记得一定要显式指定CPU特性。

2.3 RISC-V开发板选型与准备

QEMU再好,也只是模拟。真正要跑模型,还得上板子。市面上的RISC-V开发板越来越多,我帮你梳理一下,方便你选型。

2.3.1 主流开发板对比

开发板 芯片 核心数 主频 内存 AI加速 价格区间 适合场景
SiFive HiFive Unmatched FU740 4核 1.2GHz 8GB DDR4 无专用NPU ~$800 通用模型验证
StarFive VisionFive 2 JH7110 4核 1.5GHz 2/4/8GB LPDDR4 无专用NPU ~$80 入门学习、轻量模型
Allwinner D1 / Nezha D1 (C906) 1核 1.0GHz 512MB/1GB DDR3 支持RVV 0.7.1 ~$50 向量指令实验
T-Head TH1520 (LicheePi 4A) TH1520 4核 1.8GHz 8/16GB LPDDR4X 支持RVV 1.0 + GPU ~$150 AI模型部署主力
算能 SG2042 (Pioneer Box) SG2042 64核 2.0GHz 64GB DDR4 无专用NPU ~$2000 服务器级推理

我个人最推荐的是 LicheePi 4A。为什么?它支持RVV 1.0向量扩展,这是AI模型加速的关键。而且价格适中,社区活跃,遇到问题容易找到人问。

2.3.2 开发板准备工作

拿到板子后,别急着上电。先做这几步:

  1. 烧录系统:大多数板子支持从SD卡启动。下载官方提供的镜像,用 ddbalenaEtcher 烧录到SD卡。
  2. 串口连接:用USB转TTL模块连接板子的串口引脚。波特率通常是115200。我第一次用VisionFive 2时,忘了接串口线,结果板子启动了我都不知道……
  3. 网络配置:插上网线,或者配置WiFi。后面传输模型文件和交叉编译结果都靠网络。
  4. 确认工具链匹配:在板子上运行 uname -m,确认架构是 riscv64。然后交叉编译一个hello world程序,传到板子上运行,验证工具链和板子是否匹配。
# 在PC上交叉编译
riscv64-unknown-linux-gnu-gcc -o hello hello.c

# 传到板子上(假设板子IP是192.168.1.100)
scp hello root@192.168.1.100:/root/

# 在板子上运行
ssh root@192.168.1.100
./hello

看到 Hello, RISC-V! 打印出来,环境就算搭好了。

曾经的血泪教训: 有一次我交叉编译了一个程序,传到板子上运行,结果报 Illegal instruction。查了半天,发现是工具链编译时默认用了RV64GC,但板子芯片只支持RV64GC的子集。所以,一定要确认板子支持的指令集版本,编译时用对应的 -march-mabi 参数。

2.4 环境验证:跑一个简单的AI模型

环境搭好了,咱们跑个简单的模型验证一下。我用Tiny YOLO举个例子,它比较小,适合做功能验证。

# 在PC上交叉编译Tiny YOLO推理程序
riscv64-unknown-linux-gnu-gcc -O2 -march=rv64gcv -mabi=lp64d \
    -o tiny_yolo tiny_yolo.c -lm

# 传到板子
scp tiny_yolo root@192.168.1.100:/root/

# 在板子上运行
ssh root@192.168.1.100
./tiny_yolo

如果一切顺利,你会看到模型加载成功,推理结果输出。嗯,到这里,你的RISC-V AI模型移植环境就正式搭建完成了。

我的习惯: 我会写一个简单的shell脚本,把交叉编译、文件传输、远程执行串起来。这样每次修改代码后,一键就能在板子上验证结果,省得反复敲命令。

下一章,咱们开始真正接触模型移植的核心——如何把训练好的模型转换成RISC-V能高效运行的格式。准备好了吗?