分页模型概述分页单元负责将线性地址转换成物理地址(请参见图 1)。线性地址会被分组成页的形式。这些线性地址实际上都是连续的 —— 分页单元将这些连续的内存映射成对应的连续物理地址范围(称为 页框)。注意,分页单元会直观地将 RAM 划分成固定大小的页框。
正因如此,分页具有以下优点:
- 为一个页定义的访问权限中保存了构成该页的整组线性地址的权限
- 页的大小等于页框的大小
将这些页映射成页框的数据结构称为页表 (page table)。页表存储在主存储器中,可由内核在启用分页单元之前对其进行恰当的初始化。图 5 展示了页表。
图 5. 页表将页转换成页框注意,上图 Page1 中包含的地址集正好与 Page Frame1 中包含的地址集匹配。
在 Linux 中,分页单元的使用多于分段单元。前面介绍 Linux 分段模型时已提到,每个分段描述符都使用相同的地址集进行线性寻址,从而尽可能降低使用分段单元将逻辑地址转换成线性地址的需要。通过更多地使用分页单元而非分段单元,Linux 可以极大地促进内存管理及其在不同硬件平台之间的可移植性。
分页过程中使用的字段下面让我们来介绍一下用于在 x86 架构中指定分页的字段,这些字段有助于在 Linux 中实现分页功能。分页单元进入作为分段单元输出结果的线性字段,然后进一步将其划分成以下 3 个字段:
- Directory 以 10 MSB 表示(Most Significant Bit,也就是二进制数字中值最大的位的位置 —— MSB 有时称为最左位)。
- Table 以中间的 10 位表示。
- Offset 以 12 LSB 表示。(Least Significant Bit,也就是二进制整数中给定单元值的位的位置,即确定这个数字是奇数还是偶数。LSB 有时称为最右位。这与数字权重最轻的数字类似,它是最右边位置处的数字。)
线性地址到对应物理位置的转换的过程包含两个步骤。第一步使用了一个称为页目录 (Page Directory) 的转换表(从页目录转换成页表),第二步使用了一个称为页表 (Page Table) 的转换表(即页表加偏移量再加页框)。图 6 展示了此过程。
图 6. 分页字段开始时,首先将页目录的物理地址加载到 cr3 寄存器中。线性地址中的 Directory 字段确定页目录中指向恰当的页表条目。Table 字段中的地址确定包含页的页框物理地址所在页表中的条目。Offset 字段确定了页框中的相对位置。由于 Offset 字段为 12 位,因此每个页中都包含有 4 KB 数据。
下面小结物理地址的计算:
- cr3 + Page Directory (10 MSB) = 指向 table_base
- table_base + Page Table (10 中间位) = 指向 page_base
- page_base + Offset = 物理地址 (获得页框)
由于 Page Directory 字段和 Page Table 段都是 10 位,因此其可寻址上限为 1024*1024 KB,Offset 可寻址的范围最大为 2^12(4096 字节)。因此,页目录的可寻址上限为 1024*1024*4096(等于 2^32 个内存单元,即 4 GB)。因此在 x86 架构上,总可寻址上限是 4 GB。
扩展分页扩展分页是通过删除页表转换表实现的;此后线性地址的划分即可在页目录 (10 MSB) 和偏移量 (22 LSB) 之间完成了。
22 LSB 构成了页框的 4 MB 边界(2^22)。扩展分页可以与普通的分页模型一起使用,并可用于将大型的连续线性地址映射为对应的物理地址。操作系统中删除页表以提供扩展页表。这可以通过设置 PSE (page size extension) 实现。
36 位的 PSE 扩展了 36 位的物理地址,可以支持 4 MB 页,同时维护一个 4 字节的页目录条目,这样就可以提供一种对超过 4 GB 的物理内存进行寻址的方法,而不需要对操作系统进行太大的修改。这种方法对于按需分页来说具有一些实际的限制。 |