2. Boot ROM基础

在 i.MX 系列处理器中,Boot ROM 是芯片上电后执行的第一段代码,它固化在芯片内部的只读存储区中,用户无法修改。理解 Boot ROM 的固件结构、启动设备选择逻辑以及串行下载模式,是掌握整个 U-Boot 启动链的起点。很多启动失败问题,根源并不在 U-Boot 或内核,而在于 Boot ROM 阶段就没有正确进入预期的启动路径。

Boot ROM 的固件结构

i.MX Boot ROM 内部通常由几个固定功能区组成。最底层是芯片初始化代码,负责在极短时间内建立最基本的运行环境,包括时钟树的基础配置、内部 RAM(OCRAM)的初始化以及必要的电源域使能。紧接着是启动设备探测与选择模块,它按照芯片熔丝(eFUSE)中配置的启动设备顺序,依次尝试从各个候选设备读取启动镜像。再往上是镜像解析与验证模块,负责识别 IVT(Image Vector Table)和 Boot Data 结构,校验 DCD(Device Configuration Data)并执行其中的寄存器配置。最后是串行下载协议处理模块,当所有启动设备都失败或用户强制进入下载模式时,Boot ROM 会通过 USB 或 UART 等待主机发送镜像。

需要特别注意的是,Boot ROM 使用的 RAM 空间非常有限,通常只有几十 KB 到一百多 KB。这意味着它只能加载一个很小的初始镜像(如 SPL 或 U-Boot 的 first stage),由这个镜像再去初始化 DDR 并加载更大的完整 U-Boot。这个“小马拉大车”的接力关系,是理解整个启动链的关键。

i.MX Boot ROM 启动路径与镜像接力关系 Boot ROM(芯片内固化) ① 芯片基础初始化 时钟 / 电源域 / OCRAM ② 启动设备探测 按 eFUSE 顺序尝试 ③ 镜像解析与验证 IVT / Boot Data / DCD ④ 串行下载协议 USB / UART 等待主机 可用 RAM 空间 约 64–128 KB OCRAM 仅能加载小型初始镜像 OCRAM 中的初始镜像 SPL / 第一阶段引导 初始化 DDR 控制器 加载完整 U-Boot 从启动设备读取 跳转到 DDR 执行 DDR 中的完整 U-Boot U-Boot Proper 完整命令行环境 加载内核 / 设备树 从存储或网络 启动操作系统 串行下载模式(USB/SDP) 主机发送 SDP 命令 Boot ROM 写入 OCRAM 跳转执行下载镜像 eFUSE 决定启动设备优先级

启动设备选择逻辑

i.MX 芯片支持多种启动设备,常见的有 eMMC、SD 卡、NAND Flash、NOR Flash、QSPI Flash 以及串行下载。Boot ROM 如何决定从哪个设备启动?答案在 eFUSE 的 BOOT_CFG 字段中。芯片出厂时该字段通常为全 0,表示按默认顺序尝试;量产时通过烧写 eFUSE 可以固定启动设备顺序,甚至锁定只允许从某一设备启动。

以 i.MX6ULL 为例,BOOT_CFG1[7:4] 的取值决定启动设备:0b0000 表示从 NOR Flash 启动,0b0001 表示从 NAND Flash 启动,0b0010 表示从 SD/eMMC 启动,0b0011 表示从 QSPI 启动。当 BOOT_CFG 配置为从 SD 卡启动时,Boot ROM 会依次检查 SD 卡的启动分区,读取偏移 0x400 处的 IVT 结构。如果 IVT 的头部标记(0xD1 0x00 0x20 0x40 等)校验失败,则继续尝试下一个启动设备,直到所有设备都失败后进入串行下载模式。

这里有一个工程上非常实用的判断依据:如果板子上电后串口没有任何输出,且 USB 口被主机识别为“SE Blank”或“Freescale SemiConductor”设备,说明 Boot ROM 没有找到有效启动镜像,已经回落到串行下载模式。这通常意味着启动设备中的镜像损坏、IVT 位置错误或 eFUSE 配置与硬件实际连接不符。

串行下载模式与 USB/SDP 协议

串行下载模式是 Boot ROM 提供的一条“救砖”通道。当启动设备中没有有效镜像时,Boot ROM 会初始化 USB OTG 控制器,枚举为一个特定的 USB 设备,等待主机通过 SDP(Serial Download Protocol)发送镜像。SDP 协议的核心命令包括:写入内存(Write File)、跳转执行(Jump Address)、读取内存(Read File)等。主机工具(如 NXP 的 mfgtools 或开源的 imx_usb_loader)通过 USB 批量传输端点发送这些命令,Boot ROM 接收后将数据写入 OCRAM 指定地址,最后通过 Jump 命令跳转执行。

使用 imx_usb_loader 下载并运行一个 SPL 镜像的典型命令如下:

# 将 SPL 镜像通过 SDP 协议下载到 i.MX6ULL 的 OCRAM 并执行
sudo ./imx_usb u-boot-spl.bin

# 工具内部实际执行的 SDP 交互流程(简化):
# 1. 主机发送 HAB_SECURITY_GET_STATUS 确认芯片状态
# 2. 主机发送 WRITE_FILE 命令,指定目标地址 0x00910000
# 3. 主机通过 USB 批量端点传输 u-boot-spl.bin 数据
# 4. Boot ROM 将数据写入 OCRAM 0x00910000
# 5. 主机发送 JUMP_ADDRESS 命令,Boot ROM 跳转到 0x00910000 执行

在实际调试中,SDP 下载的地址必须与镜像链接地址一致。例如 SPL 的链接脚本中定义了 CONFIG_SPL_TEXT_BASE=0x00910000,那么 imx_usb_loader 的配置文件中也必须将目标地址设置为 0x00910000。地址不匹配会导致跳转后取指异常,表现为串口无输出或输出乱码。

实用判断:如果 USB 下载后串口仍然无输出,优先检查三个点:镜像链接地址与下载地址是否一致、DCD 配置是否与目标板 DDR/时钟匹配、IVT 中的自校验字段是否正确。这三项是 Boot ROM 阶段最常见的失败原因。

Boot ROM 与后续启动阶段的关系

Boot ROM 本身不负责初始化 DDR,也不负责加载内核。它的职责边界非常清晰:完成最小化芯片初始化,从启动设备或串行下载通道获取一个可执行的初始镜像,验证其基本结构后跳转执行。这个初始镜像通常是 SPL(Secondary Program Loader),它运行在 OCRAM 中,负责初始化 DDR 控制器、配置时钟树,然后从启动设备读取完整的 U-Boot 镜像到 DDR 中,最后跳转到 DDR 中的 U-Boot 入口。

理解这个接力关系后,排查启动问题时就可以按阶段定位:串口完全无输出且 USB 枚举为下载设备,问题在 Boot ROM 阶段;串口有 SPL 输出但卡在 DDR 初始化,问题在 SPL 阶段;SPL 输出正常但无法进入 U-Boot 命令行,问题在 U-Boot 加载阶段。每个阶段都有对应的观察点和判断依据,而不是盲目地反复烧写镜像。

阶段 执行位置 关键任务 失败表现
Boot ROM 芯片内部 ROM 基础初始化、设备探测、IVT 校验 串口无输出,USB 枚举为下载设备
SPL OCRAM DDR 初始化、加载完整 U-Boot 串口有 SPL 字样后卡住
U-Boot Proper DDR 命令行环境、加载内核 能进命令行但内核启动失败

掌握 Boot ROM 的固件结构、启动设备选择逻辑和 SDP 协议,不仅有助于理解启动链的全貌,更能在实际工程中快速定位启动故障所在的阶段。下一阶段的分析将建立在“Boot ROM 已经正确交出控制权”这一前提之上。