概述
- MMU 即内存管理单元,是用硬件电路逻辑实现的一个地址转换器件,它负责接受虚拟地址和地址关系转换表,以及输出物理地址
线性地址
-
由于保护模式的内存模型是分段模型,它并不适合于 MMU 的分页模型,所以我们要使用保护模式的平坦模式,这样就绕过了分段模型
-
这个平坦模型和长模式下忽略段基址和段长度是异曲同工的
-
程序代码中的虚拟地址,经过 CPU 的分段机制产生了线性地址,平坦模式和长模式下线性地址和虚拟地址是相等的
- 线性地址(Linear Address) 是逻辑地址到物理地址变换之间的中间层
-
如果不开启 MMU,在保护模式下可以关闭 MMU,这个线性地址就是物理地址
-
因为长模式下的分段弱化了地址空间的隔离,所以开启 MMU 是必须要做的, 开启 MMU 才能访问内存地址空间
MMU页表
概述
- 它描述了虚拟地址到物理地址的转换关系,也可以说是虚拟页到物理页的映射关系,所以称为
页表
构成
-
为了增加灵活性和节约物理内存空间(因为页表是放在内存空间中),所以页表并不存放虚拟地址和物理地址的对应关系,只存物理页面的地址
-
MMU以虚拟地址为索引去查表返回物理页面地址,而且页表是分级的,总体分为三个部分
- 顶级页目录
- 多个中级页目录
- 页表
工作流程
- 从上图看出,一个虚拟地址被分为从左到右四个位段
- 第一个位段索引顶级页目录中一个项,该项指向一个中级页目录
- 然后用第二个位段去索引中级页目录中的一个项,该项指向一个页目录
- 再用第三个位段去索引页目录中的项目,该项目指向一个物理页地址
- 最后用第四个位段作该物理页内的偏移去访问物理内存
开启MMU
前提
- 开启 MMU 的前提是 CPU 进入保护模式或者长模式
步骤
第一步
- 使 CPU 进入保护模式或者长模式
第二步
- 准备好页表数据,这包含顶级页目录,中间层页目录,页表,假定我们已经编写了代码,在物理内存中生成了这些数据
第三步
- 把顶级页目录的物理内存地址赋值给 CR3 寄存器
mov eax, PAGE_TLB_BADR ;页表物理地址
mov cr3, eax
第四步
- 设置 CPU 的 CR0 的 PE 位为 1,这样就开启了 MMU
;开启 保护模式和分页模式
mov eax, cr0
bts eax, 0 ;CR0.PE =1
bts eax, 31 ;CR0.P = 1
mov cr0, eax
MMU 地址转换失败
失败原因
- 例如,页表项中的数据为空,用户程序访问了超级管理者的页面,向只读页面中写入数据
失败处理
- MMU 停止转换地址
- MMU 把转换失败的虚拟地址写入 CPU 的 CR2 寄存器
- MMU 触发 CPU 的 14 号中断,使 CPU 停止执行当前指令
- CPU 开始执行 14 号中断的处理代码,代码会检查原因,处理好页表数据返回
- CPU 中断返回继续执行 MMU 地址转换失败时的指令