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 无法理解任意二进制,它只识别符合特定格式的镜像。镜像头部通常包含以下字段:
| 字段 | 作用 | 典型取值/说明 |
|---|---|---|
| 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,因此第一级镜像必须足够小。
典型加载流程如下:
- 上电复位,BootROM 根据 eFuse/GPIO 选择启动介质。
- 初始化对应控制器(如 eMMC 的 CMD0/CMD1/CMD2/CMD3)。
- 从介质固定偏移读取镜像头部(如 eMMC Boot Partition 0 的 0x0)。
- 解析头部,得到 image_size、load_addr、entry_point。
- 按块读取镜像体到 load_addr,同时计算 CRC。
- 比对头部中的 CRC/签名,通过则跳转 entry_point。
四、案例与误区复盘
案例: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 使用同一算法。
总结来看,启动介质的选择决定了 BootROM 的初始化复杂度,镜像头部决定了 BootROM 能否正确识别与校验,而加载地址则决定了第一级镜像能否在有限 SRAM 中安全运行。三者环环相扣,任何一环配置错误都会导致启动链路在最早阶段中断。调试时应优先确认介质初始化波形、头部 Magic 与 CRC 是否匹配,再检查加载地址是否越界。