• 正文
  • 相关推荐
申请入驻 产业图谱

如何扩大 MP2 的 A35 核和 M33 核共享内存

19小时前
236
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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)默认预留区域包含:

  1. TF‑M 安全固件代码与数据;
  2. M33 Cube 非安全固件、数据段;
  3. OP‑TEE 安全 OS;
  4. 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 修改

  1. 修改plat/st/stm32mp2/stm32mp2_def.h,修改STM32MP_BL33_BASE、STM32MP_HW_CONFIG_BASE基地址,整体向后偏移 32MB(0x2000000)。
  2. 修改 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 处源文件:

  1. arch/arm/mach‑stm32mp/Kconfig.25x:TEXT_BASE、PRE_CON_BUF_ADDR、BOOTSTAGE_STASH_ADDR;
  2. 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;
  3. 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. 工程落地排查清单

  1. 系统上电直接黑屏,TF‑A 阶段就崩溃:检查stm32mp2_def.hBL33_BASE、HW_CONFIG_BASE 偏移;fw‑config.dtsi 里面 load‑address 以及 RISAF (st‑mem‑firewall) 的 reg 地址是否同步修改;RISAF 内存保护配置错误会直接阻断访问。
  2. U‑Boot 可以启动,无法加载 Linux 内核,报 data abort:U‑Boot 内部内核加载地址、FDT 地址、ramdisk 地址宏没有全部同步偏移;核对stm32mp25_common.h全部地址宏。
  3. Linux 启动成功,但是 remoteproc 无法启动 M33 核,M33 固件加载失败
    • Linux resmem dtsi 节点的 reg 基地址没有和 TF‑A/FIP 配置保持一致;
    • 确认 resmem 节点使用no‑map属性;确认&m33_rproc节点正确引用memory‑region。
  4. M33 能够启动,A35 与 M33 之间 IPC 通信异常:IPC 共享内存ipc_shmem_*的基地址、大小在 TF‑A 防火墙、内核 resmem 两处必须完全一致;内存区域不能被 Linux 普通内存管理覆盖。
  5. 修改完某组件,其他组件忘记同步偏移:MP2 内存修改属于全启动链联动,TF‑A、OP‑TEE、U‑Boot、内核 DTB 四者缺一不可,只改其中 1‑2 个组件一定会内存冲突。

4. 小结

  1. STM32MP2 默认 DDR 最前面 64MB 预留给 OP‑TEE、TF‑M、M33 固件以及 A35‑M33 IPC 共享内存;当 M33 需要更大数据区或者双核共享内存,需要整体扩大前端 DDR 预留空间,所有启动链组件地址同步偏移ST。
  2. 修改涉及完整启动链:TF‑A(def.h + fw‑config.dtsi+RISAF 防火墙)、OP‑TEE (conf.mk)、U‑Boot (Kconfig、defconfig、common.h)、Linux 设备树 resmem 预留内存节点。任意组件地址不一致会出现启动崩溃、M33 无法加载、IPC 通信故障。
  3. MP2 的 A35/M33 都可以直接访问 DDR,必须同步维护 RISAF 内存防火墙配置,不可直接复用 STM32MP1 内存修改方案。
  4. 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 启停全场景验证。

相关推荐