1. 课程导入

欢迎进入《RISC-V 多核 Linux 系统开发》课程。RISC-V 作为开放指令集架构,正在从嵌入式 MCU 快速走向应用处理器、服务器与异构计算平台;而 Linux 又是这些平台上最主流的操作系统内核。把两者结合起来,意味着你不仅要会写 C 代码,还要理解启动流程、多核调度、内存管理、设备树、驱动模型、交叉编译与板级调试。本课程的目标,是让你具备从“能跑一个 Hello World”到“能定位多核启动失败、能编写并调试一个字符设备驱动、能分析内核调度与中断行为”的完整能力。

一、学习目标:从单核裸机到多核 Linux 系统

本课程的学习目标可以拆成四个层次。第一层是架构认知:理解 RISC-V 的特权级(M/S/U)、CSR 寄存器、异常与中断入口、MMU 与页表机制,以及多核启动时 hart 的分工。第二层是系统构建:能够独立完成交叉编译工具链配置、OpenSBI 固件编译、U-Boot 移植、Linux 内核裁剪与设备树编写,并生成可启动的镜像。第三层是驱动与并发:掌握平台设备驱动、设备树匹配、中断处理、自旋锁与原子操作,理解多核环境下共享资源的保护方式。第四层是调试与优化:能够使用 JTAG、串口日志、ftrace、perf、内核 oops 分析等手段定位问题,并对启动时间、调度延迟、内存占用做基本优化。

学习主线:RISC-V 架构 → 特权级与异常 → 多核启动 → OpenSBI/U-Boot → Linux 内核 → 设备树 → 驱动 → 并发与调试。每一环都依赖前一环,缺一不可。

二、知识体系:五层结构一张图看清

为了让你在学习过程中不迷失方向,我们把整个知识体系划分为五个层次:硬件层、固件层、内核层、驱动层和应用/调试层。下面的 SVG 展示了这五层之间的依赖关系与关键组件,建议你在后续每学完一章后回到这张图,确认自己处在哪一层、下一层需要什么前置知识。

RISC-V 多核 Linux 系统开发知识体系 应用与调试层 用户态程序 · 交叉调试 · ftrace/perf · oops 分析 · 启动优化 驱动与并发层 平台驱动 · 设备树匹配 · 中断处理 · 自旋锁/原子操作 · 多核同步 Linux 内核层 进程调度 · 内存管理 · VFS · 中断子系统 · SMP 启动 · 设备模型 固件与引导层 OpenSBI · U-Boot · 设备树 DTB · 多核 hart 启动 · 镜像打包 RISC-V 硬件与架构层 RV64GC · 特权级 M/S/U · CSR · 异常/中断 · MMU 页表 · 多核 hart 越往上越接近应用 越往下越接近硬件

三、工具链与开发环境:你需要准备什么

RISC-V 多核 Linux 开发不是“装一个 IDE 就能跑”的工作,它依赖一套完整的交叉工具链和调试环境。核心工具包括:GNU 交叉工具链(riscv64-linux-gnu-gcc、ld、objdump、gdb)、OpenSBI 与 U-Boot 源码、Linux 内核源码、设备树编译器 dtc、QEMU 模拟器(用于无板卡验证)、以及可选的 JTAG 调试器(如 OpenOCD + FT2232)。如果你有真实开发板(如 VisionFive 2、StarFive、SiFive HiFive Unmatched),还需要串口工具 minicom 或 picocom。

# 典型工具链安装(Ubuntu 示例)
sudo apt install gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \
                 gdb-multiarch qemu-system-riscv64 device-tree-compiler \
                 u-boot-tools minicom

# 验证交叉编译器
riscv64-linux-gnu-gcc --version
qemu-system-riscv64 --version
dtc --version

开发环境建议采用“宿主机 + 目标机”模式:宿主机运行 Ubuntu 22.04 或 24.04,负责编译、打包和调试;目标机可以是 QEMU 虚拟平台,也可以是真实 RISC-V 开发板。QEMU 适合前期快速验证启动流程和驱动逻辑,真实板卡则用于验证中断、DMA、多核缓存一致性等硬件相关行为。

建议在课程初期就固定一个工作目录结构,例如 ~/riscv-dev/{toolchain, opensbi, u-boot, linux, rootfs, images},避免后续文件混乱。所有编译产物统一放入 images 目录,便于烧录和 QEMU 启动。

四、典型场景与常见误区

一个典型的多核启动场景是:上电后 hart0 进入 M 模式执行 OpenSBI,其余 hart 处于等待状态;OpenSBI 初始化完成后跳转到 U-Boot,U-Boot 加载 Linux 内核和设备树,内核在 S 模式启动,并通过 SBI HSM 扩展唤醒其他 hart。这个过程中任何一步出错,都会表现为“串口无输出”或“卡在 Starting kernel...”。

阶段 关键组件 常见问题 排查手段
固件启动 OpenSBI hart 未唤醒、SBI 调用失败 串口日志、JTAG 单步
引导加载 U-Boot 设备树地址错误、镜像格式不对 printenv、bootm 日志
内核启动 Linux + DTB 卡在 Starting kernel、earlycon 无输出 earlycon、initcall_debug
驱动加载 平台驱动 compatible 不匹配、probe 失败 dmesg、/sys/bus/platform
多核运行 SMP 调度 锁竞争、CPU 占用不均 perf top、ftrace、/proc/interrupts

常见误区有三个。第一,把 RISC-V 当成 ARM 的简单替换:RISC-V 的特权级、CSR、中断控制器(PLIC/CLINT)与 ARM GIC 差异很大,设备树绑定也不同。第二,忽略 OpenSBI 的作用:很多启动问题其实出在固件阶段,而不是内核。第三,只在 QEMU 上验证:QEMU 对缓存一致性、中断延迟、DMA 的模拟与真实硬件有差距,驱动在 QEMU 能跑不代表在板卡上能跑。

不要跳过串口日志。RISC-V 多核 Linux 启动过程中,串口是你最重要的“眼睛”。建议在内核配置中开启 CONFIG_SERIAL_EARLYCON 和 CONFIG_DEBUG_LL,并保留 earlycon 参数。

五、学习方法与复盘建议

本课程共 30 章,建议按“架构 → 固件 → 内核 → 驱动 → 调试”的顺序推进,每章至少完成一次动手实验。学习时准备一个“问题日志”,记录每次启动失败的现象、日志、排查过程和最终原因。多核 Linux 开发的核心能力不是记住所有 API,而是建立“从现象到层次”的定位能力:看到串口无输出,先判断是固件、引导还是内核;看到驱动 probe 失败,先查 compatible 和地址;看到系统卡顿,先看中断和调度。

当你完成本课程后,应该能够独立完成以下任务:在 QEMU 或真实板卡上启动一个多核 RISC-V Linux 系统;编写并加载一个字符设备驱动;使用设备树描述硬件;分析一次内核 oops;并用 ftrace 或 perf 观察多核调度行为。这些能力,正是 RISC-V 多核 Linux 系统开发工程师的日常核心工作。