Linux 内存管理单元 MMU(上)
前言:Linux系统中的一个重要概念 —— 内存管理单元,也叫MMU。今天我们来通俗易懂的解释一下这MMU的工作机制。
目录
一、虚拟内存 与 MMU
在介绍MMU之前,我们先来理解另一个基础概念 —— 虚拟内存(地址)。
虚拟地址:在 Linux 中,每个进程拿到的都是“虚拟地址空间”(比如 0–4GB(32位),64 位更大)。
物理地址:内存条上真实的地址叫做“物理地址”。
为什么需要虚拟地址?
现代计算机系统中,应用程序对内存的需求往往远超物理内存的实际容量。如果每个程序都直接独占物理内存,会造成内存资源的极大浪费,而且容易导致多个程序之间发生冲突。
为解决这些问题,现代操作系统引入了虚拟内存技术。虚拟内存允许每个进程拥有一个独立、连续且巨大的地址空间,即使物理内存不足以容纳所有进程的全部数据,也能通过在硬盘和内存之间按需交换数据,从而支持更大的寻址空间。
那什么是MMU呢?
内存管理单元(MMU)是实现虚拟内存机制的关键。它位于CPU与物理内存之间,充当虚拟地址与物理地址之间的桥梁。它负责将程序所使用的虚拟地址(逻辑地址)转换为实际的物理地址。
二、用"借书"类比
在深入讲解MMU地址转换逻辑之前,我们先用形象的生活事件来进行简单类比:
假如你去图书馆借书,
CPU = 你
虚拟地址 = 书编号
物理地址 = 图书馆仓库
MMU +页表 = 借书管理系统(包含书编号与实际所在仓库位置的对应关系等)【页表在下一节介绍】

三、分页机制
MMU的“单位”是页。MMU 不是“一个字节一个字节”地翻译,而是“分页”。分页将虚拟地址空间划分为固定大小的块,称为页,常见的页大小为4KB,将物理内存划分为固定大小的块,称为页框。
每个虚拟页通过页表映射到一个物理页框。页表是一种数据结构,存储了虚拟页与物理页帧之间的映射关系。
每个进程都有自己的页表,由操作系统维护,用于描述该进程虚拟地址空间的布局。页表中除了存储映射关系外,还包含一些控制位,如权限位和存在位。
typedef struct {
unsigned long pfn; // 物理页框号
unsigned int present : 1; // 页表项是否存在
unsigned int rw : 1; // 读/写权限
unsigned int us : 1; // 用户权限
// 其他控制位
} PageTable;
四、地址转换过程
MMU将虚拟地址分为页号和页内偏移两部分。
+-------------+-------------+
| 页号 (p) | 页内偏移 (d) |
+-------------+-------------+
↑ ↑
高位地址 低位地址
当进程访问一个虚拟地址时,MMU会根据虚拟地址页号去页表中查找,得到对应的物理帧号,然后将物理页号与页内偏移组合,形成完整的物理地址,最就能够访问真实的物理地址了。
虚拟地址: (页号p, 偏移d)
↓
[页表查询]
↓
物理地址: (帧号f, 偏移d) ← 偏移保持不变
这里举一个简易的示例:
============================================
; 单级页表虚拟地址转换演示
; 页大小:4KB(12位偏移)
============================================
mov ecx, eax ; 保存原始虚拟地址到 ECX
shr eax, 12 ; 提取虚拟页号(虚拟地址 >> 12)
; 计算页表项地址
mov ebx, page_table_base ; EBX = 页表虚拟地址(假设已设置)
mov edx, [ebx + eax*4] ; EDX = 页表项(PTE)
; 检查页是否存在(P位)
test edx, 0x1 ; 测试Present位(bit 0)
jz .page_not_present ; 如果为0,页不存在
; 提取物理页框号
and edx, 0xFFFFF000 ; 清除低12位标志位,保留物理页框号
; 计算物理地址
and ecx, 0xFFF ; ECX = 页内偏移(原始虚拟地址低12位)
or eax, edx ; EAX = 物理页框号
or eax, ecx ; EAX = 物理页框号 | 偏移 = 完整物理地址
写在最后:本文采用通俗易懂的方式解释了MMU的基本知识,旨在让大家快速理解入门,其中还有很多细节(如多级页表、缺页异常处理、TLB),我们在后续文章中继续介绍。
更多推荐




所有评论(0)