本文约3200字,今天培训会上有做算法的同事问POOL是什么?不做Linux应用的,可能确实不知道,本文来系统梳理下Linux下关于内存的一些名词术语,也更深入理解这些不同内存叫法的含义与用法。
关注公众号, 即可获得与Linux相关的电子书籍(含《操作系统教程(Linux 版)》)以及常用开发工具,文末有文档清单。
一、先搞懂平台背景
从 project.mak 文件看 DDR 布局:
- 总 DDR:128MB,地址范围
0x40000000 ~ 0x47FFFFFF - OS_MEM:前 62MB,供 Linux 内核 / RTOS / 模型 / ramdisk / gzip 缓冲使用
- CMM 区域:剩余所有 DDR,地址范围
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 62MB 是 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 内核不可随意回收的大片预留内存,专门给:
2. 关键特性
- 物理连续:视频/AI 硬件 DMA 只能跑连续物理内存,普通 kmalloc/vmalloc、ramdisk、
/dev/shm 均不满足 - 独立于 Linux buddy 系统:不在 Linux 常规 mem 管理池,内核 OOM、页面回收、ramdisk 内存回收逻辑完全不会触碰 CMM
- 静态分区:大小由
OS_MEM_SIZE 决定,编译 mak 固定,运行时不能动态扩容/缩容 - 统一 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 大内存拆多个独立池,比如:
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/MMZ 完全隔离)
1. RAMDisk 两种实现及内存归还机制
RAMDisk 全部占用 OS_MEM 内存,不占用 CMM,硬件 DMA 无法使用 ramdisk 内存。
2. RAMDisk 优缺点
优点
- IO 速度远超 Flash,适合编译临时文件、日志缓冲、临时配置
缺点
- 占用 OS_MEM,调大 ramdisk 会挤压内核、应用、RTOS 可用内存,严重时 CMM 虽然空间充足,但 OS_MEM 不足导致系统崩溃
- 内存无法共享给 ISP/编码硬件,无连续物理地址,不能替代 CMM Buffer
- ramfs/传统 ramdisk 存在内存不释放问题,长期运行内存持续上涨
五、共享内存(3 大类,极易混淆,区分是否占用 CMM/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
六、一张表分清四者核心差异
| | | | |
|---|
| 内存归属 | | | | shm:OS_MEM ramdisk;CMM 共享 Buffer:CMM 区域 |
| 本质 | | 内存管理容器,CMM/内核 slab/tmpfs 都有 pool | | |
| 作用 | | | | |
| 物理连续性 | | | | |
| 内存回收规则 | Buffer 释放仅归还 CMM 池,不会返还 OS_MEM/ramdisk | | | |
| 生命周期 | | | | |
| 典型使用场景 | | | | 多进程图像流转、Linux-RTOS 互通;小配置进程通信 |
七、常见踩坑点(融合 CMM、RAMDisk)
- 混淆 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 支持跨进程/跨核硬件级共享
往期文章(欢迎订阅技术分享栏目全部文章):
这里是女程序员的笔记本
15年+嵌入式软件工程师兼二胎宝妈
分享读书心得、工作经验,自我成长和生活方式。
希望我的文字能对你有所帮助