1. 内存管理概述:物理内存与虚拟内存概念、MMU的作用、内核空间与用户空间划分
内存管理是操作系统内核最核心的子系统之一,它直接决定了系统的稳定性、性能与安全性。在嵌入式Linux内核裁剪场景中,理解内存管理的基本概念是进行后续精简与优化的前提。本节将围绕物理内存与虚拟内存的本质、内存管理单元(MMU)的硬件机制以及内核/用户空间的划分展开。
1.1 物理内存与虚拟内存
物理内存(Physical Memory)是硬件实际提供的RAM存储介质,通常以页框(Page Frame)为单位进行管理,大小为4KB(ARM64或x86_64默认)。物理内存的地址空间受限于硬件容量,例如512MB或1GB。
虚拟内存(Virtual Memory)是操作系统为每个进程提供的独立、连续的地址空间抽象。进程看到的地址是虚拟地址(VA),通过MMU硬件转换为物理地址(PA)。虚拟内存使得每个进程可以拥有独立的地址空间,互不干扰,并且允许“超额使用”物理内存(通过交换或页面回收)。
| 特性 | 物理内存 | 虚拟内存 |
|---|---|---|
| 地址空间 | 受限于硬件容量(如512MB) | 受限于CPU位数(32位:4GB,64位:理论16EB) |
| 分配单位 | 页框(Page Frame) | 页(Page) |
| 连续性 | 物理上可能不连续 | 对进程呈现连续线性空间 |
| 隔离性 | 所有进程共享 | 每个进程独立,互不干扰 |
| 管理主体 | 内核页分配器(Buddy System) | 内核VMA + MMU硬件 |
1.2 MMU的作用
内存管理单元(Memory Management Unit, MMU)是CPU内部负责虚拟地址到物理地址转换的硬件模块。MMU的核心功能包括:
- 地址转换:将虚拟地址(VA)通过页表(Page Table)查找转换为物理地址(PA)。
- 权限检查:检查当前访问是否具有读、写、执行权限,防止非法访问。
- 缓存控制:控制页面的缓存属性(Cacheable/Non-cacheable、Write-back/Write-through)。
- TLB加速:通过转换后备缓冲区(TLB)缓存最近使用的页表项,加速地址转换。
1.3 内核空间与用户空间划分
在Linux中,虚拟地址空间被划分为两个主要区域:内核空间(Kernel Space)和用户空间(User Space)。这种划分是系统安全与稳定性的基石。
- 用户空间:运行用户进程(应用程序),权限受限,不能直接访问硬件或内核数据结构。访问内核必须通过系统调用(syscall)接口。
- 内核空间:运行操作系统内核代码(调度器、驱动、文件系统等),拥有最高权限(Ring 0 / EL1),可以直接访问所有物理内存和硬件。
在32位系统中,典型的划分比例为:用户空间3GB(0x00000000 ~ 0xBFFFFFFF),内核空间1GB(0xC0000000 ~ 0xFFFFFFFF)。在64位系统中,划分比例更为灵活,通常用户空间与内核空间各占一半(如48位地址空间下,用户空间0x0000000000000000 ~ 0x00007FFFFFFFFFFF,内核空间0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF)。
| 属性 | 用户空间 | 内核空间 |
|---|---|---|
| 特权级别 | 低(Ring 3 / EL0) | 高(Ring 0 / EL1) |
| 访问硬件 | 不允许 | 允许 |
| 内存访问范围 | 仅限用户空间 | 全部物理内存 + 用户空间(通过copy_from_user等) |
| 崩溃影响 | 仅影响当前进程 | 可能导致整个系统崩溃(Kernel Panic) |
| 典型代码 | 应用程序、C库 | 内核、驱动、文件系统 |
1.4 地址空间布局示例(32位ARM)
以典型的32位ARM Linux为例,虚拟地址空间布局如下:
0xFFFFFFFF ┌─────────────────────────────┐
│ 内核空间 (1GB) │
│ - 内核代码/数据 │
│ - vmalloc区域 │
│ - 固定映射区 │
│ - 高端内存映射区 │
0xC0000000 ├─────────────────────────────┤
│ 用户空间 (3GB) │
│ - 栈 (向下增长) │
│ - 堆 (向上增长) │
│ - 数据段 (.data/.bss) │
│ - 代码段 (.text) │
0x00000000 └─────────────────────────────┘
在嵌入式裁剪中,若物理内存小于1GB,可考虑关闭HIGHMEM支持(CONFIG_HIGHMEM=n),简化内核地址映射,减少TLB压力并降低内核代码量。
cat /proc/meminfo — 查看物理内存总量、空闲、缓存等cat /proc/self/maps — 查看当前进程的虚拟地址空间映射free -h — 查看系统内存使用概况