文章目录
- 内存分页的原因
- 一级页表
- 分页机制的原理
- 一级页表
- 二级页表
- 二级页表概述
- 地址转换
- 启动分页机制
内存分页的原因
在还未出现内存分页机制之前,我们都内存分段机制下工作。
但是,这样会有个问题。来看个下方的例子。
进程在分段机制下运行
下图(左):系统里有 3 个进程正在运行,进程 A、B、C 各占了 10MB、20MB、30MB 的内存空间,还剩下 15MB 可用。
这时,此时进程 B 已经运行结束,空出了 20MB 的内存,可是待加载运行的进程 D 需要 20MB+3KB 的内存空间。显然,此时内存空间加载不了进程 D 。
这时,很容易就可以想到 2 个办法
- 等待其他进程结束,直到空出内存空间够大,再加载新进程。
- 将某个进程从内存中换到外存(硬盘)上。
分析:
第一种方法的等待是未知的,所以 pass 掉。
第二种方法中如果待换出的进程内存比较大,容易导致速度过慢,等待过久的问题。也 pass 掉。
这个问题如果能通过某种方式,【让线性地址连续,而物理地址可以不连续】不就可以很好的解决~
因此,提出了内存分页机制。
【补充】内存段从外存(硬盘)换到内存的过程。
在开始之前,先有个“操作系统是软件,软件中的指令靠 CPU 来执行”的印象。首先,在保护模式下,CPU 想要引用一个段时,需要先查看段描述符(描述符存在于描述符表中)。这时,我们要判断该段是否在内存中。如果该描述符中的 P 位为 1,表示该段在内存中存在。访问过该段后,CPU 将段描述符中的 A 位置 1,表示近来刚访问过该段。否则,如果 P 位为 0,说明内存中并不存在该段,这时候 CPU 将会抛出个 NP(段不存在)异常,转而去执行中断描述符表中 NP 异常对应的中断处理程序,此中断处理程序是操作系统负责提供的,该程序的工作是将相应的段从外存(比如硬盘)中载入到内存,并将段描述符的 P 位置 1,中断处理函数结束后返回。
一级页表
食用本小节之前,可以先浏览实模式和保护模式的区别中物理地址,逻辑地址,有效地址,线性地址,虚拟地址的概念。
算了,再来重新回顾一下上面基本的概念。
- 保护模式
段寄存器中的内容已经是选择子,选择子再找到段基址。但是内存访问的核心机制依然是“段基址:段内偏移地址”。“段基址:段内偏移地址”称为线性地址。没有开启地址分页的情况下,此线性地址可作物理地址直接访问内存。若开启了分页功能,此线性地址就称为是虚拟地址(逻辑上连续),虚拟地址需要到页表中查找到物理地址再进行访存。
分页机制的原理
分页机制的思想:通过映射,可以使连续的线性地址与任意物理内存地址相关联,逻辑上连续的线性地址其对应的物理地址可以不连续。
分页机制的作用:
- 将线性地址转换成物理地址。
- 将大小不同的大内存段拆分成大小相等的小内存块
具体来看下面这张进程的地址转换过程
图示
图示说明:
分页机制是建立在分段机制上,即使在分页机制下的进程也需要先经过逻辑上的分段。
- 分配内存段:当加载一个进程,操作系统按照进程中各段的起始范围,在进程自己的 4GB 虚拟地址空间中寻找可用空间分配内存段。
- 分页机制:在分页机制下,这些分配的段(例如:图示的代码段和数据段)在逻辑上被拆分成以页为单位的小内存块。
- 映射:接着操作系统为这些虚拟内存块(页)分配真实的物理内存页,OS查找物理内存中可用的页,然后在页表中登记这些物理页地址,这样就完成了虚拟页到物理页的映射。
从此,每个进程都认为自己独享 4GB 地址空间。
一级页表
页表与物理内存关系示图如下所示
上图中,页表大小计算可得: 4Byte*4G =16GB。
解释:表中存有 4G 个页表项,同时,32 位的地址要用 4 字节的页表项来存储。
由于页表存放在内存中,16G 显然过大。
换种思路
(个人理解)减小划分出的页数量,同时就可以减少页表项的大小
首先,32 位地址表示 4GB 空间,可以将 32 位地址分成高低两部分,低地址部分是内存块大小,高地址部分是内存块数量。
内存块数
∗
内存块大小
=
4
G
B
内存块数*内存块大小=4GB
内存块数∗内存块大小=4GB
CPU 中采用的页大小 (内存块大小) 定为 4KB(2的12次方)【注】:页是地址空间的计量单位,只要是 4KB 的地址空间都可以称为一页。
那么,4GB 地址空间被划分成 4GB/4KB=1M 个页,即4GB 空间中可以容纳 1048576 个页,页表中自然也要有 1048576 个页表项,这就是一级页表。
页表及页表项对应关系如下
经以上的分析,虚拟地址的高 20 位可用来定位一个物理页,低 12 位可用来在该物理页内寻址。
【解释】我们用高 20 位,索引一个页(索引范围 0~0xfffff),表示第几个页。低 12 位作为页内寻址。
重点:如何将线性地址转换成物理地址???
一个页表项对应一个页,所以,用线性地址的高 20 位作为页表项的索引,每个页表项要占用 4 字节
大小,所以这高 20 位的索引乘以 4 后才是该页表项相对于页表物理地址的字节偏移量。用 cr3 寄存器中的页表物理地址加上此偏移量便是该页表项的物理地址,从该页表项中得到映射的物理页地址,然后用线性地址的低 12 位与该物理页地址相加,所得的地址之和便是最终要访问的物理地址。
二级页表
二级页表概述
二级页表的由来
- 一级页表中最多可容纳 1M(1048576)个页表项,每个页表项是 4 字节,如果页表项全满的话,
便是 4MB 大小。 - 一级页表中所有页表项必须要提前建好。
- 每个进程都有自己的页表。
二级页表的构造
- 无论是几级页表,标准页的大小都是 4KB。因此4GB 线性地址空间最多有 1M 个标准页。
- 一级页表是将这 1M 个标准页放置到一张页表中。
- 二级页表是将这 1M 个标准页平均放置 1K 个页表中。每个页表中包含有 1K 个页表项,每个页表大小为4KB。为了更好的管理每个页表,将每个页表的物理地址存放在页目录表中都以页目录项(Page Directory Entry, PDE)的形式存储,页目录项大小同页表项一样都为 4KB ,PDE用来描述一个物理页的物理地址。
- 页目录表和所有页表都放在物理内存中。
【补充】页目录项和页表项
页目录项和页表项的都是 4 字节大小,用来存储物理页地址。具体结构如下所示
地址转换
利用二级页表将线性地址转换成物理地址过程
- 二级页表的地址转换原理
二级页表地址转换原理是将 32 位虚拟地址拆分成高 10 位、中间 10 位、低 12 位三部分,它们的作用是:高 10 位作为页表的索引,用于在页目录表中定位一个页目录项 PDE,页目录项中有页表物理地址,也就是定位到了某个页表。中间 10 位作为物理页的索引,用于在页表内定位到某个页表项PTE,页表项中有分配的物理页地址,也就是定位到了某个物理页。低 12 位作为页内偏移量用于在已经定位到的物理页内寻址。
启动分页机制
启动分页机制的3个步骤
- (1)准备好页目录表及页表。
- (2)将页表地址写入控制寄存器 cr3。
- (3)寄存器 cr0 的 PG 位置 1。
参考资料
- 《操作系统真象还原》