嵌入式内存优化与CMA连续分配低内存适配实战工程 - 第2节
2. Linux内核内存管理基础
在嵌入式 Linux 系统中,每个进程都拥有独立的 虚拟地址空间(Virtual Address Space),而实际的存储介质是有限的 物理内存(Physical Memory)。虚拟内存机制让进程误以为自己独占整个内存空间,从而简化编程模型,同时通过页表实现地址转换与隔离。
2.1.1 核心概念对比
| 概念 | 定义 | 嵌入式关键点 |
|---|---|---|
| 虚拟内存 | CPU 发出的地址,经过 MMU 转换后访问物理内存 | 每个进程 32 位下 4GB 空间(3GB 用户 + 1GB 内核) |
| 物理内存 | DRAM/SRAM 芯片上的实际存储单元 | 嵌入式通常 64MB~2GB,需高效利用 |
| 页表 | 虚拟页号 → 物理页框号的映射表 | ARMv7 使用二级页表,ARMv8 使用多级页表 |
| MMU | 内存管理单元,硬件执行地址转换 | 可关闭(实模式)或开启(保护模式) |
嵌入式实战提示: 在低内存设备(如 256MB RAM)上,虚拟内存的页表本身会占用物理内存。每页 4KB 时,4GB 虚拟空间需要约 4MB 页表空间。使用 大页(HugeTLB) 或 LPAE 可减少页表开销。
2.1.2 地址转换流程 SVG
2.2 页表结构与多级映射
页表是虚拟内存的核心数据结构。ARM 架构下,嵌入式 Linux 通常使用 二级页表(Section/Page 映射)或 三级页表(LPAE 扩展)。页表项(PTE)包含物理页框号、权限位、脏位、访问位等控制信息。
2.2.1 ARMv7 二级页表结构
| 级别 | 名称 | 粒度 | 覆盖范围 | 页表项数 |
|---|---|---|---|---|
| L1 | 页全局目录 (PGD) | 1MB (Section) | 4GB | 4096 |
| L2 | 页表 (PTE) | 4KB (Page) | 1MB | 256 |
关键指标: 嵌入式设备中,内核通常只映射低端物理内存(如 512MB),高端内存通过 vmalloc 或 kmap 临时映射。这减少了页表占用,但也带来了连续物理内存分配的限制——这正是 CMA 要解决的问题。
2.2.2 多级页表查找流程 SVG
2.3 MMU 工作原理与 TLB
MMU(Memory Management Unit)是 CPU 内部的硬件模块,负责将虚拟地址转换为物理地址。每次内存访问都经过 MMU,因此其效率直接影响系统性能。TLB(Translation Lookaside Buffer)是 MMU 内部的页表缓存,用于加速地址转换。
2.3.1 MMU 核心功能
- 地址转换: 虚拟地址 → 物理地址,支持段页式映射
- 权限检查: 读/写/执行权限,内核态/用户态隔离
- 缓存控制: 页表项中的 C/B 位控制是否缓存、写策略(write-back/write-through)
- 异常处理: 缺页异常(Page Fault)触发内核分配物理页
2.3.2 TLB 未命中处理流程 SVG
嵌入式陷阱: 在低内存设备上,频繁的 TLB 未命中会导致严重的性能下降。建议:① 使用 Section 映射(1MB 粒度)减少页表项;② 开启 TLB 预取(如 ARM 的 TLB maintenance 广播);③ 避免过多的 vmalloc 映射碎片。
2.4 内核内存布局与低内存适配
嵌入式 Linux 内核将虚拟地址空间划分为 用户空间 和 内核空间。在 32 位系统中,典型的划分是 3GB/1GB 或 2GB/2GB。内核空间进一步分为 直接映射区(低端内存)、vmalloc 区、固定映射区 和 高端内存映射区。
2.4.1 内核空间布局(以 ARM 为例)
| 区域 | 虚拟地址范围 | 用途 | 物理连续性 |
|---|---|---|---|
| 直接映射区 | 0xC000_0000 ~ 0xF000_0000 | 线性映射物理内存(低端内存) | 连续 |
| vmalloc 区 | 0xF000_0000 ~ 0xFE00_0000 | 非连续内存分配(模块、I/O 映射) | 非连续 |
| 固定映射区 | 0xFE00_0000 ~ 0xFF00_0000 | 固定虚拟地址映射(如中断向量) | 按需 |
| 高端内存映射区 | 0xFF00_0000 ~ 0xFFFF_FFFF | 临时映射高端物理内存 | 非连续 |
2.4.2 低内存设备的内存压力 SVG
CMA 的切入点: 从上图可见,物理内存碎片化导致大块连续分配失败。CMA(Contiguous Memory Allocator)在系统启动时预留一块物理连续区域,平时允许可移动页面使用,当驱动需要连续内存时,通过页面迁移腾出空间。这既保证了内存利用率,又满足了连续分配需求。
2.5 本章小结
- 虚拟内存 为每个进程提供独立地址空间,通过 MMU 和 页表 实现地址转换
- 页表 采用多级结构(ARMv7 二级,ARMv8 三级),嵌入式设备可通过 Section 映射减少开销
- TLB 是 MMU 内部的页表缓存,未命中时触发硬件页表遍历或缺页异常
- 内核空间 分为直接映射区、vmalloc 区等,低端内存连续映射,高端内存需临时映射
- 低内存设备 面临物理内存碎片化问题,CMA 通过预留 + 页面迁移机制提供连续分配能力