4.1.2 I386的分页机制
分页机制是在段机制之后进行的,它进一步将线性地址转换为物理地址。I386使用4K字节大小的页,且每页的起始地址都被4K整除。因此,I386把4GB字节线性地址空间划分为1M个页面,采用了两级表结构。
两级表的第一级表称为页目录,存储在一个4K字节的页中,页目录表共有1K个表项,每个表项为4个字节,线性地址最高的10位(22~31)用来产生第一级表索引,由该索引得到的表项中的内容定位了二级表中的一个表的地址,即下级页表所在的内存块号。
第二级表称为页表,存储在一个4K字节页中,它包含了1K字节的表项,每个表项包含了一个页的物理地址。二级页表由线性地址的中间10位(12~21)位进行索引,定位页表表项,获得页的物理地址。页物理地址的高20位与线性地址的低12位形成最后的物理地址。
分页单元负责将线性地址转换成物理地址。线性地址会被分组成页的形式。这些线性地址实际上都是连续的——分页单元将这些连续的内存映射成对应的连续物理地址范围(称为页框)。注意,分页单元会直观地将RAM划分成固定大小的页框。
将这些页映射成页框的数据结构称为页表(page table)。页表存储在主存储器中,可由内核在启用分页单元之前对其进行恰当的初始化。图4-2显示了页表。
图4-2 页表将页转换成页框
在Linux中,分页单元的使用多于分段单元。前面介绍Linux分段模型时已提到,每个分段描述符都使用相同的地址集进行线性寻址,从而尽可能降低使用分段单元将逻辑地址转换成线性地址的需要。通过更多地使用分页单元而非分段单元,Linux可以极大地促进内存管理及其在不同硬件平台之间的可移植性。
下面介绍用于在I386架构中指定分页的字段,这些字段有助于在Linux中实现分页功能。分页单元进入作为分段单元输出结果的线性字段,然后进一步将其划分成以下3个字段:
Page Directory:以10MSB表示(Most Significant Bit,也就是二进制数字中值最大位的位置——MSB有时称为最左位)。
Page Table:以中间的10位表示。
Offset:以12LSB表示。(Least Significant Bit,也就是二进制整数中给定单元值的位的位置,即确定这个数字是奇数还是偶数。LSB有时称为最右位。这与数字权重最轻的数字类似,它是最右边位置处的数字。)
线性地址到对应物理位置的转换的过程包含两个步骤。第一步使用了一个称为页目录(Page Directory) 的转换表(从页目录转换成页表),第二步使用了一个称为页表(Page Table)的转换表(即页表加偏移量再加页框)。图4-3显示了此过程。
开始时,首先将页目录的物理地址加载到CR3寄存器中。线性地址中的Directory字段确定页目录中指向恰当的页表条目。Table字段中的地址确定包含页的页框物理地址所在页表中的条目。Offset字段确定了页框中的相对位置。由于Offset字段为12位,因此每个页中都包含有4KB数据。
物理地址的计算:
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个内存单元,即4GB)。因此在I386架构上,总可寻址上限是4GB。
图4-3 分页字段
为了支持大内存区域,Linux也采用了这种三级分页机制。在不需要为大内存区域时,即可将pmd定义成“1”,返回两级分页机制,在I386架构中,Linux引入了两级页表机制。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。