3. PolarFire SoC硬件启动流程与引导模式
PolarFire SoC 的启动过程是一条由硬件强制、逐级交接的信任链。上电后,CPU 并不会直接跳转到用户程序,而是先由固化在芯片内部的 BootROM 接管,再依次把控制权交给 HSS、U-Boot SPL 和 U-Boot proper,最终加载 Linux 内核。理解这条链的关键,不只是记住四个名字,而是搞清楚每一级运行在什么存储器里、依赖哪些硬件初始化、以及如何通过模式选择决定启动路径。
上电复位与启动模式选择
PolarFire SoC 的启动模式由器件上电复位时采样的模式引脚决定。常见的模式包括从 eNVM 启动、从外部 SPI Flash 启动、从 SD/eMMC 启动,以及通过 JTAG 或串口进入调试/恢复模式。模式引脚的状态在复位释放瞬间被锁存,因此不能在启动过程中动态改变。对于嵌入式 Linux 平台,最典型的组合是:BootROM 从 eNVM 读取 HSS,HSS 再从外部存储介质加载 U-Boot 和内核。
上电复位后,E51 监控核首先退出复位,执行 BootROM 中的固化代码。BootROM 会读取启动模式寄存器,判断当前启动源,并完成最基本的时钟、eNVM 控制器和 eSRAM 初始化。此时 DDR 尚未初始化,因此 BootROM 只能使用芯片内部的 eNVM 和 eSRAM 作为代码与数据空间。
BootROM 与 HSS 的交接
BootROM 的核心职责是“找到并验证 HSS”。在 PolarFire SoC 中,HSS 通常被烧写在 eNVM 的固定偏移处,BootROM 会读取该区域的头部信息,校验镜像完整性,然后把 HSS 复制到 eSRAM 中执行。eSRAM 容量有限,通常为 128 KB 到 256 KB 量级,因此 HSS 必须保持精简,不能依赖大容量内存。
HSS 是 PolarFire SoC 启动链中承上启下的关键组件。它运行在 E51 监控核上,主要完成以下工作:初始化 DDR 控制器和 PHY,使能 U54 应用核,配置时钟树和外设引脚复用,然后从 eNVM、SPI Flash 或 SD 卡中加载下一阶段镜像。HSS 还负责提供 Hart 间通信、系统服务调用和部分运行时管理功能。可以说,没有 HSS,U54 核无法正常启动,DDR 也无法被 Linux 使用。
U-Boot SPL 与 U-Boot proper
HSS 加载的下一级通常是 U-Boot SPL。SPL 是“Secondary Program Loader”的缩写,它的体积很小,运行在 eSRAM 或已初始化的 DDR 中,主要任务是进一步初始化 DDR(如果 HSS 未完全初始化)、配置串口和存储控制器,然后加载完整的 U-Boot proper。SPL 与 U-Boot proper 的分工是:SPL 负责“把大镜像搬进内存”,U-Boot proper 负责“提供完整引导环境和操作系统加载能力”。
U-Boot proper 运行在 DDR 中,具备完整的命令行、文件系统驱动、网络支持和镜像加载能力。它可以从 FAT/ext4 分区读取 Image、dtb 和 rootfs,也可以通过网络 TFTP 加载内核。最终,U-Boot 把设备树地址、内核入口地址和启动参数传递给 Linux 内核,完成硬件启动链的最后一跳。
eNVM、eSRAM 与 DDR 的分工
三种存储器在启动链中扮演不同角色。eNVM 是非易失性存储器,掉电不丢失,通常存放 BootROM 和 HSS 镜像,容量从几百 KB 到几 MB。eSRAM 是芯片内部的高速 SRAM,容量较小,但访问延迟低,适合运行 HSS 和 SPL 这类精简代码。DDR 是外部大容量内存,需要 HSS 或 SPL 完成初始化后才能使用,U-Boot proper 和 Linux 内核都运行在 DDR 中。
一个常见的误区是认为“BootROM 可以直接启动 Linux”。实际上,BootROM 只认识 HSS 的头部格式,不具备文件系统解析能力,也不初始化 DDR。因此,从 eNVM 到 DDR 的每一步交接都必须由上一级显式完成。如果 HSS 中的 DDR 初始化参数与板卡实际内存不匹配,U-Boot proper 会在重定位阶段崩溃,表现为串口无输出或反复重启。
启动模式的实际选择与排障
在开发阶段,通常优先使用 SD 卡或 JTAG 启动,便于快速替换镜像和调试。量产阶段则倾向于 eNVM + SPI Flash 组合,减少外部连接器带来的可靠性风险。判断当前启动模式是否生效,可以观察串口输出的第一行信息:BootROM 会打印启动源标识,HSS 会打印版本和 DDR 初始化结果,U-Boot SPL 会打印 DRAM 容量,U-Boot proper 会打印板卡型号和引导命令。
下面是一段典型的启动日志片段,用于对照判断各级是否成功交接:
BootROM: PolarFire SoC, mode = eNVM
HSS: version 2023.09, DDR init OK (2GB)
U-Boot SPL: DRAM: 2 GiB
U-Boot proper: Board: MPFS-ICICLE-KIT
Loading kernel from mmc 0:1 ...
Starting kernel ...
从这段日志可以看出,启动链的每一级都留下了可观测的痕迹。BootROM 确认了启动模式,HSS 确认了 DDR 容量,SPL 确认了 DRAM 可用,U-Boot proper 确认了板卡和内核加载路径。如果某一级缺失,就能快速定位问题发生在哪个交接点。对于 PolarFire SoC 平台工程而言,掌握这条链的存储布局和交接条件,是后续裁剪 HSS、定制 U-Boot 和优化启动时间的基础。