4. 启动介质与镜像格式

在 BootROM 到内核启动的完整链路中,启动介质决定了“第一段代码从哪里来、以什么方式被读取、读取后放到哪里”。不同介质的电气特性、访问方式和可靠性机制差异很大,BootROM 必须为每种介质准备独立的驱动与加载策略。理解这些差异,是排查“上电无输出”“卡在 BootROM”“镜像校验失败”等问题的前提。

一、核心原理:介质特性决定加载方式

启动介质大致分为两类:可直接寻址的并行/映射型介质(如 NOR Flash)和需要命令交互的块设备型介质(如 NAND、eMMC、SD、UFS)。前者上电后 CPU 可直接从地址总线取指执行(XIP),后者必须先由 BootROM 内的控制器驱动初始化,再按块读取到 SRAM 中执行。

  • NOR Flash:支持随机访问与 XIP,读取可靠、无坏块,但容量小、成本高、写入慢。常用于存放 BootROM 之后的 SPL/Preloader。
  • NAND Flash:容量大、成本低,但存在坏块、需要 ECC 校验,且只能按页读取。BootROM 需内置 BCH/LDPC 纠错与坏块跳过逻辑。
  • eMMC:集成控制器,支持分区(Boot Partition、RPMB、User Data),有可靠的命令协议,是当前主流启动介质。
  • SD/TF 卡:协议与 eMMC 相近,常用于开发板量产与恢复模式,速度等级和电压切换影响初始化成功率。
  • UFS:串行全双工、高速率,采用 SCSI 命令集与 UniPro 链路,启动流程比 eMMC 更复杂,需先完成链路训练。
关键结论:BootROM 的介质驱动是“最小可用集”,它只实现读取启动镜像所需的最简命令,不包含完整文件系统与写入能力。

二、镜像头部:BootROM 识别镜像的“身份证”

BootROM 无法理解任意二进制,它只识别符合特定格式的镜像。镜像头部通常包含以下字段:

字段作用典型取值/说明
Magic标识镜像合法如 0x53424C33("SBL3")
Header Version头部格式版本决定后续字段解析方式
Image Size镜像总长度用于计算读取块数与校验范围
Load Address加载目标地址如 SRAM 0x00100000
Entry Point跳转执行地址通常等于 Load Address
Checksum/CRC完整性校验CRC32 或 SHA256
Signature安全启动验签RSA/ECDSA 签名

以高通 SBL 为例,头部结构可简化为:

struct boot_image_header {
    uint32_t magic;          // 0x53424C33
    uint32_t version;
    uint32_t image_size;
    uint32_t load_addr;      // 0x00100000
    uint32_t entry_point;
    uint32_t crc32;
    uint8_t  signature[256];
};

三、校验与加载地址:从介质到 SRAM 的搬运

BootROM 读取镜像后,必须先校验再跳转。校验失败会触发重试或进入恢复模式(如 USB 下载)。加载地址的选择受限于 BootROM 可用的片上 SRAM 大小,通常只有几十到几百 KB,因此第一级镜像必须足够小。

典型加载流程如下:

  1. 上电复位,BootROM 根据 eFuse/GPIO 选择启动介质。
  2. 初始化对应控制器(如 eMMC 的 CMD0/CMD1/CMD2/CMD3)。
  3. 从介质固定偏移读取镜像头部(如 eMMC Boot Partition 0 的 0x0)。
  4. 解析头部,得到 image_size、load_addr、entry_point。
  5. 按块读取镜像体到 load_addr,同时计算 CRC。
  6. 比对头部中的 CRC/签名,通过则跳转 entry_point。
调试提示:若串口无任何输出,优先确认 BootROM 是否成功读取头部。可用示波器抓 eMMC CLK/CMD 或 NAND RE/WE,观察是否有初始化波形。

四、案例与误区复盘

案例:eMMC 启动失败但 SD 卡启动正常。现象为插入 SD 卡可正常启动,切换到 eMMC 后串口无输出。排查发现 eMMC 的 Boot Partition 未烧录镜像,且 eFuse 中启动顺序将 eMMC 置于首位。BootROM 读取头部时 Magic 不匹配,直接跳到下一启动项,最终无输出。解决方法是重新烧录 Boot Partition 并校验 CRC。

误区一:认为镜像越大越好。BootROM 的 SRAM 有限,第一级镜像超过可用 SRAM 会导致加载地址越界,表现为跳转后跑飞。应严格控制 SPL/Preloader 体积。

误区二:忽略 NAND 坏块。NAND 启动时 BootROM 会跳过坏块,若镜像被烧录到坏块区域,读取数据会出错。量产时应使用带坏块管理的烧录工具。

误区三:校验算法不一致。头部声明 CRC32,但实际烧录工具写入的是简单累加和,导致 BootROM 校验失败。必须确保烧录工具与 BootROM 使用同一算法。

启动介质 → 镜像头部 → 校验 → 加载地址 数据流 启动介质 NOR Flash XIP / 无坏块 NAND Flash ECC / 坏块管理 eMMC Boot Partition SD / TF 恢复 / 量产 UFS 链路训练 / SCSI 镜像头部 Magic 0x53424C33 Image Size Load Address Entry Point CRC32 / SHA256 Signature Header Version 校验与决策 CRC 比对 签名验签 失败重试 进入恢复模式 加载与跳转 SRAM 0x00100000 按块搬运 跳转 Entry 执行 SPL BootROM 只实现最小读取命令;镜像头部必须与烧录工具一致;加载地址受 SRAM 容量限制

总结来看,启动介质的选择决定了 BootROM 的初始化复杂度,镜像头部决定了 BootROM 能否正确识别与校验,而加载地址则决定了第一级镜像能否在有限 SRAM 中安全运行。三者环环相扣,任何一环配置错误都会导致启动链路在最早阶段中断。调试时应优先确认介质初始化波形、头部 Magic 与 CRC 是否匹配,再检查加载地址是否越界。