Memory Layout¶
1. PureLinux¶
本文主要介绍alkaid下如何生成可视化dram layout 与 bootargs 内存参数详解(包含mma等size调整方法)
1.1 可视化dram layout实现说明¶
当前 alkaid project/build_pre_process_config.sh 负责读取Kconfig设置的size,计算dram_layout并生成所需的环境变量/编译选项/加载地址等
1.1.1 核心函数及参数说明¶
function add_region_to_layout() {
local module="$1"
local start_hex="$2"
local end_hex="$3"
local size_hex="$4"
local parent="$5"
local start_print=$(addr_to_offset "$start_hex")
local end_print=$(addr_to_offset "$end_hex")
local size_print="${size_hex:-"-"}"
local parent_print="${parent:-"-"}"
printf "%-12s %-18s %-18s %-12s %-12s\n" "$module" "$start_print" "$end_print" "$size_print" "$parent_print" >> "$DRAM_LAYOUT"
}
$1:模块名称
$2:起始地址(cpu base地址,可以是0x100000000 base,也可以是0x20000000 base)
$3:结束地址(cpu base地址,可以是0x100000000 base,也可以是0x20000000 base)
$4:模块大小
$5:父模块名称(如CMA/MMA这种在LX内部reserve的模块,支持不传入地址)
1.1.2 调用时机¶
在 alkaid project/build_pre_process_config.sh中,确保所有runtime模块都有调用add_region_to_layout函数进行记录,当前纳入统计的模块有:
add_region_to_layout "CMA" "" "" "$cma_size" "LX"
add_region_to_layout "FB" "" "" "$fb_size" "LX"
add_region_to_layout "LOGO" "$((logo_start_addr + dram_base_addr))" "$((logo_end_addr + dram_base_addr))" "$logo_size" "LX"
add_region_to_layout "FIRMWARES" "" "" "$component_size" "LX"
add_region_to_layout "LX" $lx_addr $lx_end_addr $lx_size
add_region_to_layout "MMA" "" "" "$mma_size" "LX"
add_region_to_layout "MMA" $mma_addr $mma_end_addr $mma_size
add_region_to_layout "IPU" $ipu_addr $ipu_end_addr $ipu_size
add_region_to_layout "RTOS" $rtos_addr $rtos_end_addr $rtos_size
add_region_to_layout "VMM" $vmm_addr $vmm_end_addr $vmm_size
add_region_to_layout "OPTEE" $optee_addr $optee_end_addr $optee_size
add_region_to_layout "RISCV" $riscv_addr $riscv_end_addr $riscv_size
add_region_to_layout "TFA" $tfa_addr $tfa_end_addr $tfa_size
1.1.3 可视化脚本¶
project/scripts/dram_layout_graph.py 读取由build_pre_process_config.sh生成dram_layout.txt,生成可视化html
# 依赖plotly库,需在python3环境下运行
python3 scripts/dram_layout_graph.py --input configs/dram_layout.txt --output configs/dram_layout.html
举例如下,cat project/configs/dram_layout.txt内容:
===========================================================================
DRAM: 0x0-0x40000000
Generation time: 2025-12-18 12:03:03
===========================================================================
MODULE Start End Size Parent
---------------------------------------------------------------------------
CMA - - 0x400000 LX
FB - - 0x1CF0000 LX
LOGO 0x3f500000 0x3fd00000 0x800000 LX
LX 0x0 0x3fd00000 0x3FD00000 -
MMA - - 0x10000000 LX
RISCV 0x3fd00000 0x3ff00000 0x200000 -
TFA 0x3ff00000 0x40000000 0x100000 -
以上例子既包含了地址确定的模块,又包含了地址不确定,但父模块确定的模块,dram_layout_graph.py处理结果如下图示(使用浏览器打开可视化html)
-
对于地址确定的模块,使用实体色块显示,鼠标悬停后可显示具体的地址信息
图1-1

-
对于地址不确定,但父模块确定的模块,仅从父模块中模拟占用一块内存,但位置不具有实际意义,使用阴影色块显示,鼠标悬停后不显示具体的地址信息
图1-2

-
可通过点击上方色块实现单独显示或屏蔽某个模块的效果
图1-3

运行时查看内存的方法
1.图1-1蓝色部分划分给linux,由linux管理,使用情况可以用linux通用命令查看,如:
2.图1-1绿色条纹部分划分给MMA,由sys管理,使用情况查看:
1.2 bootargs 内存参数详解¶
bootargs 是 U-Boot 传递给 Linux 内核的启动参数,其中包含了关键的内存配置信息。以下是一个典型的 bootargs 示例:
bootargs=ubi.mtd=ubia,2048 root=/dev/mtdblock6 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x1000000000,0x80000000 cma=2M mma_heap=mma_heap_name0,miu=0,sz=0x22000000 mma_memblock_remove=1 mma_heap=mma_heap_fb,miu=0,sz=0x4048000 mmap_reserved=fb,miu=0,sz=0x800000,max_start_off=0x7f800000,max_end_off=0x80000000 mtdparts=nand0:1920k@1280k(BOOT),1920k(BOOT_BAK),256k(ENV),256k(ENV1),5m(KERNEL),5m(KERNEL_BACKUP),4m(rootfs),1152k(MISC),109952k(ubia)
1.2.1 内存相关参数说明¶
| 参数 | 含义与作用 | 对应defconfig配置 | 如何修改 |
|---|---|---|---|
LX_MEM= |
Linux 内存配置(内核可用的系统内存空间) 格式: LX_MEM=<基地址>,<大小>(arm64)或 LX_MEM=<大小>(arm32)示例: LX_MEM=0x1000000000,0x80000000(基地址0x1000000000,大小2GB) |
CONFIG_LX_MEM_SIZE |
修改 defconfig 中的 CONFIG_LX_MEM_SIZE |
cma= |
CMA(Contiguous Memory Allocator)连续内存区域大小 用于 DMA、Framebuffer、Camera 等需要物理连续内存的设备 格式: cma=<十进制大小>M(本项目脚本只生成带 M 单位的格式)示例: cma=2M、cma=16M(由脚本从十六进制配置自动转换) |
CONFIG_CMA_MEM_SIZE |
修改 defconfig 中的 CONFIG_CMA_MEM_SIZE(十六进制)脚本自动转换为十进制+M单位格式 |
mma_heap= |
MMA(Memory Management Allocator)内存堆配置 格式: mma_heap=<名称>,miu=<MIU号>,sz=<大小>参数说明: - 名称:堆标识符(如 mma_heap_name0 主堆、mma_heap_fb 帧缓冲堆)- miu:MIU 接口号(通常为0,表示 MIU0) - sz:堆大小(十六进制,如 0x22000000 约 544MB)示例: mma_heap=mma_heap_name0,miu=0,sz=0x22000000 |
CONFIG_MMA_MEM_SIZECONFIG_FB_MEM_SIZE |
修改 defconfig 中的对应配置项 miu 和名称由系统自动指定 |
mma_memblock_remove= |
MMA 从系统 memblock 中移除已分配的内存 防止 Linux 内核将 MMA 预留的内存分配给其他模块 格式: mma_memblock_remove=<0|1>参数说明: 0=不移除,1=移除(默认启用) |
自动生成 | 不需要手动修改 |
mmap_reserved= |
预留内存映射区域(用于 LOGO 等固定位置预留内存) 格式: mmap_reserved=<名称>,miu=<MIU号>,sz=<大小>,max_start_off=<起始偏移>,max_end_off=<结束偏移>参数说明: - 名称:预留区域标识(如 fb)- miu:MIU 接口号(通常为0) - sz:预留大小(十六进制) - max_start_off:相对于 DRAM 基地址的最大起始偏移(十六进制) - max_end_off:相对于 DRAM 基地址的最大结束偏移(十六进制) 偏移计算: 仅 LOGO( CONFIG_LOGO_MEM_SIZE)的偏移由 build_pre_process_config.sh 自动计算,从 lx_size 往下分配;其他区域需手动指定偏移示例: mmap_reserved=fb,miu=0,sz=0x800000,max_start_off=0x3f500000,max_end_off=0x3fd00000 |
CONFIG_LOGO_MEM_SIZE 等 |
修改 defconfig 中对应配置 LOGO 偏移自动计算,其他需手动指定 |
bootargs中格式统一约定:
- 地址格式:十六进制,以
0x前缀开头(如0x80000000)- 大小格式:
cma=:十进制+M单位(由脚本从十六进制自动转换,如2M)mma_heap=的sz:十六进制(如0x22000000)mmap_reserved=的sz:十六进制(如0x800000)- MIU 号:数字标识,通常为 0(表示 MIU0)
1.2.2 内存布局示例¶
根据上述 bootargs,内存布局如下(从高地址到低地址):
┌─────────────────────────────────────┐
│ mmap_reserved FB (8MB) │ ← 0x80000000 (高地址)
├─────────────────────────────────────┤
│ MMA Heap (544MB) │
├─────────────────────────────────────┤
│ MMA Heap FB (64MB) │
├─────────────────────────────────────┤
│ CMA (2MB) │
├─────────────────────────────────────┤
│ Linux System Memory (~1.36GB) │ ← 0x0 (低地址)
│ kernel + user space │
└─────────────────────────────────────┘
1.2.3 LX_MEM 与 DRAM 的大小关系¶
在 defconfig 配置中,pure Linux defconfig 默认CONFIG_LX_MEM_SIZE=CONFIG_DRAM_SIZE
但有些defconfig中CONFIG_LX_MEM_SIZE 可能小于 CONFIG_DRAM_SIZE,比如需要开OPTEE的defconfig,会预留部分区间用于 ARM TrustZone 安全固件,对Linux是不可见的。
1.2.4 修改 bootargs 的方式¶
修改 defconfig
通过修改项目配置文件中的相关配置项:
CONFIG_LX_MEM_SIZE="0x80000000"
CONFIG_CMA_MEM_SIZE="0x200000"
CONFIG_MMA_MEM_SIZE="0x22000000"
CONFIG_FB_MEM_SIZE="0x4048000"
U-Boot 环境变量