STM32MP2 系列同时具备 Cortex‑A35(Linux)与 Cortex‑M33(MCU 固件)两个异构内核。默认配置将 DDR最前面 64MB 预留给 OP‑TEE 安全固件、TF‑M、M33 Cube 固件以及双核 IPC 共享内存,剩余 DDR 交给 Linux 内核使用ST。
当业务需要更大 M33 数据区、更大 A35/M33 双核交互共享内存,默认 64MB 预留空间不足,需要整体扩大 DDR 前端预留区域。MP2 两个内核均可直接访问 DDR,修改内存映射必须同步修改完整启动链:TF‑A、OP‑TEE、U‑Boot、Linux 内核设备树,任意组件地址不一致会出现内存越界、系统启动崩溃、M33 远程处理器无法加载运行。本文基于 LAT6048 官方笔记,梳理启动链内存分布、每一个组件修改点、配置示例、落地排错。
重要提示:MP2 与 MP1 内存模型差异巨大,MP2 的 A35/M33 均可直接访问 DDR,内存防火墙 RISAF 需要跟随地址同步配置,不能直接照搬 MP1 的内存修改经验。
资料获取:应用笔记 | LAT6048 如何扩大MP2的A35核和M33核共享内存_v1.0
1 默认内存与启动链说明
1.1 默认 DDR 内存分配
DDR 起始0x80000000,前64MB(0x80000000‑0x84000000)默认预留区域包含:
- TF‑M 安全固件代码与数据;
- M33 Cube 非安全固件、数据段;
- OP‑TEE 安全 OS;
- A35 与 M33 IPC 交互共享内存; DDR 64MB 之后地址,分配给 U‑Boot、Linux 内核、CMA 缓冲区。
1.2 STM32MP2 完整启动链路(涉及内存修改)
ROM Code → TF‑A BL2 → FIP(OP‑TEE + U‑Boot) → U‑Boot → Linux Kernel
- TF‑A BL2:初始化 DDR,解析 fw‑config 设备树,加载 FIP 内各组件;
- OP‑TEE:安全世界操作系统,加载至固定 DDR 地址,运行全程地址不能变动;
- U‑Boot:二级引导,负责加载内核、DTB、ramdisk;
- Linux 内核:通过 resmem 设备树节点预留 M33 固件、IPC 共享内存,remoteproc 驱动管理 M33 核启动通信。
业务示例:把前端预留区域从默认 64MB 扩大至 96MB(额外增加 32MB 预留),所有启动链组件地址同步向后偏移 32MB。
2 各组件修改要点(以扩大 32M 预留空间为示例)
2.1 TF‑A BL2 修改
- 修改
plat/st/stm32mp2/stm32mp2_def.h,修改STM32MP_BL33_BASE、STM32MP_HW_CONFIG_BASE基地址,整体向后偏移 32MB(0x2000000)。 - 修改 fw‑config 设备树
stm32mp257f‑ev‑ca35tdcid‑fw‑config.dtsi:- 修改
dtb‑registry下soc_fw‑config、tos_fw的load‑address加载地址; - 修改
st‑mem‑firewall(RISAF)节点bl31‑context、op‑tee的 reg 寄存器地址与 RISAF 保护属性,同步更新内存防火墙配置,防止安全内存被非安全世界越界访问。
- 修改
TF‑A 通过 fw‑config.dtsi 设备树完成 FIP 各个镜像加载地址配置,RISAF 寄存器必须同步更新,否则安全内存访问异常。
2.2 OP‑TEE 修改
修改core/arch/arm/plat‑stm32mp2/conf.mk
#原配置 CFG_TZDRAM_START ?= 0x82000000
CFG_TZDRAM_START ?= 0x84000000
CFG_TZDRAM_SIZE ?= 0x02000000
CFG_TZDRAM_START为 OP‑TEE 安全内存起始,跟随整体偏移,TZDRAM 大小按需配置。
2.3 U‑Boot 修改
U‑Boot 多处地址需要统一向后偏移 32MB,涉及 4 处源文件:
arch/arm/mach‑stm32mp/Kconfig.25x:TEXT_BASE、PRE_CON_BUF_ADDR、BOOTSTAGE_STASH_ADDR;configs/stm32mp25_defconfig:CONFIG_CUSTOM_SYS_INIT_SP_ADDR、CONFIG_SYS_LOAD_ADDR、CONFIG_FASTBOOT_BUF_ADDR,内存测试起止地址CONFIG_SYS_MEMTEST_START / CONFIG_SYS_MEMTEST_END;include/configs/stm32mp25_common.h:内核、FDT、脚本、overlay、ramdisk 加载地址宏。
U‑Boot 所有 DDR 相关加载、栈、缓冲、fastboot 缓存地址必须全部同步偏移,遗漏任意一处会 U‑Boot 直接崩溃或者无法加载 Linux 内核。
2.4 Linux Kernel 设备树 resmem 节点修改
修改 board 的 resmem 预留内存 dtsi 文件,调整tfm‑data、cm33‑cube‑data、ipc_shmem_1等shared‑dma‑pool节点的reg基地址与 size。示例片段:
tfm_data: tfm‑data@80900000 {
compatible = "shared‑dma‑pool";
reg = <0x0 0x80900000 0x0 0x100000>;
no‑map;
};
cm33_cube_data: cm33‑cube‑data@80a00000 {
compatible = "shared‑dma‑pool";
/* 将cube‑data从默认8M扩大到40M,基地址同步偏移 */
reg = <0x0 0x80a00000 0x0 0x2800000>;
no‑map;
};
ipc_shmem_1: ipc‑shmem‑1@83200000 {
compatible = "shared‑dma‑pool";
reg = <0x0 0x83200000 0x0 0xf8000>;
no‑map;
};
关键点:TF‑A、OP‑TEE、U‑Boot、内核 resmem 的所有 DDR 基地址必须一一对应;no‑map属性告诉 Linux 内核不要映射该段预留 DDR,交由 M33、OP‑TEE 使用;remoteproc 驱动引用这些 memory‑region 完成 M33 固件加载与双核通信。
3. 工程落地排查清单
- 系统上电直接黑屏,TF‑A 阶段就崩溃:检查
stm32mp2_def.hBL33_BASE、HW_CONFIG_BASE 偏移;fw‑config.dtsi 里面 load‑address 以及 RISAF (st‑mem‑firewall) 的 reg 地址是否同步修改;RISAF 内存保护配置错误会直接阻断访问。 - U‑Boot 可以启动,无法加载 Linux 内核,报 data abort:U‑Boot 内部内核加载地址、FDT 地址、ramdisk 地址宏没有全部同步偏移;核对
stm32mp25_common.h全部地址宏。 - Linux 启动成功,但是 remoteproc 无法启动 M33 核,M33 固件加载失败
- Linux resmem dtsi 节点的 reg 基地址没有和 TF‑A/FIP 配置保持一致;
- 确认 resmem 节点使用
no‑map属性;确认&m33_rproc节点正确引用memory‑region。
- M33 能够启动,A35 与 M33 之间 IPC 通信异常:IPC 共享内存
ipc_shmem_*的基地址、大小在 TF‑A 防火墙、内核 resmem 两处必须完全一致;内存区域不能被 Linux 普通内存管理覆盖。 - 修改完某组件,其他组件忘记同步偏移:MP2 内存修改属于全启动链联动,TF‑A、OP‑TEE、U‑Boot、内核 DTB 四者缺一不可,只改其中 1‑2 个组件一定会内存冲突。
4. 小结
- STM32MP2 默认 DDR 最前面 64MB 预留给 OP‑TEE、TF‑M、M33 固件以及 A35‑M33 IPC 共享内存;当 M33 需要更大数据区或者双核共享内存,需要整体扩大前端 DDR 预留空间,所有启动链组件地址同步偏移ST。
- 修改涉及完整启动链:TF‑A(def.h + fw‑config.dtsi+RISAF 防火墙)、OP‑TEE (conf.mk)、U‑Boot (Kconfig、defconfig、common.h)、Linux 设备树 resmem 预留内存节点。任意组件地址不一致会出现启动崩溃、M33 无法加载、IPC 通信故障。
- MP2 的 A35/M33 都可以直接访问 DDR,必须同步维护 RISAF 内存防火墙配置,不可直接复用 STM32MP1 内存修改方案。
- resmem 设备树使用
shared‑dma‑pool与no‑map属性,保证 Linux 内核不会接管 M33/OP‑TEE 专属 DDR 区域,remoteproc 驱动使用 memory‑region 引用预留内存完成 M33 核管理。
5. FAQ
Q:能不能只扩大共享内存大小,不整体向后偏移所有组件?
A:如果原有 64MB 预留内部还有空闲 DDR,可以直接在 resmem 内部调大 size;若 64MB 已经用尽,就必须整体扩大预留窗口,全部启动链组件地址向后偏移。
Q:RISAF (st‑mem‑firewall) 不修改会发生什么?
A:RISAF 硬件内存防火墙控制安全 / 非安全域 DDR 访问权限,地址改动不更新 RISAF,OP‑TEE/M33 访问 DDR 会触发内存访问错误,系统直接挂死。
Q:修改完内存之后,M33 的 Cube 工程链接脚本需要改吗?
A:需要。M33 Cube 固件链接脚本中的 DDR 基地址、数据段地址,必须和 Linux resmem 分配的cm33‑cube‑fw、cm33‑cube‑data地址完全匹配。
免责声明:本文全部基于 ST 官方 LAT6048 文档,实际项目请参考 ST 官方 wiki、OSTL BSP 源码,DDR 地址修改完成务必完整做上电、休眠唤醒、M33 启停全场景验证。
236