内存布局调整指南
前言
本文描述了小系统各模块如何定义内存空间并给出示例修改,以指导开发人员根据实际业务场景,调整系统的内存布局。
与本文档相对应的产品版本如下。
本文档主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
修订记录累积了每次文档更新的说明。最新版本的文档包含以前所有文档版本的更新内容。
说明:
以下描述以Hi3516CV610为例,如无特殊说明,Hi3516CV608与Hi3516CV610内容一致。
概述
在调整内存布局时,要充分考虑布局变动对各模块间的影响。
本文将阐述各模块与内存布局的关系,以及修改内存布局的方法。涉及模块如下:
- GSL(general secure bootloader)
- U-Boot
- Linux内核
- MMZ
- OP-TEE OS
默认内存布局
无 TEE 场景

有 TEE 场景

有 TEE OS 和无 TEE OS 的内存布局相比,需要考虑在 Linux Kernel 外预留出 OP-TEE OS 的内存。
注意:
有 TEE 时,调整 Linux 内存,可关掉 OP-TEE 的动态共享内存( CFG_CORE_DYN_SHM=n), 或者修改 OP-TEE 中 core/arch/arm/plat-vendor/main.c 文件中 DRAM0_BASE 的值与 Linux 内存范围一致。
地址范围定义
本章描述各模块如何定义自身使用的内存空间。
说明:
各模块先给出文件路径,然后描述该文件中涉及内存布局定义的配置项、宏、变量的含义。
GSL(general secure bootloader)
修改boards/dmeb/components/gsl/include/platform.h文件
- BL32_BASE —— OP-TEE OS起始地址
- BL32_SIZE —— OP-TEE OS运行时内存大小
GSL 承担了在固定地址加载启动安全固件(OP-TEE OS)的工作,因此需要在代码中定义安全固件的运行地址范围。
U-Boot
修改third_party/u-boot/u-boot-2022.07目录下配置文件。
U-Boot 加载Kernel 和 DTB 的地址配置:boards/dmeb/tools/pc/image_tree_source/linux_image.its
Linux Kernel
根据场景修改 Linux Kernel 源码中以下文件,Linux Kernel 源码位于third_party/linux/linux-5.10.y:
无TEE:boards/dmeb/dts/hi3516cv610-demb.dts
/memory 节点的 reg 属性,描述 kernel 可用的内存地址空间。定义如下:
其中 reg 属性定义了内核 memory 的基地址和大小。
示例:Kernel 起始地址 0x40008000,最大内存空间 0x40000000(1GB)。
说明:
/memory 节点定义的是 Kernel 可管理的最大内存,bootargs 中配置的 mem 字段会限制 Kernel 实际内存大小。 例如:/memory 节点配置了 1GB 大小,而 bootargs 配置了 mem=32M,最终 Kernel 内存只有32M。 Hi3516CV610 内核可用内存大小默认以 4K 为粒度管理。自解压方式启动的内核,运行地址需按 128M 对齐。
MMZ
smp/a7_linux/source/out/ko/load3516cv610/目录下的 KO 加载脚本 load3516cv610_10b为例配置了 MMZ 的内存范围:
- mmz_start:linux mmz起始地址
- mmz_size:linux mmz内存大小
说明:
MMZ 起始地址和内存大小以 4K 为粒度对齐。
OP-TEE OS
使用 OP-TEE OS 应关注以下种类的内存:
- TEE OS 内存:安全 OS 内部分配、使用;
- SMMZ:给具有访问安全内存权限的硬件分配、使用。
SMMZ 在 OP-TEE OS 启动时初始化。因此,相关内存地址都在 OP-TEE OS 目录下定义。
TEE OS 内存
修改third_party/optee/optee_os-3.20.0目录下core/arch/arm/plat-vendor/hi3516cv610.mk文件。
- CFG_TZDRAM_START,TEE OS 内存空间起始地址
- CFG_TZDRAM_SIZE,TEE OS 内存空间大小
- CFG_SHMEM_START,非安全的静态共享内存空间起始地址
- CFG_SHMEM_SIZE,非安全的静态共享内存空间大小
SMMZ
third_party/optee/optee_os-3.20.0目录中core/arch/arm/dts/hi3516cv610.dts 定义了 SMMZ 的内存布局,用一个设备树节点表示,用 reg 属性定义范围。
示例:SMMZ 节点地址从 0x43000000 开始,大小为 0x400000(4M)。
smmz2: smmz@2 {
compatible = "vendor,memory_zone";
reg = <0x0 0x43000000 0x0 0x400000>;
secure-node = "okay";
status = "okay";
};
内存布局修改示例
Kernel 内存增大 32 MB
Linux Kernel 增大 32MB 后,MMZ 受到影响往后偏移32MB(0x2000000)
-
Linux Kernel 的 bootargs 中 mem 字段增大到 64MB
修改为:
-
MMZ 的基地址改为 0x42000000 + 0x2000000 = 0x44000000,size 缩小32MB
文件:smp/a7_linux/source/out/ko/load3516cv610/load3516cv610_10b
修改为:
U-Boot 运行时内存布局
加载过程

GSL 加载 U-Boot 到内存后,U-Boot 会进行自解压与 relocate,最终在 relocate 地址运行。
说明:
U-Boot 运行起来后,SRAM 会被设置为安全属性。因此不建议在 U-Boot 运行时操作 SRAM,以免引发问题。
运行时地址

U-Boot 在初始化过程中,会将自己 relocate 到可见内存的末端位置。
默认配置的可见内存从 0x40000000 开始,大小为 0x20000000,因此 U-Boot 被 relocate 到 0x60000000 之前。
通过启动日志可以看到 relocate 的具体信息,例如下述日志显示 U-Boot 被重定向到 0x43b5eed0:
System startup
Uncompress Ok!
U-Boot 2022.07-g98aa117d50 (Apr 06 2024 - 14:36:30 +0800)hi3516cv610-debug
DRAM: Relocation Offset is: 0279f000
Relocating to 43f9f000, new gd at 43b5eed0, sp at 43b5eeb0
相关地址定义
-
third_party/u-boot/u-boot-2022.07目录下文件:include/configs/hi3516cv610.h
- PHYS_SDRAM_1,U-Boot 可见物理内存基址
- PHYS_SDRAM_1_SIZE,U-Boot 可见物理内存大小
-
third_party/u-boot/u-boot-2022.07/configs目录下配置文件,如:hi3516cv610_defconfig