3. SoC 启动与复位调试
SoC 上电后的前几百毫秒,是软硬件协同调试中最难观测、也最容易出问题的阶段。此时 CPU 刚退出复位,DDR 尚未初始化,串口可能还没配置,操作系统和调试代理都不存在。一旦启动失败,现象往往只是“没有任何输出”或“电流停在某个值”,传统打印和断点手段几乎失效。本章围绕上电复位序列、BootROM 跟踪、启动模式选择、早期启动失败定位以及 TRACE32 脚本化复位控制展开,目标是让工程师能够在“黑屏”阶段建立可观测性。
上电复位序列与启动模式选择
典型 SoC 的复位并非单一信号,而是由电源管理芯片(PMIC)输出的多路电源就绪信号、外部复位输入、内部上电复位(POR)电路和看门狗复位共同作用的结果。以一颗常见的 ARM 架构 SoC 为例,其复位释放顺序大致为:核心电源稳定 → PLL 锁定 → 复位控制器释放 CPU 复位 → CPU 从复位向量取指。复位向量地址由芯片的启动模式引脚(Boot Mode Pin)在复位释放瞬间采样决定,常见组合如下表所示。
| BOOT[2:0] | 启动介质 | 典型用途 |
|---|---|---|
| 000 | BootROM(内部 ROM) | 正常量产启动 |
| 001 | SPI NOR Flash | 小容量固件 |
| 010 | eMMC | 主流存储启动 |
| 011 | SD 卡 | 开发调试 |
| 100 | UART 下载 | 工厂烧录/救砖 |
| 101 | USB 下载 | 快速恢复 |
| 110/111 | 保留/测试模式 | JTAG 直连 |
启动模式引脚的电平必须在复位释放前保持稳定,否则采样结果可能落在保留组合上,导致 CPU 进入未定义状态。调试时若发现“同一固件有时能启动、有时不能”,应优先用示波器检查 BOOT 引脚在复位释放沿附近的电平是否干净。
BootROM 跟踪与早期启动失败定位
BootROM 是固化在芯片内部的一段只读代码,负责初始化最基础的时钟、扫描启动介质、加载第一阶段引导程序(如 SPL 或 BL1)。它通常不提供源码,但会通过一组固定的“启动进度寄存器”或“启动状态码”暴露执行阶段。TRACE32 可以在 CPU 复位释放后立即接管,通过读取这些寄存器判断 BootROM 走到了哪一步。
例如,某 SoC 的 BootROM 状态寄存器位于 0x1E0000A0,其低 8 位含义为:0x01 表示时钟初始化完成,0x02 表示介质探测完成,0x03 表示镜像头校验通过,0x04 表示已跳转到 SPL。若读回值为 0x02,说明 BootROM 卡在镜像头校验,常见原因是存储介质中前 4KB 的头部签名或长度字段不合法。此时可用 TRACE32 直接 dump 介质前 64 字节,与 BootROM 期望的格式逐字段比对。
TRACE32 脚本化复位控制
手动点击复位按钮难以复现“上电—复位释放—BootROM—SPL”这一完整时序。TRACE32 提供 SYStem.RESet、SYStem.Up、SYStem.Mode 等命令,可编写 .cmm 脚本实现可重复的复位控制。下面是一段示例脚本,用于在复位释放后立即停住 CPU 并读取启动状态。
; reset_boot_trace.cmm
SYStem.Mode Down
SYStem.CPU CortexA53
SYStem.JtagClock 10MHz
SYStem.Mode Prepare
SYStem.RESet
SYStem.Up
; 复位释放后立即停住
Break.Set 0xFFFF0000 /Program
Go
WAIT !STATE.RUN()
; 读取 BootROM 状态寄存器
PRINT "BOOT_STATUS = " %Hex(Data.Long(0x1E0000A0))
; dump 介质头部
Data.Dump 0x00000000 /Long
ENDDO
脚本中 SYStem.Mode Prepare 让调试器在复位释放前完成 JTAG 连接准备,SYStem.RESet 触发目标复位,SYStem.Up 在复位释放后接管 CPU。关键点是 Break.Set 设在复位向量处,使 CPU 一退出复位就停在第一条指令,从而保留最原始的启动现场。
启动失败定位的典型路径
早期启动失败通常表现为三类:完全无输出、输出乱码、输出停在某一行。完全无输出时,先用 TRACE32 确认 CPU 是否真的在取指——若 PC 停在复位向量且反复重启,多半是看门狗或电源问题;若 PC 已跑飞,则检查启动模式引脚和复位向量映射。输出乱码通常是 UART 时钟源或分频配置错误,可在 SPL 中打印时钟寄存器验证。输出停在某一行,则结合 BootROM 状态码和 SPL 的打印点,定位到具体初始化步骤。
上图把电源、复位、启动模式采样、BootROM、状态寄存器、SPL 以及 TRACE32 的介入点放在同一条链路上,便于对照定位。实际调试时,建议先用脚本在复位向量处停住,确认 PC 和启动模式采样值,再单步或设断点跟踪 BootROM 的状态码变化,最后进入 SPL 检查 DDR 初始化是否成功。这样即使没有任何串口输出,也能通过 JTAG 和状态寄存器还原启动过程。
0x1E0000A0 和状态码仅为教学示例,实际使用时请以芯片手册为准。把复位控制脚本化之后,每次启动失败都可以用同一条命令序列复现现场,避免手工操作引入的时序差异。进一步地,可以把状态码读取、介质头部 dump、PC 采样值打印合并到一个 .cmm 脚本中,形成“一键启动诊断”流程,显著缩短早期启动问题的定位时间。