3. STM32MP启动与系统基础

在STM32MP系列(如STM32MP157、STM32MP135)上部署边缘AI推理之前,必须先理解这颗异构SoC是如何从加电走到Linux用户态的。STM32MP内部包含Cortex-A7/A35应用核与Cortex-M4/M33实时核,AI推理通常运行在A核的Linux侧,因此启动链的每一环都会影响模型加载、NPU/GPU驱动初始化以及推理服务的可用性。本节沿着真实的上电顺序,把BootROM、TF-A、U-Boot、Linux内核、根文件系统与设备树串成一条可观察、可调试的链路。

一、启动链的整体结构

STM32MP的启动不是单一引导程序完成的,而是由多个阶段逐级接力。上电或复位后,芯片内部固化的BootROM首先执行,它根据BOOT引脚(BOOT0~BOOT2)和OTP熔丝选择启动介质,常见顺序为:SD卡 → eMMC → NAND → USB/UART(工程模式)。BootROM只做最小化工作:初始化必要时钟、从所选介质读取第一级引导镜像(FSBL)到内部SYSRAM,然后跳转执行。

在STM32MP的官方启动方案中,FSBL由TF-A(Trusted Firmware-A)承担。TF-A分为BL2和BL32/BL33等阶段:BL2运行在SYSRAM,负责初始化DDR、加载并校验后续镜像;BL32通常是OP-TEE(安全世界),BL33则是U-Boot。U-Boot作为通用引导加载器,负责加载Linux内核镜像(Image/zImage)、设备树(DTB)和根文件系统,并把控制权交给内核。内核挂载根文件系统后启动init进程,最终进入用户空间,AI推理应用才得以运行。

STM32MP 启动链与镜像加载关系 BootROM 固化只读 选启动介质 / 载FSBL TF-A (BL2/BL32) 初始化DDR 校验并加载BL33 U-Boot (BL33) 加载Image / DTB 传递bootargs Linux内核 解压/初始化驱动 挂载根文件系统 启动介质 SD / eMMC / NAND FSBL镜像 tf-a-*.stm32 内核与设备树 Image + stm32mp15xx.dtb 根文件系统 ext4 / squashfs 设备树 (DTB) 关键节点 • chosen / bootargs:console、root=、rootfstype • memory:DDR 基址与容量 • soc / pinctrl:外设引脚复用 • gpu / npu / csi:AI 推理相关外设 • mmc / usb:根文件系统所在介质 用户空间 init / systemd 驱动加载 AI 推理服务 模型加载 应用启动

二、BootROM与启动介质选择

BootROM的行为由硬件引脚和OTP决定,开发者能干预的空间有限,但必须理解它的选择逻辑。以STM32MP157为例,BOOT0~BOOT2引脚在上电时被采样,组合决定启动源。若BOOT2:BOOT0 = 000,则从SD卡启动;001对应eMMC;010对应NAND;100进入USB/UART工程模式。工程模式常用于量产前通过STM32CubeProgrammer烧写镜像。

BootROM从介质中读取的第一个镜像必须符合STM32MP的头部格式(包含签名、长度、目标地址等字段)。如果头部校验失败,BootROM会尝试下一个启动源,最终可能停在ROM代码的串口输出上。因此,当板子“完全无输出”时,第一步应确认BOOT引脚电平和介质中是否存在合法的FSBL镜像,而不是直接怀疑内核。

三、TF-A:DDR初始化与安全启动

TF-A的BL2阶段运行在芯片内部SYSRAM中,此时DDR尚未可用。BL2的核心任务包括:配置时钟树、初始化DDR控制器、根据设备树(TF-A自带一份精简DT)设置内存参数,然后把U-Boot镜像从介质加载到DDR,并完成签名校验。在安全启动场景下,BL2还会验证BL32(OP-TEE)和BL33(U-Boot)的签名,任一校验失败都会中止启动。

实际调试中,TF-A阶段的串口输出通常以“NOTICE: CPU: STM32MP157FAC Rev.Z”开头,随后打印DDR容量、启动介质和镜像加载地址。如果卡在这里,常见原因是DDR参数与硬件不匹配,或FSBL镜像与芯片型号不符。此时应检查TF-A的编译配置(如STM32MP15x的DDR类型、频率)是否与板卡原理图一致。

四、U-Boot:加载内核与设备树

U-Boot启动后,会读取环境变量中的bootcmd,典型流程是:从mmc或网络加载Image、DTB和根文件系统,然后执行bootz或booti。以SD卡启动为例,常见命令序列如下:

ext4load mmc 0:4 0xc2000000 /boot/Image
ext4load mmc 0:4 0xc4000000 /boot/stm32mp157f-dk2.dtb
setenv bootargs console=ttySTM0,115200 root=/dev/mmcblk0p5 rootwait rw
booti 0xc2000000 - 0xc4000000

其中0xc2000000是内核加载地址,0xc4000000是DTB地址,bootargs中的root=指向根文件系统分区。U-Boot还会把设备树地址通过寄存器传递给内核。若内核启动后提示“Unable to mount root fs”,应优先检查root=分区号与rootfstype是否正确,以及该分区是否真的包含可挂载的文件系统。

五、Linux内核启动与根文件系统

内核被解压并接管后,首先解析设备树,识别内存、CPU、中断控制器和各类外设。随后内核初始化驱动,包括MMC控制器、USB、显示、GPU以及AI推理常用的CSI摄像头接口。当内核打印“Run /sbin/init as init process”时,说明根文件系统已成功挂载,用户空间开始运行。

根文件系统通常包含/bin、/etc、/lib、/usr等目录,以及AI推理所需的运行时库(如OpenCV、TensorFlow Lite、ONNX Runtime)和模型文件。在STM32MP上,根文件系统常放在eMMC的ext4分区或SD卡分区中,也可使用只读的squashfs加overlay。若推理程序依赖的库缺失,内核仍能启动,但应用会在用户空间报“error while loading shared libraries”,这属于根文件系统内容问题,而非启动链故障。

六、设备树:硬件描述与AI外设

设备树是连接内核与硬件的关键。对于边缘AI部署,需要重点关注以下节点:

  • chosen/bootargs:内核命令行,决定控制台、根文件系统位置和调试级别。
  • memory:DDR基址与大小,影响模型可用的内存空间。
  • soc/pinctrl:引脚复用,摄像头、SPI、I2C等外设依赖它。
  • gpu/npu/csi:AI推理相关外设的使能状态与时钟配置。
  • mmc/usb:根文件系统所在介质的控制器配置。

设备树通常由U-Boot传递给内核,也可与内核镜像打包为FIT镜像。修改设备树后必须重新编译DTB并更新到启动分区,否则改动不会生效。调试时可通过/proc/device-tree查看内核实际解析到的节点内容,与源文件对比可快速定位配置错误。

启动链排查建议:先看串口是否有BootROM输出,再看TF-A是否打印DDR信息,接着确认U-Boot能否加载Image和DTB,最后检查内核是否挂载根文件系统。每一阶段的输出都是下一阶段的前提,按顺序定位比盲目重烧镜像更高效。

七、启动参数与AI部署的关系

在边缘AI场景中,启动参数会直接影响推理性能与稳定性。例如,通过bootargs中的cma=64M可以为摄像头和GPU预留连续内存;rootwait确保根文件系统设备就绪后再挂载,避免eMMC初始化较慢导致挂载失败;rw与ro决定根文件系统是否可写,量产设备常设为只读以提升可靠性。此外,若使用OP-TEE,还需在设备树中正确配置安全内存区域,否则AI应用可能无法访问受保护资源。

理解从BootROM到用户空间的完整链路,是后续部署推理框架、调试驱动和优化启动时间的基础。只有每一级镜像、每一个设备树节点都正确衔接,STM32MP才能稳定进入Linux并承载边缘AI任务。