2. STM32MP硬件启动机制

STM32MP1 系列(如 STM32MP157、STM32MP135)上电后,最先运行的并不是我们烧写的 U-Boot,而是固化在芯片内部 ROM 中的一段只读代码,通常称为 Boot ROM Code。它由 ST 在流片时写入,用户无法修改,是整个启动链的“第一推动力”。理解它的行为,是理解后续 FSBL、SSBL 以及 U-Boot 移植与调试的前提。

Boot ROM Code 做了什么

复位释放后,Cortex-A7 从 Boot ROM 的固定入口开始执行。Boot ROM 的核心任务可以概括为四步:读启动模式 → 选启动设备 → 加载 FSBL → 校验并跳转。它首先读取启动模式引脚(BOOT0~BOOT2)以及 OTP(One-Time Programmable,一次性可编程)熔丝中的相关位,判断本次应从哪个设备启动;随后初始化对应外设控制器(SDMMC、QSPI、FMC 等),从设备固定偏移处读取头部信息,解析镜像并做完整性校验;校验通过后,把 FSBL 搬到片上 SYSRAM 中执行。

需要特别注意的是,Boot ROM 能识别的镜像格式是固定的,它只认 ST 定义的 STM32 头部(STM32 Header)。这个头部包含魔数、镜像长度、入口地址、校验和等字段。如果头部不合法或校验失败,Boot ROM 会按启动设备顺序尝试下一个候选设备,全部失败后进入串口/USB 的恢复模式(Recovery Mode),等待外部工具通过 UART 或 USB DFU 下载镜像。这也是“变砖”后仍能救回的理论依据。

启动模式选择:Boot Pins 与 OTP

STM32MP1 的启动模式由两类信息共同决定:BOOT 引脚电平和 OTP 熔丝位。BOOT0~BOOT2 三个引脚在复位释放瞬间被采样,组合出不同的启动源。典型组合如下(以 STM32MP157 为例,具体以参考手册为准):

BOOT2BOOT1BOOT0启动源
000Boot from eMMC/SD(SDMMC1/2)
001Boot from QSPI NOR
010Boot from NAND(FMC)
100Serial/USB Recovery

OTP 的作用是“锁定”启动策略。例如,量产阶段可以把 OTP 中的 BOOT_DEV_SEL 或安全启动相关位烧写,使芯片强制从某个设备启动,或强制启用签名校验。一旦烧写不可逆,因此调试阶段通常保持 OTP 为空,仅靠引脚跳线切换启动源。实际开发板上常见用拨码开关或跳线帽控制 BOOT 引脚,切换 SD 卡启动与 eMMC 启动。

启动设备接口差异

不同启动设备在 Boot ROM 眼中的“读取方式”并不相同:

  • SD 卡 / eMMC:走 SDMMC 控制器,Boot ROM 按块读取,镜像通常放在分区起始的固定偏移(如 0x0 或 0x100)。eMMC 还支持 Boot Partition,可把 FSBL 放在独立的 boot 分区中。
  • QSPI NOR:走 QUADSPI 控制器,Boot ROM 以 1-1-1 或 1-4-4 模式读取,镜像从 Flash 起始地址开始。QSPI 启动速度快,适合作为主启动介质。
  • NAND:走 FMC 控制器,Boot ROM 需要处理坏块管理和 ECC,因此对 NAND 的页大小、ECC 配置有要求,镜像布局也更复杂。

选择哪种设备,取决于产品对成本、容量、可靠性和启动速度的权衡。工业产品常用 eMMC 或 QSPI NOR,消费类可能用 SD 卡或 NAND。

FSBL 与 SSBL 的角色划分

Boot ROM 加载的第一个用户镜像叫 FSBL(First Stage Boot Loader),在 STM32MP1 上通常就是 TF-A(Trusted Firmware-A) 的 BL2 阶段。FSBL 运行在 SYSRAM 中,负责:初始化 DDR、配置时钟树、加载并校验 SSBL、建立安全环境(如启用 TrustZone)。

FSBL 完成后跳转到 SSBL(Second Stage Boot Loader),也就是我们常说的 U-Boot。U-Boot 运行在 DDR 中,负责更丰富的功能:网络、USB、文件系统、环境变量、引导 Linux 内核。FSBL 与 SSBL 的分工可以概括为:FSBL 解决“芯片能不能跑起来”,SSBL 解决“系统能不能用起来”。

FSBL(TF-A BL2)→ 初始化 DDR/时钟 → 加载 SSBL → 跳转
SSBL(U-Boot)→ 初始化外设 → 加载 Kernel/DTB → 启动 Linux

下面这张图展示了从复位到 U-Boot 的完整硬件启动链,包括 Boot ROM 的判断逻辑、启动设备分支以及 FSBL/SSBL 的衔接关系。

复位释放 Boot ROM Code 读引脚/OTP → 选设备 → 校验 启动模式判定 BOOT0~2 + OTP SD / eMMC QSPI NOR NAND (FMC) USB/UART Recovery FSBL (TF-A BL2) SYSRAM 运行 · 初始化 DDR SSBL (U-Boot) DDR 运行 · 加载 Kernel Linux Kernel + Device Tree + RootFS FSBL 职责: DDR 初始化 · 时钟树配置 · 安全环境建立 · 加载 SSBL 运行位置:片上 SYSRAM(容量有限,代码需精简) SSBL 职责: 外设驱动 · 环境变量 · 网络/USB · 加载 Kernel 与 DTB 运行位置:DDR(空间充足,功能丰富) OTP 熔丝 锁定启动源 强制签名校验

实际调试中的观察点

在开发板上验证启动链时,最直接的手段是串口日志。Boot ROM 阶段通常没有输出,但一旦 FSBL 开始运行,串口会打印 TF-A 的版本和 DDR 初始化信息;随后 U-Boot 打印 U-Boot 2021.10 之类的版本行。如果串口毫无输出,应优先检查 BOOT 引脚电平是否正确、SD 卡/eMMC 中镜像头部是否合法。如果 FSBL 有输出但卡在 DDR 初始化,则要检查 DDR 配置参数是否与硬件匹配。

调试建议:先用 SD 卡启动验证 FSBL/SSBL 镜像正确,再切换到 eMMC 或 QSPI。因为 SD 卡可以直接在 PC 上替换文件,迭代最快。确认无误后再烧写到目标介质。

总结来说,STM32MP1 的硬件启动机制是一条由 Boot ROM 主导、FSBL 承接、SSBL 扩展的链式过程。Boot ROM 决定“从哪里启动”,FSBL 决定“芯片能否就绪”,SSBL 决定“系统能否引导”。三者各司其职,任何一环出错都会导致启动失败。掌握这条链的每个环节,才能在 U-Boot 移植和启动问题排查中快速定位根因。