2. 基础 - MMU 工作原理

103 阅读5分钟

一、前MMU时代:物理寻址的原始世界(1940s-1970s)

1. 早期计算机架构

直接物理寻址:CPU发出的地址信号直接连接到内存总线

+---------------------+
| CPU                 |
|  指令寄存器(IR)      |--+
|  程序计数器(PC)      |  | 物理地址直通
+---------------------+  |
                         v
+---------------------+  |
| 内存                |  |
| 物理地址0x0000-0xFFFF|<+
+---------------------+

致命缺陷:

  • 无内存保护:一个程序可随意覆盖操作系统内核
  • 无地址空间隔离:程序A可读写程序B的数据
  • 碎片化严重:程序需连续物理内存(加载位置固定)

2. 原始解决方案

基址寄存器(Base Register):程序使用逻辑地址,硬件自动加上基址寄存器值。

IBM System/360 示例
LOAD  R1, BASE_ADDR   ; 加载基址
ADD   R2, R1, OFFSET  ; 计算物理地址

局限性:无法动态扩展,无法处理碎片。

二、MMU的诞生:虚拟内存革命(1960s)

1. 里程碑:Atlas Supercomputer(1962)

  • 首次实现分页式虚拟内存: 发明页表(Page Table)
  • 数据结构; 引入缺页异常(Page Fault)处理机制;
  • 使用磁鼓存储器作为后备存储;

2. 核心技术创新

+---------------------+       +-----------------+
| CPU                 |       | MMU             |
| 逻辑地址(VA) ------>|------>| 页表查询(PTE)   |
+---------------------+       | TLB缓存         |
                              | 物理地址(PA) ---> 内存
                              +-----------------+

分页机制:

  • 内存划分为固定大小页(如4KB);
  • 页表存储虚拟页到物理页帧的映射;

关键技术突破:

  • 硬件加速转换:专用电路处理地址转换;
  • 权限控制:页表项包含RWX权限位;
  • 缺页中断:触发操作系统加载数据;

三、MMU的演进史:架构创新时间线

1. 段页式混合架构(1978:Intel 8086)

// 段寄存器 + 偏移量

uint32_t phys_addr = (segment_reg << 4) + offset; 

16位实模式限制:

  • 20位地址空间(1MB)
  • 无内存保护

2. 保护模式革命(1985:Intel 80386)

选择子(Selector)
   |
   v
全局描述符表(GDT) ---> 段基址
   |
   v
线性地址(LA) ------> 分页单元 ---> 物理地址(PA)

两级转换:

  • 段式转换:逻辑地址→线性地址
  • 页式转换:线性地址→物理地址

关键创新:

  • 4级权限环(Ring 0-3)
  • 硬件任务切换

3. 纯分页时代(1995+:x86 PAE/AMD64)

  • 放弃段式内存:设置CS/DS/ES/SS基址为0,偏移=线性地址。
  • 物理地址扩展(PAE):36位物理地址(64GB支持)。
  • x86-64架构:48位虚拟地址(256TB用户空间)和 4级页表(PML4→PDP→PD→PT)。

四、现代MMU核心技术解析

1. 多级页表工作流程(x86-64为例)

虚拟地址: 63-48  47-39    38-30    29-21    20-12    11-0
          保留位 | PML4索引 | PDP索引 | PD索引 | PT索引 | 页内偏移

TIPS:为什么页内偏移是 bit11 - bit0 12位表示?4k对齐, 4096=0x100 在这里插入图片描述 MMU 硬件内部进行地址转换的简化版逻辑过程如下:

phys_addr_t translate(uint64_t va) {
    pml4e_t *pml4 = get_cr3();             // 获取顶级页表地址
    pml4e_t pml4e = pml4[va.pml4_idx];     // 读取PML4E
    pdpe_t *pdpt = pml4e.pdp_base;         // PDPT基址
    pdpe_t pdpe = pdpt[va.pdp_idx];        // 读取PDPE
    pde_t *pdt = pdpe.pd_base;             // PDT基址
    pde_t pde = pdt[va.pd_idx];            // 读取PDE
    pte_t *pt = pde.pt_base;               // PT基址
    pte_t pte = pt[va.pt_idx];             // 读取PTE
    return (pte.pfn << 12) | va.offset;    // 组合物理地址
}

2. TLB(转换后备缓冲器)

工作原理

+-------------------+     +---------------------+
| CPU执行内存访问     |     | 硬件MMU              |
| 1. 检查TLB         |--->| 2. TLB命中: 完成访问  |
| 3. TLB未命中       |     | 4. 自动页表遍历       |
|                   |     | 5. 转换失败触发#PF    |
+-------------------+     +---------------------+
                                |
                                v
+-------------------+     +---------------------+
| 内核#PF处理程序    |<----| 6. 传递错误地址(CR2)  |
| 7. 调用handle_mm_fault() |                     |
| 8. 软件模拟遍历修复页表  |                     |
+-------------------+     +---------------------+

关键技术:

  • 全关联/组关联缓存:存储近期转换结果
  • ASID(地址空间ID):区分进程上下文
  • PCID(进程上下文ID):避免切换时TLB刷新

高级特性

  • 大页支持(2MB/1GB):减少TLB Miss(1个TLB项覆盖更大范围)
  • 内存保护密钥(Intel MPK):为内存页附加4-bit密钥,硬件强制隔离
  • IOMMU(设备虚拟化):为DMA设备提供地址转换
+----------+      +-------+
| 设备DMA  |----->| IOMMU |---> 物理内存
| 虚拟地址 |      +-------+
+----------+

五、现代MMU架构对比

在这里插入图片描述

六、MMU与操作系统的协作

1. 关键内核操作

// 页表更新示例(Linux内核)

void update_mapping(unsigned long va, phys_addr_t pa) {
    pte_t *pte = lookup_pte(va);  // 查找PTE项
    set_pte(pte, mk_pte(pa, PAGE_KERNEL)); // 设置物理地址+权限
    flush_tlb_kernel_range(va, va+PAGE_SIZE); // 刷新TLB
}

2. 缺页异常处理流程

               +---------------+
               | CPU触发#PF异常 |
               +---------------+
                       |
                       v
               +---------------+
               | 保存寄存器现场 |
               +---------------+
                       |
                       v
               +---------------+
               | 调用do_page_fault() |
               +---------------+
                       |
           +-----------+-----------+
           |                        |
用户态缺页(v)                   内核态缺页(x)
           |                        |
+-------------------+     +---------------------+
| 检查VMA权限       |     | 检查内核地址合法性  |
| 分配物理页        |     | 若是vmalloc区域     |
| 建立映射          |     | 同步内核页表        |
| 返回用户空间      |     | 否则触发Kernel Oops |
+-------------------+     +---------------------+

3. MMU 和 软件处理边界

在这里插入图片描述

  1. 完整处理流程 在这里插入图片描述

七、未来演进方向

  • CXL内存池化:MMU需支持跨设备一致性内存访问
  • 异构内存管理:统一管理DRAM、PMEM、GPU显存
  • 安全增强:内存加密(Intel SGX, AMD SEV)、物理不可克隆功能(PUF)集成
  • AI加速:专用硬件预测页表访问模式