PAE——使32位系统支持最大64G内存

1 PAE


Physical Address Extension(PAE,中文译名:物理地址扩展)技术最初是为了弥补32位地址在PC服务器应用上的不足而推出的。我们知道,传统的IA32架构只有32位 地址总线,只能让系统容纳不超过4GB的内存,这么大的内存,对于普通的桌面应用应该说是足够用了。可是,对于服务器应用来说,还是显得不足,因为服务器上可能承载了很多同时运行的应用。PAE技术将地址扩展到了36位,这样,系统就能够容纳2^36=64GB的内存。同时,PAE技术的提出,也是为了解决在PSE技术中,大物理页面必须为4MB的限制。通过前面的讨论,我们知道PSE和PSE-36技术虽然满足了部分应用对大内存页面的需要,但是,从4KB到4MB的跳跃显得太大了一些,现有的操作系统和应用对这种大页面的采用势必会导致严重的页面内碎片,从而浪费内存。PAE技术在Pentium Pro以及以后的CPU中实现,AMD公司也在Athlon以及以后的CPU中普及了这一技术。

2 实现

与PSE、PSE-36技术类似,判断一个CPU是否支持PAE,也可以通过CPUID指令的返回值来取得CPU对PAE的支持信息。激活CPU对PAE的支持,可以通过写CR4的PAE使能位(第5位)来实现。
由于向下兼容的原因,在拥有PAE技术支持的CPU上运行的操作系统以及应用程序被规定继续沿用以前的32位 虚拟地址,通过段式转换,仍然得到32位的 线性地址。而打开PAE支持的页式管理系统则负责把32位的线性地址映射到64GB物理空间的任何位置。在PAE技术支持下,系统可以拥有两种大小的物理页面:传统的4KB和2MB页面(注意,不是4MB)。同时,采用PAE技术的页式 地址转换与传统的IA32方式有了非常大的变化:首先,IA32中的两级 页表在PAE中变成了三层,CR3指向的不再是页目录表,而被称为页目录指针表(Page Directory Pointer Table),它其实是个短表,只包含了4个指向页目录表的指针(在Linux的实现里,被称为中间页表PMD,Page Middle Directory),再由该页目录表指向可以选择的页表(也可以直接指向2MB的物理页面)。其次,虽然页目录表和 页表仍然是4KB的大小,但是页目录项和页表项(PDE和PTE)从以前的32位变为了64位。同时,页目录表和 页表所容纳的页目录项或页表项也从以前的1024个缩水到了512个。
在新的页目录表项中,如果PS位(第7位)被设置为1,则该页目录项所指向的就是一个2MB的物理页面,否则,它所指向的就是下一级的 页表(注意,这与PSE、PSE-36技术是不同的,在前面的讨论中,我们知道如果仅打开PSE,且PS设置为1,则该页目录项指向的是一个4MB的物理页面)。同时,在PAE中的页目录项新增加了一位,被称为NX(No eXecute)位,它跟其他标志位不同,被放在页目录项的高端(第63位)。我们知道,在传统的IA32架构的页目录项(或者 页表项中),高20位存储的是它指向的页表或者物理页面的首地址(因为页表或物理页面都是4KB对齐的,寻址时只需要在这20位后面扩充12个0就是 物理地址了),页目录项(或者页表项)的低12位则存储的是它指向的页表或者物理页面的属性(包括PS位)。而使用PAE后,页目录项(或者 页表项)已经被扩充到了64位,这64位中能够被用来存储 物理地址的位一共有:64-1(NX位)-12(属性位)=51。也就是说,极端情况下,一个这样的页目录项(或者 页表项)能够覆盖的 物理内存范围(如果我们不考虑在该 物理地址后面填0来进一步扩充的话)为2^51=2 PetaByte!
采用PAE技术的页式 地址映射机制如下图所示:
PAE——使32位系统支持最大64G内存
PAE with 4 KiB pages
PAE——使32位系统支持最大64G内存
PAE with 2MB pages
3. 讨论
应该说,PAE技术的引入,为x86在内存管理方面带来了翻天覆地的变化。可是,这里,我们要反问自己:为什么要翻天覆地?在前面的讨论中,我们知道PSE-36已经可以管理到64GB的内存,只是管理的方法比较矬而已(在4GB以上只能分配4MB的大页面)。
首先,我们来分析传统的IA32页目录或 页表项能否适应 地址总线从32位到36位的变化。我们知道,在传统的IA32页目录或 页表项中,除了存储物理地址的20位外,本来还剩下了12位。除了 存储若干页属性的位,新增的PS位(第7位),以及必须为0的位(第8位)外,只剩下了3个可用位(第9-11位),也就是说该页目录或 页表项最多能容纳23个地址位。假设保持4KB的物理页面大小(实际上这个不可能改,因为要向下兼容,也就是说要让32位的操作系统不加改变就可以运行),这样传统的IA32 页表最大能够管理的 地址空间为:23+12=35,这与要达到的36个地址位的目标正好差了1位!这样,在往36位甚至更高的64位扩展,而又要保证向下兼容性的前提下,传统的IA32页式 地址映射机制中页目录或页表项的32位 存储空间就显得太小,对它的扩充是必然的。
可是如果将这些表项的大小进行扩充,一个4KB的物理页面能够容纳的表项的数目必然会变少。将其扩充1倍到64位,那么一个4KB的物理页面只能容纳512个表项,也就是说每一级 页表或者页目录能够覆盖的地址位就从以前的10位变到了9位。这样很自然的,32-12-9-9=2,也就是说还剩下2个地址位没有被覆盖,这样就自然地催生了三级页目录、 页表结构,而最高的页指针目录就只用覆盖2位,拥有4个表项就够了。
从另一个角度来看这个问题。我们前面讨论过,PSE和PSE-36技术扩充的大页面只能是4MB,这跟传统的4KB页面相比,显得跳跃太大,会浪费不少空间。而在三级 页表结构中,我们正好有了机会来修正这个错误:9+12=21,那么2^21=2MB。所以,采用新的三级 页表结构,我们就可以支持2MB的大页面了。那么新的三级 页表结构能够比较方便地实现同时支持4MB的大物理页面吗?这个问题留给读者来思考。另一个问题是,如果我们要在三级 地址映射的机制上支持4KB和1MB两种页面大小,页式地址映射机制应该如何改变?
从以上的分析,我们可以看到,三级 页表结构虽然是不得已而为之,但确实达到了将 地址总线宽度扩展到36位,且同时支持2MB的大物理页面,这两个目的,可谓一箭双雕!所以三级页表结构绝不是Intel的工程师随意为之,而是经过了慎重的思考和利益的权衡的。
随着PAE技术的引入,如果系统使能了PAE,则传统的IA32页式 地址映射机制,以及刚讨论的PSE、PSE-36就都成了历史。同时,PAE技术的引入,将页目录和 页表项扩充到了64位,这也为以后的x86-64的地址进一步扩展打下了基础,虽然是无意的。
Linux 内核对PAE的支持始于2.3.23,当然,为了管理更大的 地址空间,必须在支持PAE的CPU上运行支持PAE的内核。到了2009年,支持PAE技术的 内核已经成了Linux发行版的默认配置。
最后,需要特别指出的是,虽然PAE技术将系统实际的物理 寻址空间扩展到了36位,然而,对于操作系统和应用程序来说,它们能够使用的 逻辑地址仍然是32位的!也就是说,应用能够用到的逻辑内存只有4GB(当然还要减去操作系统所占的 逻辑地址空间)。这要到x86-64技术推出后,情况才得以改观。

你可能感兴趣的:(32位,PAE,最大内存)