在云栈社区的技术讨论中,算法同事常问 POOL 到底是什么?本文基于 AX615 平台,系统梳理 Linux 下内存管理相关的核心概念——CMM、POOL、共享内存与 RAMDisk,帮助开发者理清这些术语背后的设计逻辑与内存布局。
一、理解平台内存划分背景
从 project.mak 文件看 DDR 布局:
- 总 DDR:128 MB,地址范围
0x40000000 ~ 0x47FFFFFF
- OS_MEM:前 62 MB,供 Linux 内核、RTOS、模型、ramdisk、gzip 缓冲使用
- CMM 区域:剩余部分,地址范围
0x43B00000 ~ 0x47FFFFFF,专供多媒体、AI、视频编解码、ISP 使用
关键构建参数如下所示:
OS_MEM_SIZE := 62
CMM_START_ADDR = SYS_DRAM_BASE + OS_MEM_SIZE
CMM_SIZE = 总DDR - OS_MEM_SIZE
CMM_POOL_PARAM := anonymous,0,$(CMM_START_ADDR),$(CMM_SIZE)M
AXERA 平台的 CMM = Chip Multimedia Memory,是厂商自定义的一大块物理连续内存池,独立于 Linux 的标准内核内存管理,属于预留的大块物理内存。
行业同类概念对照
海思平台的多媒体专用内存叫 MMZ(Media Memory Zone),AXERA 叫 CMM,二者定位、用途高度相似,但属于不同厂商的私有内存分区机制,不能等同:
| 对比项 |
说明 |
| 相同点 |
均在 DDR 启动阶段静态划分、物理连续、脱离 Linux buddy 内存管理、专供 ISP/编码/AI 等硬件 DMA 使用 |
| 差异点 |
驱动接口、内核参数、内存申请与释放 API 完全不兼容。海思使用 mmz_alloc,AX615 使用自研 CMM 驱动接口 |
OS_MEM 内部细分(含 RAMDisk)
OS_MEM 的 62 MB 属于 Linux 标准操作系统内存域,包含几类完全不同的资源,与尾部的 CMM 物理隔离:
- Linux 内核基础内存:内核代码、页表、buddy 系统、slab、进程堆栈、vmalloc/kmalloc 常规内存
- RTOS 运行内存:双核 RTOS 固件、任务栈、RPMSG 通信缓冲
- AI 模型加载内存:轻量模型可放在 OS_MEM,大张量必须放 CMM
- RAMDisk 内存(tmpfs/传统 ramdisk):本文讨论的重点,全部占用 OS_MEM 空间,不会占用 CMM
- 系统缓冲:文件页缓存、gzip 解压缓冲、日志临时缓存、
/tmp、/dev/shm 等 tmpfs 挂载区
关键分区约束:OS_MEM 与 CMM 地址空间完全隔离。扩容 ramdisk 会挤占内核、应用、系统缓存的可用内存,不会占用 CMM 多媒体内存;反之调大 CMM_SIZE,OS_MEM 同步缩小,ramdisk 可用上限随之降低,极易出现 ramdisk 不足或视频缓存申请失败。
二、CMM:AXERA 私有多媒体内存池(对标海思 MMZ)
1. 核心定义
CMM 是启动阶段在 DDR 尾部静态切割、物理地址连续、Linux 内核不可随意回收的大片预留内存,专门服务于:
- ISP 图像采集、YUV 帧缓存
- H264/H265/JPEG 编解码帧缓存
- AI 模型推理的输入输出张量
- RTOS-Linux 跨核图像共享缓冲区
2. 关键特性
- 物理连续:视频/AI 硬件 DMA 只能操作连续物理内存,普通 kmalloc/vmalloc、ramdisk、
/dev/shm 均不满足
- 独立于 Linux buddy 系统:不在常规内存管理池中,内核 OOM、页面回收、ramdisk 内存回收逻辑完全不会触碰 CMM
- 静态分区:大小由
OS_MEM_SIZE 决定,编译时固定,运行时不可动态扩容或缩容
- 统一 POOL 管理:CMM 整块内存内部再切分为多个子内存池(POOL)
- 内存回收规则:CMM Buffer 释放后仅归还 CMM 内部 POOL,不会返还给 Linux OS_MEM,也不会供给 ramdisk 使用
3. 与工程的关联
cmmpool=anonymous,0,0x43B00000,66M 直接嵌入内核 bootargs,内核启动后注册 CMM 物理内存池驱动,应用层通过 CMM 接口申请/释放帧缓存。
三、POOL:通用内存池,CMM 内部的细分单元
1. 基础概念
POOL 即内存池,是同规格内存块的缓存容器,可分为三种场景:
- Linux 标准 slab pool:内核
kmem_cache,管理固定大小的结构体(task_struct、file 等),占用 OS_MEM
- RAMDisk(tmpfs)隐式内存池:tmpfs 动态从 OS_MEM 的页缓存分配内存,文件删除后页框归还给 OS_MEM 全局内存池
- AXERA CMM 内部 POOL:把整块 CMM 大内存拆成多个独立的业务池,例如:
ISP_YUV_POOL:2M 帧缓存池
ENC_FRAME_POOL:4M 编码缓存池
AI_TENSOR_POOL:模型张量缓存池
2. CMM POOL 工作逻辑
- 整块 CMM 是一片独立大物理内存,与 OS_MEM、ramdisk 物理隔离
- 驱动初始化时按业务切割出多个 POOL,每个 POOL 包含 N 块等大 buffer
- 应用申请帧缓存时从对应 POOL 取空闲块;释放时归还 POOL,避免频繁的物理内存分配释放(DMA 分配极慢)
- POOL 块一旦分配,物理地址固定,可直接交给硬件 DMA 使用
- CMM POOL 的空闲内存永远留在 CMM 区域,无法挪给 ramdisk 或普通进程使用
3. 层级关系
总DDR
├── OS_MEM(Linux 常规内存,含 ramdisk)
└── CMM 整块多媒体内存(对标海思 MMZ)
└── CMM 内部划分多个业务 POOL
四、RAMDisk:OS_MEM 专属,与 CMM 完全隔离
1. RAMDisk 两种实现及内存归还机制
RAMDisk 全部占用 OS_MEM 内存,不占用 CMM,硬件 DMA 也无法直接使用 ramdisk 内存。
| 类型 |
内存归还机制 |
| tmpfs |
文件删除或卸载后,内存自动归还 OS_MEM |
| ramfs/传统 ramdisk |
文件删除后内存不释放,长期运行风险高 |
2. RAMDisk 优缺点
优点
- IO 速度远超 Flash,适合编译临时文件、日志缓冲、临时配置
- 断电数据自动清空,适合临时敏感数据
- tmpfs 动态占用,闲置内存可自动归还系统
缺点
- 占用 OS_MEM,调大 ramdisk 会挤压内核、应用、RTOS 可用内存;严重时虽然 CMM 空间充足,但 OS_MEM 不足会导致系统崩溃
- 数据易失,不能存储业务持久化的录像、图片
- 内存无法共享给 ISP/编码硬件,无法保证物理连续,不能替代 CMM Buffer
- ramfs/传统 ramdisk 存在内存不释放问题,长期运行内存持续升高
五、共享内存:三类机制,极易混淆
分类 1:标准 Linux 用户态共享内存(POSIX shm / System V shm,底层基于 tmpfs ramdisk)
- System V
shmget/shmat:进程间内存共享,虚拟地址不保证物理连续
- POSIX
/dev/shm:基于 tmpfs 的 ramdisk 分区,占用 OS_MEM,适合多进程传递小数据、配置
- 短板:物理不连续,不能直接给视频 DMA 硬件使用;在 AX 多媒体大图流转中完全不用
分类 2:CMM 跨进程/跨核共享内存(平台业务主流,对标海思 MMZ 共享 Buffer)
即 CMM POOL 分配出的 buffer,自带物理地址 + fd 句柄,完全不占用 ramdisk/OS_MEM 普通内存:
- Linux 多进程:通过 fd 传递 buffer,映射到各自的虚拟地址,底层指向同一块 CMM 物理内存
- Linux ↔ RTOS 双核共享:CMM 物理地址直接写入 RPMSG 消息,两边核直接访问同一片物理帧缓存
- 优势:天然物理连续,适配 ISP/编码/AI 硬件 DMA,是 IPC 摄像机图像流转的核心
分类 3:内核态共享内存(vmalloc、dma_buf,分两类内存来源)
dma_buf 封装 CMM Buffer:底层内存来自 CMM 区域,多媒体专用
- 普通
dma_buf / vmalloc:内存取自 OS_MEM,可分配给 ramdisk、普通驱动,物理不连续,不支持多路视频 DMA
六、四者核心差异对比
| 维度 |
CMM(对标海思 MMZ) |
POOL |
RAMDisk(tmpfs) |
共享内存(分三类) |
| 内存归属 |
DDR 尾部独立分区,不属于 OS_MEM |
CMM 内部管理单元 |
OS_MEM Linux 标准内存域 |
shm:OS_MEM ramdisk;CMM 共享 Buffer:CMM 区域 |
| 本质 |
静态预留、大片连续物理内存区域(厂商私有) |
内存管理容器,CMM/内核 slab/tmpfs 都有 pool |
内存文件系统,模拟磁盘,存临时文件 |
进程/核之间共用同一块内存的机制 |
| 作用 |
提供大块连续物理内存给多媒体 DMA 硬件 |
复用同规格 buffer,减少 DMA 分配开销 |
高速临时文件存储,替代 Flash |
数据跨进程、跨核传递 |
| 物理连续性 |
整块完全连续 |
CMM 池内 buffer 连续 |
物理碎片化,不连续 |
shm 不连续;CMM 共享 Buffer 连续 |
| 内存回收规则 |
Buffer 释放仅归还 CMM 池,不会返还 OS_MEM/ramdisk |
释放归还所属内存池 |
文件删除或卸载后内存归还 OS_MEM 全局内存 |
引用计数清零释放,视底层内存来源而定 |
| 生命周期 |
内核启动固定分配,关机释放 |
驱动初始化创建,系统销毁释放 |
挂载生效,umount 或重启清空 |
随进程或引用计数释放 |
| 典型使用场景 |
ISP、编码、AI 推理大缓存 |
多路 IPC 循环复用 YUV 帧 |
临时日志、编译缓存、/dev/shm 小参数 |
多进程图像流转、Linux-RTOS 互通;小配置进程通信 |
七、常见踩坑点
- 混淆 CMM 与 Linux 标准内存/ramdisk:不能用 vmalloc/kmalloc、
/dev/shm、ramdisk 替代 CMM 做视频 DMA,物理不连续会导致硬件报错;海思 MMZ 同理,不可用系统 shm 传递大图
- OS_MEM 和 CMM 此消彼长:单纯加大 ramdisk 而不调整总 DDR,会挤占内核和应用内存,出现视频业务 CMM 充足但系统 OOM 的奇怪现象
- POOL 数量不足 ≠ CMM 不够:CMM 空间仍充裕,但 POOL 预分配 buffer 太少,依然会申请失败,需调整驱动 POOL 块数;ramdisk 不存在 POOL 块数限制,仅受 size 上限约束
- 共享内存误区:
/dev/shm(tmpfs ramdisk)只能传小参数,大图必须用 CMM dma_buf 共享
- 内存回收混淆:ramdisk tmpfs 闲置内存自动还给系统;CMM 空闲 Buffer 仅留在私有内存区,无法供给 ramdisk;ramfs 删除文件内存不释放
- 分区修改连锁问题:调大
CMM_SIZE,OS_MEM 同步缩小,ramdisk 最大可用容量随之下降,容易出现 ramdisk 空间不足
八、极简总结
- CMM:AXERA 平台 DDR 尾部静态预留、专供多媒体的大块连续物理内存,对标海思 MMZ,独立于 Linux OS_MEM、ramdisk
- POOL:内存管理容器,分内核 slab、CMM 业务池、tmpfs 内存管理池;CMM POOL 用于循环复用 YUV/AI 帧缓存,提升 DMA 分配效率
- RAMDisk:运行在 OS_MEM 内的内存文件系统,tmpfs 可自动归还内存,ramfs/传统 ramdisk 内存不回收,仅做临时文件存储,不能给硬件 DMA 使用
- 共享内存:一种内存共用机制;业务大图流转靠 CMM buffer 实现共享,普通进程小数据用系统 shm(底层 ramdisk)
整体层级关系:
总DDR
├── OS_MEM(内核/应用/ramdisk)
└── CMM
└── 拆分为多个 POOL
└── POOL 分配的 buffer 支持跨进程/跨核硬件级共享
|