引言
RISC-V 作为开放指令集架构,近年来在嵌入式领域发展迅猛。本文以全志 D1-H(玄铁 C906 内核)为例,完整梳理从芯片上电到 Linux Kernel 运行的启动全链路。
启动流程总览
Power On
└─ BootROM (掩膜固化,不可修改)
└─ SPL (Secondary Program Loader,加载至 SRAM)
└─ OpenSBI (RISC-V Supervisor Binary Interface)
└─ U-Boot / UEFI
└─ Linux Kernel
└─ RootFS (init)
各阶段详解
1. BootROM
芯片出厂固化,一般做最基本的初始化:时钟配置、DDR 初始化、从 Flash/SD 卡加载 SPL。RISC-V 上电后 PC 指向 0x00000000(M-mode),BootROM 的核心职责是跳转到下一阶段。
2. SPL
受限于片内 SRAM 大小(通常 32KB~128KB),SPL 必须精简。主要任务:初始化 DDR、配置 PLL 时钟树、加载 OpenSBI 和 U-Boot 到 DDR。
// SPL 入口 (start.S)
.globl _start
_start:
csrr a0, mhartid // 读取 hart ID
li t0, 0
beq a0, t0, boot_core // 仅 hart 0 执行初始化
wfi // 其他 hart 等待
boot_core:
call board_init_f // 板级初始化
call spl_load_opensbi // 加载 OpenSBI
3. OpenSBI
OpenSBI 提供 SBI(Supervisor Binary Interface),是 M-mode 和 S-mode 之间的桥梁。内核通过 ecall 指令调用 OpenSBI 服务(如 IPI、计时器、远程 fence 等)。
4. U-Boot
U-Boot 在 S-mode 运行,负责加载设备树(.dtb)和内核镜像(Image),并准备启动参数。
BSP 开发要点
- 设备树 (.dts):描述外设地址映射、中断号、时钟信息。在 Linux 内核
arch/riscv/boot/dts/下编写 - 驱动移植:SPI、I2C、UART、Ethernet 等标准外设一般复用内核已有驱动,仅需在 .dts 中正确配置
- 烧录调试:使用 xfel(全志烧录工具)或 OpenOCD + JTAG
RISC-V 生态日趋成熟,从 MCU 级别到 Linux 级别都有完整的软件栈支持。国产芯片的崛起为嵌入式开发者提供了更多选择。