1. STM32MP Linux BSP工程全景

在开始移植之前,先把“BSP到底由什么组成、系统从加电到应用启动经过哪些阶段、哪些部分属于硬件适配、哪些属于通用软件”这几件事理清楚,后续的每一步操作才有明确的落点。STM32MP 系列(如 STM32MP157、STM32MP135)是 ST 的双核异构 MPU:一颗 Arm Cortex-A7(或 A35)应用核运行 Linux,一颗 Cortex-M4 协处理器可运行裸机或 RTOS 固件。这种“A 核跑系统、M 核跑实时任务”的结构,直接决定了 BSP 的组成与启动链路比普通单核 SoC 更复杂。

一、BSP 的组成:从固件到根文件系统

一个可启动的 STM32MP Linux BSP,本质上是若干“按启动顺序被逐级加载”的软件层,加上描述硬件的配置数据。可以按职责分成五块:

  • FSBL(First Stage Boot Loader):由 ST 提供的 TF-A(Trusted Firmware-A)实现,运行在 A 核,负责时钟、DDR、电源域等最底层初始化,并把下一级镜像搬入内存。
  • SSBL(Second Stage Boot Loader):通常是 U-Boot,负责更完整的设备初始化、环境变量管理、镜像加载策略,并最终引导内核。
  • OP-TEE:可选的安全固件,运行在 A 核的安全世界,提供可信执行环境;启用后 TF-A 会先加载它。
  • Linux 内核与设备树:内核是通用代码,设备树(.dts/.dtsi)才是描述“这块板子上有什么外设、接在哪个引脚、用什么参数”的关键适配载体。
  • 根文件系统与 M4 固件:rootfs 提供用户空间;M4 固件(.elf)由 Linux 侧的 remoteproc 框架加载,实现异构协同。

其中真正需要工程师大量改动的,集中在设备树、U-Boot 板级配置、TF-A 的 DDR/时钟参数、以及 M4 固件的资源划分这四处。内核驱动本身大多已由社区或 ST 维护,适配工作更多是“把板子描述对”。

二、启动链路:从上电到用户空间

STM32MP1 的启动是典型的“ROM Code → FSBL → SSBL → OS”多级链。上电后,片内 Boot ROM 根据 BOOT 引脚选择启动介质(eMMC、SD 卡、NOR、串口/USB 下载),从介质中读取分区头,校验并加载 FSBL。TF-A 完成 DDR 初始化后,把 U-Boot 载入 DDR;U-Boot 再加载内核、设备树与 initramfs/rootfs,最后移交控制权给内核,内核挂载根文件系统并启动 init。整个过程可以用下面的信号链来理解各级镜像的加载与交接关系。

STM32MP1 启动链路与镜像交接 Boot ROM BOOT引脚选介质 FSBL / TF-A 时钟·DDR·电源域 可选加载 OP-TEE SSBL / U-Boot 环境变量·镜像加载 bootcmd 引导内核 Linux 内核 解析设备树 挂载 rootfs 启动介质 eMMC / SD / NOR 设备树 .dtb 引脚·外设·参数 M4 固件 .elf remoteproc 加载 根文件系统 init → 用户空间 硬件适配边界(工程师主要改动点) ① TF-A:DDR 时序、时钟树、电源域、启动介质分区表 ② U-Boot:板级 defconfig、环境变量、bootcmd、网络/存储驱动 ③ 内核:设备树节点、pinctrl、驱动使能 ④ M4:资源划分、IPCC 通信、固件加载路径

理解这条链的关键在于:每一级只负责把下一级“搬进来并交权”。因此当系统卡在某一级时,排查范围天然被限定——串口无任何输出,问题在 Boot ROM 或介质分区;TF-A 打印后停住,问题多在 DDR 参数;U-Boot 能进命令行但内核起不来,问题通常在 bootargs、设备树或 rootfs 挂载参数。

三、硬件适配边界:什么该改,什么不该改

初学者最容易犯的错误,是把“通用软件问题”当成“硬件适配问题”去改。这里给出一条清晰的边界:

层次属于硬件适配(需改)属于通用软件(尽量不改)
TF-ADDR 型号与时序、时钟树、电源域、启动分区异常向量、安全启动框架
U-Boot板级 defconfig、环境变量、外设引脚命令行解析、镜像格式处理
内核设备树节点、pinctrl、regulator、驱动使能调度、内存管理、通用驱动框架
用户空间板级初始化脚本、外设权限systemd、busybox 等通用组件

判断依据很简单:凡是“这块板子特有的物理事实”,就写进设备树或板级配置;凡是“所有同架构板子都一样的逻辑”,就留在通用代码里。例如“LED 接在 PG14、低电平点亮”是物理事实,写进设备树;“GPIO 子系统如何注册字符设备”是通用逻辑,不动。

四、典型开发流程

一个完整的 BSP 适配闭环通常这样展开:先拿到 ST 官方 EVK 的 BSP 作为基线,确认能在开发板上跑通;然后基于自己的板子做硬件差异分析,列出“与 EVK 不同的部分”(DDR、PMIC、外设、引脚);接着依次修改 TF-A、U-Boot、设备树;每次修改后通过串口日志和启动阶段判断是否推进到下一级;最后验证关键外设(网络、存储、显示、串口)并固化镜像。

建议在第一次适配时保留 EVK 的完整启动日志作为“正常基线”。当自研板卡启动异常时,逐级对比日志差异,比盲目改参数高效得多。
DDR 参数错误是 TF-A 阶段最常见的“静默死机”原因。若串口在 TF-A 打印后无输出,优先核对 DDR 型号、频率与 timing 参数,而不是怀疑内核。