在RISC-V上搭建Linux开发环境:内核、BSP与工具链

芯向开源
2026-08-28
收藏
0
点赞
0
14
本文从工具链、QEMU 模拟、内核编译、固件引导、根文件系统到 BSP 适配,逐层梳理搭建过程中的技术决策点和工程问题。讨论范围限定于 64 位 RISC-V(RV64GC)Linux 开发场景。
RISC-V 软件生态在过去两年发生了质变。Debian/Fedora 的 riscv64 端口进入官方仓库,GCC 16 扩展 -mcpu= 微架构 targeting,openEuler RISC-V SIG 发布可用发行版镜像——搭建一套完整的 Linux 开发环境已是工程化常规操作。
本文从工具链、QEMU 模拟、内核编译、固件引导、根文件系统到 BSP 适配,逐层梳理搭建过程中的技术决策点和工程问题。讨论范围限定于 64 位 RISC-V(RV64GC)Linux 开发场景。

一、工具链:交叉编译器的选择与构建

目标三元组与 ISA 字符串

RISC-V 工具链的目标三元组与 Arm 的关键区别在于:ISA 不是固定的,-march 参数决定编译器生成哪些指令。riscv64-linux-gnu(Debian/Ubuntu 打包前缀)与 riscv64-unknown-linux-gnu(源码构建默认前缀)功能等价,仅命名约定不同。
-march 指定指令集扩展组合,-mabi 指定调用约定,两者匹配是硬约束:
rv64gc + lp64d:最通用组合。G = IMAFD,C = 压缩指令,lp64d = 64 位指针 + 硬件双精度浮点 ABI。
rv64gcv + lp64d:在 gc 基础上加入 Vector 1.0,面向支持 RVV 的处理器。
rv32imac + ilp32:32 位指针,无硬件浮点,用于 MCU 级别。
常见错误是 -march 指定了目标硬件不支持的扩展,运行时触发 illegal instruction 异常。

GCC 与 LLVM

GCC 路径最快的方式是发行版包管理器安装:
xxxxxxxxxx
sudo apt install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu
源码构建用于需要特定 -march 或最新版本的场景。riscv-gnu-toolchain 的 make linux 构建带 glibc 的 Linux 工具链,make(不带参数)构建 newlib bare-metal 工具链。
LLVM 的优势是单一编译器覆盖所有架构:clang --target=riscv64-linux-gnu -march=rv64gc -mabi=lp64d。LLVM 17+ 的 RISC-V 后端已可用于生产,对 lld、Sanitizer、LTO 的支持比 GCC 更完整。
实际工程考量:GCC 与 LLVM 在不同 RISC-V 微架构和工作负载上的代码生成与性能表现可能存在差异,性能敏感场景建议结合目标处理器和实际 workload 进行基准测试。
GCC 16 进一步扩展了 RISC-V -mcpu= targeting 支持,可针对更多具体微架构进行指令选择与调度优化,厂商定制工具链(如玄铁资源中心提供的 Xuantie GCC)与上游工具链间的性能差距正在缩小。

二、QEMU:无硬件环境下的开发与调试

QEMU 提供两种模式。用户模式(qemu-riscv64)模拟用户态系统调用,直接运行 RISC-V 二进制,适合快速验证交叉编译结果。系统模式(qemu-system-riscv64)完整模拟一台 RISC-V 虚拟机,-machine virt 是最常用的虚拟平台:
xxxxxxxxxx
qemu-system-riscv64 -machine virt -smp 4 -m 4G -nographic \
 -bios opensbi/build/platform/generic/firmware/fw_jump.bin \
 -kernel linux/arch/riscv/boot/Image \
 -append "root=/dev/vda ro console=ttyS0" \
 -drive file=rootfs.ext4,format=raw,id=hd0 \
 -device virtio-blk-device,drive=hd0 \
 -netdev user,id=net0 -device virtio-net-device,netdev=net0
virt 机器支持多核 RV32GC/RV64GC 配置,当前 QEMU 版本最多可配置 512 个通用 RISC-V 核,集成 CLINT/PLIC 中断控制器与 virtio-mmio 设备。启用 Vector 扩展需指定 -cpu rv64,v=true,vlen=128。
GDB 远程调试通过 -s -S 参数开启:
xxxxxxxxxx
qemu-system-riscv64 -machine virt -kernel Image -S -s ...
riscv64-linux-gnu-gdb vmlinux
(gdb) target remote :1234
(gdb) break start_kernel
多核场景下可通过 info threads 查看所有 hart 状态,thread N 切换——调试 SMP 启动逻辑和 IPI 时是必要的。

三、内核:获取、配置与编译

RISC-V 架构自 Linux 4.15 合入主线。当前 6.x 内核状态:RV64GC 基础支持稳定;Vector 1.0 已合入,支持上下文切换中的向量寄存器保存/恢复;RISC-V KVM 支持自 Linux 5.16 进入主线,此后持续扩展对 ISA 扩展和虚拟化功能的支持;AIA 和 RISC-V IOMMU 的 Linux/QEMU 支持仍在持续完善,不同内核版本、平台和硬件实现之间的支持程度存在差异。
xxxxxxxxxx
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc)
defconfig 生成 QEMU virt 机器的默认配置。关键 Kconfig 项:
CONFIG_RISCV_ISA_V:Vector 扩展支持。
CONFIG_HVC_RISCV_SBI:启用通过 SBI 调用提供的 RISC-V SBI console,主要用于启动阶段的 console 输出;实际使用取决于平台固件和 console 配置。
CONFIG_BLK_DEV_VIRTIO / CONFIG_VIRTIO_NET:virtio 设备,QEMU 环境必需。
CONFIG_SMP:多核支持,RISC-V SMP 启动通过 SBI HSM 扩展完成。
编译产物 arch/riscv/boot/Image 供 QEMU 直接加载。U-Boot 的 booti 命令可直接加载未压缩的 Image;如需压缩镜像,可生成 Image.gz。
发行版 LTS 内核(5.10/6.6)与主线存在特性滞后。RVA23 Profile 要求的 Hypervisor 和 Vector 1.0 需较新内核,LTS 需大量回迁工作。openEuler RISC-V SIG 维护的 RVCK 开发树是国内较活跃的 RISC-V 内核补丁来源,但对最新 ISA 扩展的支持建议直接使用主线源码。

四、固件与引导:OpenSBI 与 U-Boot

典型 RISC-V Linux 启动流程:BootROM → OpenSBI (M-mode) → U-Boot/Linux (S-mode)。OpenSBI 运行在 M-mode,提供 SBI 接口给 S-mode 的操作系统;Linux 通过 SBI 调用获取 M-mode 服务(时钟、中断、控制台等)。
xxxxxxxxxx
git clone https://github.com/riscv-software-src/opensbi.git
cd opensbi
make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic -j$(nproc)
产物 fw_jump.bin 跳转到固定地址的 S-mode payload。其他模式:fw_payload.bin 将内核直接打包进固件;fw_dynamic.bin 运行时动态指定 payload 地址,U-Boot 通常使用此模式。SBI 规范采用基础版本与可选扩展相结合的方式。SBI 0.2 引入标准化扩展接口机制,HSM 等扩展用于 hart 状态管理和 SMP 启动;后续版本持续完善标准接口。SBI 3.0 已于 2025 年正式 ratified。
U-Boot 对 RISC-V 支持已进入主线。QEMU virt 使用 qemu-riscv64_smode_defconfig。真实硬件需厂商 defconfig——TH1520 早期需 T-Head 版本 U-Boot,主线支持从 2023 年 6 月逐步合入;VisionFive 2(JH7110)已较成熟,可直接用主线。
RISC-V 设备发现机制以 Device Tree 为主(服务器级平台正推进 ACPI 路线,内核已合入相应支持)。QEMU virt 机器的设备树由 QEMU 自动生成(-machine virt,dumpdtb=virt.dtb 可导出)。真实硬件的 DTS 通常由 SoC 厂商提供,BSP 适配的核心工作之一就是维护和修正 DTS。

五、根文件系统:Buildroot 与发行版

Buildroot 是最轻量的方案,一条 make 完成工具链、内核、固件、rootfs 的全量构建:
xxxxxxxxxx
git clone https://git.buildroot.net/buildroot
cd buildroot
make qemu_riscv64_virt_defconfig
make menuconfig
make -j$(nproc)
产物在 output/images/。Buildroot 的 RISC-V 支持:glibc 是支持最完整的 C 库,musl 亦可用但需注意浮点 ABI 限制。Yocto 提供更灵活的包管理和镜像定制能力,适合量产产品长期维护,但学习曲线更陡。
应用开发可直接使用发行版预构建镜像:Debian riscv64(支持 VisionFive 2、Lichee Pi 4A 等)、Fedora 38+(桌面体验最完整)、openEuler RISC-V(TH1520、SG2042 等平台镜像)。发行版镜像的硬件基线是 RV64GC + lp64d,C 扩展为强制项。

六、BSP:从 QEMU virt 到真实硬件

QEMU virt 是理想化平台,提供标准化的中断控制器、UART、PCIe、virtio 等设备模型,设备树由 QEMU 自动生成。从 QEMU 切换到真实硬件,主要差异在:设备树(QEMU 自动生成 vs 真实硬件需手写或从厂商 SDK(如玄铁 Linux SDK)获取,时钟节点缺失、pinctrl 配置不匹配、中断号映射错误是常见问题);驱动适配(virtio 标准化接口 vs 各厂商外设驱动,部分 SoC 驱动尚未合入主线);启动配置(BootROM 加载地址和介质各芯片不同,QEMU 环境中不存在这些差异);调试接口(真实硬件通过 JTAG,配合 OpenOCD + GDB)。

七、调试环境

GDB 交叉调试建议加载 vmlinux(带 debug info 的 ELF)而非 Image。gdb-multiarch 是多数发行版提供的多架构 GDB 包。
RISC-V 的 perf 支持取决于 PMU 实现。QEMU virt 提供基本 cycle/instruction 计数器。真实硬件的 PMU 事件覆盖取决于 SoC 实现,玄铁 C950 已集成 Perf Top-Down 性能分析框架(TMAM),支持通过标准 perf stat --topdown 进行分层微架构瓶颈归因。
ftrace 等内核调试手段与 x86 一致。RISC-V 特有的调试点是 SBI 调用追踪——可通过 SBI debug 扩展或 OpenSBI 日志级别配置观察 M-mode/S-mode 交互。

结语

当前介入 RISC-V Linux 开发的技术门槛已显著降低。工具链双路径可用,QEMU 系统级模拟成熟,内核主线支持 RV64GC + Vector + Hypervisor,OpenSBI/U-Boot 已进入主线。真正需要投入精力的不再是环境搭建,而是 BSP 适配中的设备树修正、主线驱动回合、性能调优——这些工作与 Arm Linux 生态早期的工程路径高度相似,已有的嵌入式 Linux 开发经验可直接迁移。
如需深入了解相关内容,可参考高性能 RISC-V 计算页

相关阅读

RISC-VLinux工具链
您尚未登录,请登录后再评论
回答(0)
非常抱歉,暂无相关数据
非常抱歉,暂无相关数据
订阅
商务咨询
AI Assistant
AI