3. BootROM与启动阶段划分

Zynq-7000 与 Zynq UltraScale+ MPSoC 的启动过程并不是“上电即运行应用程序”,而是由芯片内部一段固化代码接管,再逐级把控制权交给外部软件。理解这条链路的阶段划分,是定位启动故障、设计可靠启动方案的基础。本节围绕 BootROM 的作用、Stage-0 到 Stage-3 的职责边界、FSBL 与 U-Boot/ATF 的角色分工,以及各阶段故障域展开。

BootROM:芯片内的第一段可信代码

BootROM 是掩膜在芯片内部的只读代码,上电复位后由 Cortex-A9(Zynq-7000)或 Cortex-A53(MPSoC)从固定地址开始执行。它不依赖外部存储即可运行,因此承担了“最小可信根”的角色。BootROM 的主要工作包括:采样启动模式引脚(MIO[8:2] 等)确定启动设备;初始化最基本的时钟与所选启动控制器;从启动设备读取 Boot Header 与第一阶段引导镜像;校验镜像完整性(Zynq-7000 使用校验和,MPSoC 支持 RSA/ECDSA 认证与加密);校验通过后把镜像搬移到 OCM(On-Chip Memory)并跳转执行。

BootROM 的关键约束是容量极小、功能固定、不可修改。它只认识 Boot Header 规定的镜像格式,因此后续所有灵活性都必须由 FSBL 承担。若 BootROM 阶段失败,芯片通常表现为无任何串口输出、反复复位或 JTAG 无法识别,这类故障无法通过软件修补,只能从启动模式、镜像格式、供电与时钟等硬件层面排查。

Zynq 启动阶段划分与故障域 Stage-0 BootROM 模式采样 / 镜像读取 校验 / 搬移到 OCM 故障域:硬件/镜像格式 Stage-1 FSBL DDR / 时钟 / MIO 初始化 PL 配置 / 加载下一级 故障域:DDR/PL/镜像 Stage-2 U-Boot / ATF 外设驱动 / 环境变量 加载内核 / 安全监控 故障域:存储/网络/配置 Stage-3 OS / 应用 Linux / RTOS 用户空间 故障域:驱动/文件系统 移交 移交 移交 各阶段故障域与可靠性关注点 Stage-0 故障域 • 启动模式引脚电平错误 • QSPI/SD 供电或时钟异常 • Boot Header 格式不符 • 镜像校验和/签名失败 • OCM 搬移越界 现象:无串口输出 反复复位 / JTAG 不可见 排查:示波器测引脚 核对 BOOT.BIN 头 Stage-1 故障域 • DDR 训练失败/参数错 • 时钟 PLL 未锁定 • MIO 复用配置冲突 • PL bitstream 损坏 • 下一级镜像地址错误 现象:FSBL 打印后卡死 DDR 读写校验失败 排查:FSBL 调试串口 Vivado DDR 配置核对 Stage-2 故障域 • 存储介质读取失败 • 网络 TFTP/NFS 不通 • 环境变量损坏 • 内核镜像格式错误 • ATF 与 U-Boot 版本不匹配 现象:U-Boot 命令行 无法加载内核 排查:printenv 检查 ping / tftp 验证 Stage-3 故障域 • 内核驱动缺失/冲突 • 根文件系统挂载失败 • 设备树与硬件不符 • 应用依赖库缺失 • 看门狗未喂狗复位 现象:内核 panic 挂载 rootfs 失败 排查:dmesg 日志 设备树比对

Stage-0 到 Stage-3 的职责边界

把启动链拆成四个阶段,核心目的是明确“谁负责什么、失败时该找谁”。Stage-0 由 BootROM 完成,职责是“找到并验证第一段镜像”;Stage-1 由 FSBL 完成,职责是“把芯片带到可以运行复杂软件的状态”;Stage-2 由 U-Boot 或 ATF 完成,职责是“准备操作系统运行环境并加载内核”;Stage-3 是操作系统与应用程序,职责是“提供最终业务功能”。

需要特别说明的是,Zynq-7000 与 MPSoC 的阶段划分略有差异。Zynq-7000 的典型链路是 BootROM → FSBL → U-Boot → Linux;MPSoC 则引入 ATF(ARM Trusted Firmware),形成 BootROM → FSBL → ATF → U-Boot → Linux 的结构,其中 ATF 运行在 EL3,负责安全监控与 PSCI 电源管理。无论哪种芯片,Stage-0 与 Stage-1 的边界始终是“BootROM 跳转到 FSBL”,这是启动链上第一个可被开发者干预的交接点。

FSBL:从裸芯片到可运行环境

FSBL 是开发者可以修改的第一段代码,通常由 Xilinx Vitis 根据硬件平台(XSA)自动生成,再按需裁剪。它的执行顺序大致为:读取 Boot Header 中的分区表;初始化 DDR 控制器并完成训练;配置时钟与 MIO;若分区表中包含 bitstream,则配置 PL;最后根据分区表把下一级镜像(U-Boot 或 ATF)搬移到 DDR 指定地址并跳转。

FSBL 阶段最常见的故障是 DDR 初始化失败。例如某设计使用 DDR3-1600,若 Vivado 中 DDR 型号、位宽或时序参数与实际硬件不一致,FSBL 可能在 DDR 训练时卡住,串口只输出到 “DDR init” 便停止。此时应核对 XSA 中的 DDR 配置,并用 FSBL 调试版本观察训练日志。另一个常见问题是 PL 配置失败,通常由 bitstream 与硬件不匹配或供电不足引起,表现为 FSBL 打印 “PL configuration failed”。

U-Boot 与 ATF:承上启下的加载器

U-Boot 是 Stage-2 的主角,它提供命令行、环境变量、存储与网络驱动,负责把内核镜像(Image 或 zImage)、设备树(DTB)和根文件系统加载到 DDR,然后跳转到内核入口。U-Boot 的可靠性关注点集中在存储介质与网络:QSPI 读取失败、SD 卡接触不良、TFTP 服务器不可达、环境变量被写坏,都会导致“U-Boot 能起来但加载不了内核”。

在 MPSoC 中,ATF 位于 U-Boot 之前,运行在 EL3,负责建立安全世界与非安全世界的隔离,并提供 PSCI 服务。ATF 与 U-Boot 的版本需要匹配,否则可能出现 “BL31 跳转后无输出” 或 “PSCI 调用失败导致 CPU 无法上线”。排查时可用 JTAG 连接,确认 BL31 是否成功加载到 DDR 并跳转。

各阶段故障域与可靠性关注点

把故障域按阶段划分后,排查思路会清晰很多。Stage-0 故障通常没有串口输出,应优先检查启动模式引脚、启动设备供电与时钟、BOOT.BIN 的 Boot Header 格式;Stage-1 故障通常有 FSBL 打印,应重点检查 DDR 配置、时钟、MIO 与 PL bitstream;Stage-2 故障通常能进入 U-Boot 命令行,应检查存储、网络、环境变量与镜像格式;Stage-3 故障通常表现为内核 panic 或挂载失败,应检查设备树、驱动与根文件系统。

可靠性设计建议:为 Stage-0 保留正确的启动模式跳线;为 Stage-1 在 FSBL 中加入 DDR 训练失败重试;为 Stage-2 使用双分区(A/B)镜像与回滚机制;为 Stage-3 启用看门狗并在应用层定期喂狗。这样即使某一阶段镜像损坏,系统仍有机会回退到可用版本。

最后需要强调,启动链的每一级都依赖上一级的正确交接。BootROM 只认 Boot Header,FSBL 只认分区表,U-Boot 只认环境变量与镜像格式。任何一级的格式或地址错误,都会让后续阶段无法执行。因此在实际工程中,应把 BOOT.BIN 的生成、分区表配置、环境变量保存和镜像版本管理纳入统一的构建流程,而不是在上板失败后再逐级猜测。