读书频道 > 系统 > windows > Windows内核原理与实现
4.1.1 页式内存管理
2013-05-18 14:51:17     我来说两句 
收藏    我要投稿   

本文所属图书 > Windows内核原理与实现

本书从操作系统原理的角度,详细解析了Windows如何实现现代操作系统的各个关键部件,包括进程、线程、物理内存和虚拟内存的管理,Windows中的同步和并发性支持,以及Windows的I/O模型。在介绍这些关键部件时,本...  立即去当当网订购

在如今的计算机体系结构中,内存基本单元总是字节,即8 个二进制位。每个地址指向一个字节,地址值加1 以后指向下一个字节。物理内存的编址,即前文讲到的物理地址,是固定的,所以,若直接让进程使用物理地址来访问内存将使得进程的动态分配难以有效实施,因为内存单元与进程将通过物理地址紧密地联系在一起了,从而内存的回收和再分配将受限于特定的进程和物理地址。为了打破这种关联关系,简单的思路是,让进程使用虚拟地址,而虚拟地址和物理地址之间通过一个映射表来完成转译。本节将要介绍的Intel x86 的页式内存管理正是这样一种方案。

在页式内存管理中,虚拟地址空间是按页(page )来管理的,对应于物理内存也按页来管理,物理内存中的页面有时候称为页帧(page frame ),其大小与虚拟空间中的页面相同。因此,映射关系是在内存页面的基础上进行的。在虚拟地址空间中连续的页面对应于在物理内存中的页面可以不必连续,并且,通过小心地维护好虚拟地址空间的页面与物理内存页面之间的映射关系,物理页面可以被动态地分配给特定的虚拟页面,从而只有当真正有必要的时候才把物理页面分配给虚拟页面,毕竟物理页面相对来说是稀缺资源。如图4.1所示,物理地址空间(其地址范围取决于系统中物理内存的数量,图中假设为1 GB物理内存)中有一部分页面被映射到了左侧的虚拟地址空间(在32位平台上,其地址范围为0x0~0xffffffff )。


 

注意,在一个系统中,物理地址空间只有一个,但虚拟地址空间可以有多个。每个虚拟地址空间都必须有一个映射关系,而且,虚拟地址空间中有相当一部分页面并没有对应的物理页面(在图 4.1中标记为“不使用”的页面)。实际上,每个虚拟地址空间往往只能映射到很少一部分物理页面。反过来,每个物理页面往往只被映射到一个虚拟地址空间中。如果有一个物理页面被映射至两个或两个以上的虚拟地址空间,那么,这些地址空间将共享此页面,若在一个虚拟地址空间中改写了此页面中的数据,则在其他的虚拟地址空间中将可以看到这样的变化。

有了页面划分的机制以后,我们可以想象,每个虚拟地址32位信息中,其中一部分位信息指定了一个物理页面,其余的位信息则指定了页内的偏移量。也就是说,虚拟地址分成了两部分:页索引+ 页内偏移,其结构如图4.2 所示。页索引是指该虚拟地址在映射关系中的索引编号,页内偏移则指定了该地址在页面内部的具体位置。


 

下面我们以Intel x86 为例来介绍从虚拟内存页面到物理内存页面的映射。首先,寻址系统必须确定页面的大小,标准的大小为4 KB,即212字节,所以,32位地址值的最后12位是页内偏移,而前 20位则是页索引部分,用于找到一个实际的物理页面。因此,在这样的系统上,页面映射表是一个 220=1 048 576(即1 M )大小的表。如果直接用一个简单的线性表来表达这一映射表的话,需要 4 MB 内存,因为表中每一项都要表达一个物理页面地址,即使考虑到页面起始地址的后面12位总是0,那也需要2.5 MB;如果再考虑到物理内存最高几位可能总是0,则还可以有一定程度的压缩,这取决于当前系统中物理内存的数量,譬如1 GB内存的话,则物理内存地址的最高2 位总是0 。这里我们忽略这些要素,假设映射表中的每一项都指定了一个32位物理内存地址。

另一方面,在此1 M 大小的映射表中,有相当数量的表项其实并没有用,所以,为这部分表项分配存储空间是浪费。Intel x86 采用了分级页表的方式来管理这一映射关系。32位虚拟地址中的页索引部分又被分成页目录索引(10位)和页表索引(10位)两部分,所以,一个32位虚拟地址的实际构成如图4.3中最上边的虚拟地址结构所示。


 

基于这样的虚拟地址构成,每个虚拟地址空间对应有一个页目录,其中包含210=1 024个目录项(PDE ,Page Directory Entry );每一个目录项指向一张包含 1 024项的页表。所以,Intel x86 处理器在解析一个虚拟地址时,首先根据最高10位在页目录中定位到一个页目录项,它指向一个页表。然后根据接下来的10位,在页表中定位到一个页表项(PTE ,Page Table Entry ),此页表项指定了目标页面的物理地址。最后在此物理地址的基础上加上页内偏移,即得到最终的物理地址。在图 4.3所示的地址解析过程中,实线箭头代表页目录、页表和页面之间的指示关系,而虚线箭头则代表了一个虚拟地址各个组成部分在页目录、页表或页面内部的索引关系(或偏移)。

在以上二级页表结构中,CR3 寄存器包含了页目录的物理地址,页目录的大小是4 096个字节,每个目录项为 4 个字节;同样,每个页表的大小也是 4 096个字节,其中每个页表项为4 个字节。目录项和页表项均指向一个 32位地址,但只有前 20位真正指向一个物理地址,后12位用于各种标志信息,比如页面是否已被访问过、是否允许缓存等。在本章后面介绍Windows 虚拟内存管理时,我们再进一步讨论PDE 和PTE 的结构。

对于一个满的虚拟地址空间,为维护映射关系共需要 1 个页目录和1 024个页表,所占空间为4 096+1 024×4 096个字节,即4 KB+4 MB大小。这比简单的线性页表多了4 KB开销,但它带来的好处是,当虚拟地址空间中实际使用的内存的比例较小时,很多页表不必在内存中构建出来,从而可以极大地节省这些页表的开销。不过,二级页表结构也要付出性能的代价,因为在解析一个虚拟地址时,需要两次查表操作。

为了避免在多级页表解析过程中多次查表而导致性能下降的问题,Intel x86 处理器缓存了地址转译信息,即从虚拟地址到物理地址的映射关系。这样,当处理器重复访问同一个地址时无须再进行转译。此缓存是一种位于处理器内部的关联存储单元阵列,也被称为地址转译快查缓冲区(TLB ,Translation Look-aside Buffer)。TLB 中包含了最近使用过的页面的内存映射信息,处理器提供了专门的电路来并发地读取并比较TLB 中的页面映射项。因此,对于频繁使用的虚拟地址,它们很可能在TLB 中有对应的映射项,因而处理器可以绝对快速地将虚拟地址转译成物理地址;反之,如果一个虚拟地址没有出现在TLB 中,那么处理器必须采用以上介绍的两次查表过程(意味着要两次访问内存)才能完成地址转译。在这种情况下,这一次内存访问会慢一些,但是,经过这次访问以后,此虚拟页面与对应物理页面之间的映射关系将被记录到TLB 中,所以,下次再访问此虚拟页面时,处理器就可以从 TLB 中实现快速转译,除非此映射项已经被 TLB 移除了。研究表明,由于计算机程序的内存访问有一定的局部性,因此,即使处理器只维护一个相对较小的TLB ,程序的运行也能获得较显著的性能提升[TLB-MISS]

在Intel x86 处理器中,TLB 是完全由硬件来维护的,换句话说,软件无法操纵TLB 以便加入、保留或移除其中的映射项。(但其他有些处理器允许软件通过异常机制来操纵TLB 。)然而,有一种情况可以使TLB 中的映射项失效,那就是当处理器切换CR3 寄存器的时候,原因很简单,一旦 CR3 寄存器切换了,就意味着从一个虚拟地址空间切换到了另一个虚拟地址空间,因此原来那些项没有理由再保留。但有一个例外,如果映射项的PTE的全局标志位(32 位PTE 的低 12 位都是标志位,其中第 8 位指明了这是一个全局项还是局部项)已置上,则在 CR3 寄存器切换虚拟地址空间的过程中,此映射项仍然留在 TLB 中。此外,在 Intel x86 Pentium Pro 以后的处理器中,通过 invlpg 指令可以使单个 TLB 项失效。

以上介绍了在Intel x86 处理器中,一个32位虚拟地址如何被转译为一个物理地址。另外,Intel x86 Pentium Pro 处理器还引入了一种称为物理地址扩展(PAE ,Physical Address Extension)的内存映射模式,它支持36位物理地址,但虚拟地址仍然是32位。因此,在PAE 模式下,系统支持64 GB 物理内存,其地址映射方式和页表结构也有所不同。虚拟地址的转译采用了三级页表机制,如图4.4 所示。在页目录之前增加了一个页目录指针索引,而页目录和页表中的每一项都为64位,所以,4 KB大小的页目录和页表只能存放512 项,正好对应于虚拟地址中的9 位索引值。页目录指针表包含4 项,分别指向4 个页目录之一。由于页目录和页表中的每一项都变成了64位,因此它们可以描述更长的物理地址。若简单地增加4 位物理地址,即从原来的20位(注意,还有12个标志位)扩展到24位,则处理器将允许系统使用64 GB 物理内存。Windows 用26位来表达物理地址,因此可以支持226+12=256 GB 物理内存。


 

简而言之,PAE 模式并没有增加虚拟地址空间的大小,但允许系统支持更多的物理内存。最后顺便提一下,在 Intel x64 处理器中,支持更多级页表机制。例如,64 位Windows使用四级页表,将一个 48 位虚拟地址转译成一个 40 位物理地址(从而允许物理内存达 1 TB大小)。在WRK的代码中,我们可以看到Windows 对于 Intel x86 PAE 模式和 64 位处理器的支持,但是,本书只讨论 Windows 对于 Intel x86 的32 位物理内存的支持。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:4.1 内存管理概述
下一篇:4.1.2 段式内存管理
相关文章
图文推荐
3.4.4 进程生命期管
3.4.2 Windows应用商
3.4.1 Windows应用商
3.4 进程生命期管理
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站