
1. 先搞懂启动链路再谈排查STM32MP235 不是一颗普通的单片机它是 ST 推出的 MP2 系列中的一员跑的是 Linux核心是 Cortex-A35。这类芯片从上电到系统完全起来中间要经过好几段 bootloader 接力。很多人一遇到 “fails to boot” 就急着盯串口日志但如果对整条启动链路没有一个全局概念日志看半天也看不出所以然。所以第一步我建议先把启动流程在脑子里过一遍。1.1 STM32MP235 的启动流程STM32MP235 的启动链路大致是这样ROM 阶段芯片内部固化的一段代码上电后 first 执行。它的任务很简单——根据 BOOT 引脚的电平状态决定从哪个介质加载下一段代码。这个阶段你基本干预不了也无法调试只能祈祷它别出问题。FSBL 阶段第一级 bootloader在 STM32MP2 系列里就是 TF-ATrusted Firmware-A的 BL2 部分。它负责最基础的时钟、DDR 初始化然后加载 OP-TEE 和 BL33。OP-TEE 阶段安全世界Secure World的运行时环境。如果 OP-TEE 加载失败整个系统直接卡死不会有任何后续输出。U-Boot 阶段也就是 BL33正常世界的引导加载程序。它负责加载 kernel 和设备树把控制权交给 Linux。Kernel 阶段Linux 内核启动挂载根文件系统init 进程接管。这里有个和 STM32MP1 不太一样的地方MP1 系列的 DDR 初始化通常在 FSBL 里完成而 MP2 系列把 DDR 初始化也放进了 TF-A 的早期阶段。这意味着如果你的 DDR 配置有问题在 TF-A 阶段就会暴露而不是等到 U-Boot 才报错。排查方向要跟着架构走不能拿 MP1 的旧经验硬套。1.2 boot 失败的本质搞清楚卡在哪一棒我把所有 boot 失败问题归结为一句话系统在某个阶段没能把接力棒交到下一棒手里。每一段接力都有各自的“交接信号”ROM → TF-ATF-A 有没有开始执行看串口有没有输出 TF-A 的版本信息。如果连这个都没有问题大概率出在启动介质选择、镜像烧录位置或者硬件本身。TF-A → OP-TEE/U-Boot看日志有没有报告 DDR 初始化失败、OP-TEE 加载失败。卡在这一步多半是 DDR 参数不对、TrustZone 配置错误或者镜像签名校验失败。U-Boot → KernelU-Boot 打印了启动 logo、读到了设备树但 kernel 起不来。常见原因是设备树和硬件不匹配、kernel 镜像损坏、以及 boot 参数配置错误。Kernel → 文件系统kernel 已经起来了但挂载 rootfs 失败。这是另一类问题通常在 initramfs 或者根文件系统类型配置上找原因。如果连卡在哪一段都分不清那就没法谈排查。这也是我为什么一直强调先看日志再看代码最后才动烙铁。2. 第一现场串口日志怎么读串口是整个排查过程中最重要的信息源没有之一。STM32MP235 的调试串口默认跑在某个固定的 UART 上具体是哪个要看你的板卡设计。拿到板子的第一件事就是把串口接好波特率、电平、接线确认清楚。2.1 串口连接的前置条件很多人在串口上栽跟头不是板子坏了而是物理连接根本没打通。电平匹配STM32MP235 的 UART 是 3.3V TTL 电平不能直接怼到 RS232 或者某些只认 5V 电平的调试器上。用 USB 转 TTL 模块时确认模块的输出电平是 3.3V。如果不确定用万用表量一下。TX/RX 交叉这是几乎每个人都踩过的坑。调试器 TX 要接板子的 RX调试器 RX 接板子的 TX。接反了串口工具里什么都看不到。波特率别搞错默认 115200 8N1 是 ST 官方固件最常见的配置。但如果你的 bootloader 被修改过波特率就得先确认实际配置。有个小技巧如果用 minicom 或 screen 连串口连接前先随便敲几个字符看终端有没有回显乱码。如果完全没反应多半是接线问题如果有乱码说明数据在走只是波特率不对。2.2 三段式日志分析法拿到完整日志后不要从头到尾逐行读那样效率太低。我习惯把日志切成三段来看第一段ROM 和 TF-A 阶段。看有没有 TF-A 的版本号打印。STM32MP2 系列的 TF-A 日志会输出类似NOTICE: BL2: v2.x这样的信息。如果这段日志缺失说明要么没从正确的介质启动要么时钟/电源初始化就挂了。第二段U-Boot 阶段。看 U-Boot 有没有正常打印版本号以及启动命令执行的情况。正常情况下U-Boot 会打印U-Boot 20xx.xx以及一堆板级信息。第三段Kernel 阶段。看有没有Starting kernel ...后面有没有 kernel 的启动 banner以及最后 panic 或卡死的位置。实际排查时把整段日志保存到一个文件里然后分段标注时间点这样定位问题会快得多。我每次都会在日志文件头部贴上板卡型号、软件版本、复现时间方便后续追溯。注意STM32MP235 如果使能了 TrustZone还要留意 OP-TEE 的日志。有些安全相关的 boot 问题日志不会直接报 “fail”而是卡在一个地方不动这时候要看有没有 OP-TEE 的初始化记录。3. 逐个击破三类最常见的 boot 失败根据我处理过的案例STM32MP235 boot 失败可以粗略分成三类。每一类的现象、原因和排查思路都不一样。3.1 完全无输出先查硬件底子现象串口什么打印都没有上电后电流有变化但就是看不到任何字符。这种问题最让人头疼因为信息量为零。我一般的排查顺序是查电源。STM32MP235 的供电时序要求很严格VDD 核电压、DDR 电压、IO 电压之间的上电顺序不能乱。用示波器量各路电源的上升时序重点看有没有在要求的窗口内全部稳定。很多板子启动失败就是电源时序错了那么几毫秒。查复位。确认 NRST 引脚在释放后是高电平并且没有外部器件一直在拉低。有些设计里看门狗芯片的复位输出接在 NRST 上如果看门狗配置不对芯片会反复进入复位状态现象就是永远起不来。查 BOOT 引脚配置。STM32MP235 会通过 BOOT0/BOOT1/BOOT2 等引脚的电平组合决定从哪个介质启动。如果引脚电平配置和实际烧录的介质不一致ROM 代码找不到有效的启动镜像串口同样不会有输出。查时钟。芯片需要外部晶振或者时钟源才能工作。如果 HSE 晶振没起振或者 MCO 时钟配置错误整个芯片都跑不起来。用示波器看晶振引脚有没有振荡信号。这些项目全部查完后如果还是无输出那就得考虑芯片本身、板卡制造缺陷或者焊接问题了。这个时候再动烙铁也不迟。3.2 有输出但卡在 TF-A现象串口能看到 TF-A 的部分日志但系统没有继续往下跑。这类问题比完全无输出好办因为有了日志可以分析。常见的几个点DDR 初始化失败。TF-A 日志中如果有ERROR关键词或者卡在 DDR 相关的初始化流程里优先怀疑 DDR 参数配置。STM32MP2 系列的 DDR 参数通过设备树/配置文件传递给 TF-A如果你的板卡换了 DDR 颗粒型号仿真参数没有对应更新就会出问题。看看 TF-A 有没有把 DDR 初始化结果打印出来比如INFO: DDR: ...。OP-TEE 加载失败。TF-A 在加载 OP-TEE 镜像时如果出现问题日志会有明确提示。常见原因是 OP-TEE 镜像损坏、签名校验失败或者 OP-TEE 所需的 DDR 保留区域配置不当。镜像签名验签失败。如果开启了安全启动Secure BootTF-A 会对所有后续镜像做验签。一旦签名不对就会拒绝加载并停止。很多人开发阶段根本没配签名但工程模板里可能默认开了这个选项结果就是自己把自己卡死。排查手段上有条件的话可以接上 JTAG/SWD 调试器在 TF-A 源码里打断点看它到底卡在哪个函数。没有调试器的话就仔细读日志TF-A 的日志详细程度可以通过编译选项调整开 DEBUG 级别后能看到更多信息。3.3 卡在 U-Boot 到 Kernel 之间现象U-Boot 已经启动但执行bootcmd后卡住或者 kernel 启动到一半死掉。先把 bootcmd 和 bootargs 搞明白。U-Boot 环境的bootargs决定了 kernel 启动参数包含了 console、root、init 等关键信息。很多时候 kernel 起不来就是 console 参数和实际串口设备不匹配导致 kernel 日志全部输出到黑洞里去了。设备树匹配问题。如果 U-Boot 加载的设备树和实际硬件不一致kernel 可能在初始化某个外设时崩溃。常见现象是U-Boot 正常退出但 kernel 没有任何输出。这个时候先确认设备树编译时用的板级配置是否正确。STM32MP235 的设备树中有大量和电源、时钟相关的内容错了任何一个节点都可能导致 kernel 在启动早期卡死。镜像加载地址问题。U-Boot 要把 kernel 和设备树加载到 DDR 的指定地址。如果地址配置和 kernel 编译时预期的运行地址不一致kernel 解压或启动时就会出问题。查看 U-Boot 的 load 地址和 kernel 的 TEXT_OFFSET 是否匹配。rootfs 问题。如果 kernel 已经起来了但最后卡在 mount root 失败重点检查 bootargs 中的root参数、根文件系统类型和实际存储介质是不是对得上。比如你用的是 SD 卡启动但root指向了 eMMC 设备那必然失败。实际排查时我习惯在 U-Boot 里手动敲命令一步步执行 bootcmd 拆开来看。比如先fatload加载镜像再确认fdt addr设置正确最后手动bootm。这样能定位到具体是哪一步没做好。4. 几分钟能出结果的排查速查表4.1 常见问题快速对照下面这个表是根据实际经验整理的遇到问题可以先对着查一遍。现象高概率原因快速检查方式串口无输出供电/复位/BOOT引脚示波器量时序确认BOOT电平串口无输出调试串口接错确认TX/RX和电平匹配卡在TF-A早期时钟或DDR问题看晶振波形核对DDR配置卡在TF-A后期OP-TEE加载失败确认镜像签名和DDR保留区U-Boot正常但kernel无输出console参数错误核对bootargs的consolekernel输出后panic设备树不匹配检查设备树板级节点挂不上rootfsroot参数错误确认根文件系统所在设备节点4.2 我常用的三条调试思路第一善用 U-Boot 的bootargs临时修改能力。很多时候不需要重新编译整个固件在 U-Boot 命令行里用setenv修改 bootargs再保存环境变量就能快速调整启动参数验证是不是配置问题。第二把日志分段保存。每次调试前把串口工具的日志保存功能打开作为备份。就算当下没发现问题回头再看日志往往能发现之前忽略的细节。我吃过太多亏每次都是事后翻旧日志才找到问题。第三不要一个人硬憋。STM32MP235 相关的讨论区、ST 官方社区、Github 上的 issue都可能有人已经踩过同一个坑。遇到奇怪的问题先搜索一下再动手有时候十分钟找到的答案比自己调试一天还靠谱。5. 总结STM32MP235 fails to boot本质上是一个多阶段启动链路中的接力失败问题。排查的关键在于先理清启动流程再分段看日志最后针对性地定位和修复。大多数情况下问题出在电源时序、BOOT配置、DDR参数、设备树或者 bootargs 上而这些都可以通过系统化的排查流程快速收敛。我在实际调试中最深的体会是不要急着改代码先把现场证据收集完整。一份完整的串口日志、一次准确的电压时序测量往往比十次盲目的代码修改更有效。希望这篇文章能帮你少走一些弯路早日看到 Linux 启动的 friendly welcome。