3. ROM Code启动机制
TI Sitara 系列(AM335x、AM437x、AM57x 等)在上电或复位后,最先运行的并不是 U-Boot,而是固化在芯片内部的一段只读代码,通常称为 ROM Code。它相当于芯片的“第一段固件”,职责非常明确:在外部存储或外设尚未被初始化之前,用最少的片上资源找到一段可执行的二级引导程序,把它搬进片内 SRAM 并跳转执行。理解 ROM Code 的行为,是排查“板子上电没反应”“串口无任何输出”“只打印 CCC”等启动问题的前提。
一、ROM Code 的启动阶段划分
ROM Code 的执行可以拆成四个连续阶段,每个阶段都有明确的输入与判定条件:
- 上电复位与最小初始化:复位释放后,CPU 从 ROM 内部固定地址取指。ROM Code 先配置 PLL 到基础频率、初始化片内 SRAM、设置看门狗与时钟,并读取芯片的启动模式引脚(SYSBOOT)状态。此时外部 DDR 尚未初始化,因此后续所有代码只能运行在片内 SRAM 中。
- 引导设备枚举:根据 SYSBOOT 引脚的电平组合,ROM Code 生成一张“候选设备列表”,按优先级依次尝试。列表顺序由引脚决定,而不是由软件指定。
- 镜像获取与校验:对每个候选设备,ROM Code 按该设备协议读取头部(Header),校验魔术字、镜像大小、校验和等字段。校验通过才继续搬运,否则放弃该设备并尝试下一个。
- 搬运与跳转:把镜像主体搬入片内 SRAM 的固定地址(AM335x 上通常为 0x402F0400),然后跳转到该地址执行。至此 ROM Code 使命结束,控制权交给二级引导程序。
需要特别注意的是:ROM Code 只认识“引导头 + 镜像”这一种格式,它不解析文件系统,也不理解 ELF。因此无论后面是 SPL 还是 U-Boot,第一段被加载的镜像必须满足 ROM Code 的格式要求。
二、引导设备枚举顺序
SYSBOOT[4:0] 五个引脚共同决定启动顺序。以 AM335x 为例,常见的组合含义如下(示例值,具体以对应芯片 TRM 为准):
| SYSBOOT[4:0] | 首选设备 | 次选设备 | 典型用途 |
|---|---|---|---|
| 11000 | MMC0 (SD) | SPI0 | SD 卡启动调试 |
| 10010 | NAND | MMC0 | 量产 NAND 板 |
| 10100 | UART0 | USB0 | 串口/USB 恢复 |
| 00000 | SPI0 | MMC0 | SPI Flash 启动 |
枚举顺序的意义在于:当首选设备没有有效镜像时,ROM Code 会自动降级到次选设备,而不是直接停机。这为“主存储损坏时用 SD 卡救砖”提供了硬件基础。但要注意,枚举是串行且不可回退的——一旦在某个设备上读取到看似合法但实际损坏的头部,ROM Code 可能在该设备上反复重试并最终失败,而不会继续尝试后面的设备。
三、镜像格式要求:MLO 与 SPL 的关系
在 TI 的语境里,MLO 和 SPL 经常被混用,但严格来说:SPL 是 U-Boot 源码中的二级引导程序模块,编译产物为 u-boot-spl.bin;MLO 则是给 ROM Code 使用的、带引导头的镜像文件,通常由 u-boot-spl.bin 加上头部生成。ROM Code 只认 MLO 这种格式。
MLO 的头部结构(以 AM335x 为例)包含:魔术字、镜像大小、加载地址、CRC32 校验和等字段。ROM Code 读取头部后会先校验魔术字,再校验 CRC,两者都通过才搬运。因此如果 MLO 被截断、烧写偏移错误或 CRC 不匹配,ROM Code 会直接判定该设备无效。
# 生成 MLO 的典型流程(AM335x)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x_evm_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
# 编译后得到 spl/u-boot-spl.bin
# 使用 ti 提供的工具加头生成 MLO
./tools/mkimage -T omapimage -a 0x402F0400 -d spl/u-boot-spl.bin MLO
烧写到 SD 卡时,MLO 必须放在 FAT 分区根目录,且文件名严格为 MLO(部分版本要求全大写)。ROM Code 在 MMC 启动时按固定扇区偏移查找,而不是遍历文件系统,因此分区格式和文件位置同样关键。
四、启动失败诊断与恢复模式
当板子上电后串口没有任何输出,或只输出一个字符就停止,可以按以下顺序排查:
- 确认 SYSBOOT 引脚:用万用表测量启动模式引脚电平,确认与预期设备一致。引脚虚焊或上拉电阻缺失会导致 ROM Code 枚举到错误设备。
- 观察串口输出特征:AM335x 在 UART 启动模式下会持续输出字符
C,表示等待通过串口发送 MLO。如果看到CCCC,说明 ROM Code 已进入 UART 恢复模式,此时可用spl_uart工具或teraterm的 XMODEM 发送 MLO 进行恢复。 - 检查 MLO 头部:用
hexdump -C MLO | head查看前 16 字节,确认魔术字和大小字段合理。若头部全为 0xFF 或 0x00,说明烧写失败。 - 核对烧写偏移:SD 卡启动时 MLO 必须位于 FAT 分区,且分区起始扇区不能随意改动;NAND 启动时需确认 ECC 配置与 ROM Code 要求一致。
- 使用恢复模式:当所有存储设备都无效时,把 SYSBOOT 设为 UART 或 USB 模式,通过串口或 USB 把 MLO 直接送入片内 SRAM,绕过损坏的存储介质。这是 TI Sitara 最可靠的“救砖”手段。
把上述流程串起来看,ROM Code 的行为是高度确定性的:它不“智能”,只按引脚和头部字段做判断。因此启动失败时,最有效的做法不是反复改 U-Boot 配置,而是回到 ROM Code 的视角,逐项确认 SYSBOOT 电平、MLO 头部、烧写位置和校验结果。只要这四项中有一项不满足,ROM Code 就会在枚举阶段放弃当前设备,最终进入恢复模式或直接停机。掌握这条链路,就能把大部分“上电无输出”的问题定位到具体环节。