4. Bootloader概述

Bootloader 是芯片上电后由 BootROM 接力加载的第一段可编程固件,它承担着“把系统从裸硬件状态带到可运行操作系统或应用环境”的桥梁作用。理解 Bootloader,不能只把它看成一个“启动程序”,而应把它视为信任链中的关键可编程环节:它既受 BootROM 的验证与约束,又负责后续镜像的加载、校验、跳转与安全策略实施。

一、Bootloader的常见类型

不同产品形态对启动速度、镜像大小、升级方式和安全等级的要求差异很大,因此 Bootloader 演化出多种类型。常见分类如下:

  • 一级引导(Primary Bootloader / SPL):通常运行在片内 SRAM,体积小,负责初始化时钟、DDR 控制器等最基础硬件,然后把二级引导搬到内存。
  • 二级引导(Secondary Bootloader / U-Boot SPL、U-Boot Proper):功能完整,支持文件系统、网络、USB、串口交互、环境变量、镜像校验与启动菜单。
  • U-Boot:嵌入式领域最广泛使用的开源 Bootloader,支持多架构、多启动介质和 FIT 镜像格式。
  • GRUB / systemd-boot:常见于 x86 PC 与服务器,支持多内核菜单、配置文件启动和 Secure Boot 验证。
  • Little Kernel / LK:常见于 Android 早期设备,负责 fastboot 与内核加载。
  • ABL(Android Bootloader):高通平台上的应用引导加载程序,负责 A/B 分区、AVB 校验和 fastboot 协议。
  • TF-A BL1/BL2/BL31:ARM 可信固件启动阶段,与 BootROM 共同构成安全启动链。

这些类型并非互斥,实际系统常采用“BootROM → SPL → U-Boot → OS”的多级组合。级数越多,灵活性越高,但信任链传递和调试复杂度也越高。

二、典型启动阶段划分

从工程视角看,Bootloader 的启动过程可划分为若干阶段,每个阶段都有明确的输入、输出和验证责任。下图展示了 BootROM 与 Bootloader 各阶段之间的接力关系与信任传递路径。

BootROM 与 Bootloader 启动阶段接力与信任链 BootROM 固化只读代码 根信任 / 验签 SPL / BL2 片内SRAM运行 初始化DDR/时钟 U-Boot Proper DDR中运行 加载/校验/跳转 OS / 应用 内核 + 根文件系统 业务运行环境 信任链传递: BootROM 验签 SPL → SPL 验签 U-Boot → U-Boot 验签内核/DTB → 内核验签根文件系统 阶段1:BootROM • 上电复位向量 • 采样启动引脚 • 读取 eFuse 公钥 • 验签 SPL 镜像 • 失败则进入恢复模式 • 不可修改,根信任 阶段2:SPL • 运行于片内 SRAM • 初始化时钟/PLL • 初始化 DDR 控制器 • 加载 U-Boot 到 DDR • 校验 U-Boot 签名 • 跳转到 U-Boot 阶段3:U-Boot • 完整驱动初始化 • 读取环境变量 • 加载内核/DTB/initrd • FIT 镜像验签 • 设置启动参数 • 跳转内核入口 阶段4:内核/OS • 解压内核镜像 • 初始化内存管理 • 挂载根文件系统 • 启动 init 进程 • 进入用户态 • 信任链终点

从图中可以看到,BootROM 是信任根,SPL 是硬件初始化的第一棒,U-Boot 是功能最丰富的加载器,内核与 OS 则是信任链的最终消费者。每一级都必须验证下一级镜像的完整性与真实性,否则信任链断裂。

三、Bootloader与BootROM的关系

BootROM 与 Bootloader 的关系可以概括为“根信任与可编程接力”的关系。BootROM 固化在芯片内部,不可修改,负责最原始的启动介质选择、镜像读取和签名验证;Bootloader 则是可编程、可升级的,负责更复杂的硬件初始化和镜像加载。

对比维度 BootROM Bootloader
存储位置 芯片内部掩膜 ROM 外部 Flash / eMMC / SD
可修改性 不可修改,出厂固化 可升级、可替换
运行内存 片内 SRAM,容量极小 DDR / 片内 SRAM
核心职责 启动介质选择、根验签、恢复模式 硬件初始化、镜像加载、启动菜单
信任角色 信任根(Root of Trust) 信任链传递者
安全能力 eFuse 公钥哈希、安全启动开关 签名校验、回滚保护、AVB

工程上常见的误区是:认为“BootROM 已经验签了,Bootloader 就可以不做校验”。实际上,BootROM 只验证它直接加载的那一级镜像;如果 Bootloader 不继续验证内核,攻击者仍可在 Bootloader 之后替换内核。因此,信任链必须逐级传递,不能只依赖 BootROM。

四、安全扩展与工程实践

现代 Bootloader 的安全扩展主要包括以下机制:

  • 安全启动(Secure Boot):每一级镜像都携带签名,加载前用公钥验证,失败则拒绝启动或进入恢复模式。
  • 回滚保护(Anti-Rollback):通过 eFuse 或安全存储记录最低版本号,防止攻击者刷入旧版有漏洞的镜像。
  • A/B 分区与无缝升级:保留两套系统镜像,升级失败可回退,避免变砖。
  • AVB(Android Verified Boot):对 system、vendor、boot 等分区做哈希树校验,确保系统分区未被篡改。
  • FIT 镜像:U-Boot 使用 Flattened Image Tree 将内核、DTB、ramdisk 和签名打包在一起,便于统一验签。
  • 调试口保护:量产设备关闭 JTAG、串口下载和 fastboot 解锁,防止物理攻击绕过启动校验。
实践建议:在项目早期就确定信任链边界和密钥管理方案。BootROM 阶段通常使用芯片厂商提供的签名工具,Bootloader 阶段则需要自行维护密钥、签名脚本和版本策略。密钥一旦泄露,整条信任链都会失效。
常见排障点:如果设备卡在 BootROM 阶段,优先检查启动引脚、eFuse 烧写状态和镜像签名格式;如果卡在 SPL 阶段,重点排查 DDR 初始化参数和时钟配置;如果卡在 U-Boot 阶段,检查环境变量、镜像加载地址和 FIT 配置;如果内核启动失败,则关注 bootargs、DTB 匹配和根文件系统挂载。
# 典型 U-Boot 启动日志片段
U-Boot SPL 2023.07 (Jan 10 2024 - 10:22:31)
Trying to boot from MMC1
NOTICE:  BL31: v2.8(release):v2.8
NOTICE:  BL31: Built : 09:15:22, Jan 10 2024
U-Boot 2023.07 (Jan 10 2024 - 10:22:31 +0800)
CPU:   i.MX8MPlus
Model: Example Board
Loading kernel from mmc 0:1
Verifying FIT image signature... OK
Starting kernel ...

从日志可以看出,启动过程依次经过 SPL、BL31、U-Boot Proper,最终完成 FIT 镜像验签并跳转内核。每一行日志都对应信任链中的一个验证或加载动作,工程调试时应逐级确认,而不是只看最终结果。

总结来说,Bootloader 是 BootROM 之后的可编程信任接力者。它既要完成硬件初始化和镜像加载,又要承担签名校验、回滚保护和分区管理等安全职责。只有把 BootROM、Bootloader、内核和文件系统纳入统一的信任链设计,才能构建真正可验证、可升级、可恢复的启动体系。