memory layout¶
1. DualOS¶
1.1 LH mode¶
本章节主要介绍LH mode image加载阶段和执行阶段的memory layout。此部分内容涉及到image加载阶段的启动流程知识,你需要先了解LH mode启动流程,可参考启动流程。
1.1.1 memory layout组成¶
DualOS的memory layout可区分为几个主要的区域:
- Linux: 运行linux所需空间,由linux管理,该区域需要包含完整的ramdisk区域。
- Linux ramdisk: 本区域需要完整的包含在Linux区域内。
- MMA: 运行image pipeline所需的buffer,该区域由mma_heap模块管理。
- RTOS: 运行RTOS所需的空间,该区域由RTOS管理。
- RTOS Timestamp: 本区域需要完整的包含在RTOS的区域内。
以ipc-rtos_iford.nor.uclibc-9.1.0-ramdisk.ssz029c.128.qfn128_ddr3_demo_aov_defconfig为例:
图1-1 image加载阶段和执行阶段memory layout图
1.1.2 各阶段介绍¶
image加载阶段:
| 名称 | 简述 | Load Address | 编译阶段调整方法 |
|---|---|---|---|
| Linux image | linux镜像 | 0x20008000 | 固定在0x20008000 |
| IPL CUST share memory | IPL/IPL CUST共享内存,本区域需要完整的包含在Linux区域内 | 0x20800000-0x216fff00 | IPL的defconfig(与IPL共用,不允许修改): CONFIG_SHMEM_DRAM_BASE查看load addr CONFIG_SHMEM_DRAM_LIMIT查看size |
| Linux Ramdisk | Linux initial ramdisk package | 0x217fffc0-0x21829a92 | 固定值image/script.mk的INITRAMFSLOADADDR |
| IPL CUST-ROM | IPL CUST代码、只读变量、非0全局变量,本区域需要完整的包含在Linux区域内 | 0x21f00000-0x21f06cd0 | IPL的defconfig(不建议修改): CONFIG_IPL_CUST_ROM_BASE控制load addr CONFIG_IPL_CUST_ROM_LIMIT控制size |
| IPL CUST-RAM | IPL CUST初始化为0的全局变量,堆栈,本区域需要完整的包含在Linux区域内 | 0x21f20000-0x21f30c40 | IPL的defconfig(不建议修改): CONFIG_IPL_CUST_RAM_BASE控制load addr |
| IPL CUST DRAM heap | IPL CUST malloc()的内存池,本区域需要完整的包含在Linux区域内 | 0x21f40000-0x22000000 | IPL的defconfig(不建议修改): CONFIG_SHMEM_DRAM_BASE控制load addr CONFIG_SHMEM_DRAM_LIMIT控制size |
| u-boot image | u-boot镜像,主要功能是加载其他image | 0x23dfffc0-0x23e31052 | uboot defconfig: CONFIG_SYS_TEXT_BASE控制load addr |
| RTOS image | RTOS镜像 | 0x27007fc0-0x27152632 | Alkaid defconfig: RTOS addr = 0x20000000 + CONFIG_DRAM_SIZE - CONFIG_RTOS_MEM_SIZE + 0x8000 |
说明:
RTOS起来后会分配MMA内存,所以在加载阶段各区域不能与MMA区域有重叠。
执行阶段:
在不重新编译image的前提下,可通过uboot env动态调整 Linux/Linux ramdisk/MMA/RTOS 相关参数,saveenv保存后下次开机时生效。
pure linux生效的为bootargs_linux_only,dualOS生效的为bootargs和bootargs_rtos。
| 名称 | 简述 | Start Address | Size | 编译阶段调整方法 | runtime调整方法 |
|---|---|---|---|---|---|
| Linux | 运行linux所需空间 | 固定在0x20000000 | 可调 | Alkaid defconfig: CONFIG_LX_MEM_SIZE控制size |
bootargs子字串LX_MEM控制size |
| Linux Ramdisk | 本区域需要完整的包含在Linux区域内 | 固定在0x21800000 | 不可调(编译结果决定) | 固定值image/script.mk的INITRAMFSLOADADDR | bootargs的子字串initrd控制start addr |
| MMA | 运行image pipeline所需的buffer | 可调 | 可调 | addr = linux Start addr + CONFIG_LX_MEM_SIZE size = CONFIG_DRAM_SIZE - CONFIG_LX_MEM_SIZE - CONFIG_RTOS_MEM_SIZE |
bootargs/bootargs_rtos的子字串mma_base控制start addr mma_size控制size |
| RTOS | 运行RTOS所需的空间 | 可调 | 可调 | Alkaid defconfig: CONFIG_RTOS_MEM_SIZE控制size addr = MMA addr + MMA size RTOS defconfig: CONFIG_RTOS_MEM_START_VA/CONFIG_RTOS_MEM_START_PA控制start addr CONFIG_RTOS_MEMORY_SIZE控制size |
bootargs_rtos的子字串rtos_size控制size rtos_base控制start addr |
| RTOS Timestamp | 本区域需要完整的包含在RTOS的区域内 | 可调 | 可调 | Alkaid defconfig: CONFIG_RTOS_TIMESTAMP_MEM_SIZE控制size addr = RTOS ramdisk addr - CONFIG_RTOS_TIMESTAMP_MEM_SIZE - 0x1000 |
bootargs_rtos的子字串rtosts_addr控制start addr rtosts_size控制size |
说明:
1.Linux addr与memory size需alignment 1MB
2.RTOS addr与memory size需alignment 1MB
3.rtos ramdisk和rtos timestamp需alignment 4K
4.128M DRAM IPL CUST限制在32M以内,并且LX_MEM的size不能小于32M
5.如果sys_memmap.c不是源码,修改RTOS defconfig不生效
注意:
LH mode下无load rtos ramdisk动作,Alkaid defconfig中的CONFIG_RTOS_RAMDISK_MEM_SIZE配置为无效配置,bootargs_rtos的子字串rtosrd_addr和rtosrd_size为无效字段。
1.1.3 memory layout调整¶
在alkaid defconfig 调整各个runtime module 的size


make defconfig 之后会在project\configs 目录下生成dram_layout.txt

make image 之后会check 各个runtime module 的load addr 是否有重叠。在project\image\output\images 目录生成load_addr.txt

layout需符合以下原则
- 不得超出物理DRAM大小。
- 加载期间各区域不可重叠。
- 运行期间linux/rtos ramdisk区域必须完整落在linux/rtos 区域内,若打包内容太多且linux/rtos区域不够大,可能会导致解析ramdisk失败。经验值是ramdisk不要超过linux/rtos区域的⅓。
- 执行期间rtos timestamp区域必须完整的落在rtos区域内。
1.1.4 Debug¶
调整layout后开机异常的debug方法
若原始layout可以正常开机,但调整layout后开机异常,可采取以下debug SOP:
1.整理当前IPL_Cust/u-Boot/Linux/Ramdisk/MMA/RTOS的规划范围,确保符合前述原则。
2.确认开机失败在哪个阶段,例如:
- 可以启动IPL_Cust但RTOS启动失败 → 检查RTOS区域设定。
- 可以启动RTOS但Linux启动失败 → 检查Linux和Ramdisk区域设定。
- 可以启动Linux但解析ramdisk失败 → 检查Ramdisk区域和大小是否合理。
运行时查看内存的方法
1.图1-1蓝色部分划分给linux,由linux管理;使用情况可以用linux通用命令查看,如:
cat /proc/meminfo
cat /proc/vmallocinfo
2.图1-1黄色部分划分给MMA,由sys管理;使用情况查看:
cat /proc/mi_modules/mi_sys/mi_sys0
cat /proc/mi_modules/mi_sys_mma/mma_heap_name0
3.图1-1绿色部分主要划分给RTOS,由RTOS自己管理。
RTOS主要用heap和pool管理memory,查看方法如下:
先将uart log输出模式由buffer mode切换至direct mode,防止打印内存信息太多,导致messages dropped,输入命令:
echo cli log_mode_sw > /proc/dualos/rtos
然后查看对应memoryinfo,输入命令:echo cli memstat ? > /proc/dualos/rtos
显示结果如图1-2所示:
图1-2 memstat图

根据需要打印相关信息,例如打印内存使用信息,输入命令:echo cli memstat --usage > /proc/dualos/rtos
显示结果如图1-3所示:
图1-3 memstat --usage图

以QFN128 DDR3 128M为例,RTOS总的划分16M = Total Heap size + 代码段 size(可通过未压缩的rtos bin档size确认)