PAE ( Physical Address Extension )

本文探讨了32位与64位系统内存管理的不同之处,包括32位系统的4GB内存限制、如何通过物理地址扩展(PAE)技术突破这一限制以及64位系统的优势。此外还介绍了平面模式、保护模式和实模式等内存管理模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.chinaunix.net/uid-20384269-id-1954602.html
首先,内存访问和管理是一个跨越应用程序,操作系统,硬件平台的一个复杂过程,不能单纯的讲32bit系统就支持4G内存,从而认为这个过程只是OS和内存两者之间的关系
 
理论上:
32位系统,32bit的地址总线位数,寻址空间2^32B=4GB。 64位系统,寻址空间2^64。
至于在实际应用环境中,对于有4G物理内存而OS最多只能识别3G的情况,主要是主板的问题,丢掉的内存被PCI设备占用。
64位的主板支持PCI hole memory remapping,可以把这部分内存重新映射到高位的物理地址空间。
32是可用的地址总线位数(地址总线可不只32位,系统是32位的,用不了那么多)。
每次CPU工作,地址总线就给个地址,32位每次只能决定一个,然后地址总线把32个0或1弄出来成一个0或1(当然,地址总线不仅仅只有这个功能),基本就相当于译码器了。32个或0或1排列,根据排列组合就是2的32次方,由于内存编址是按字节(C中狭隘的字节,8bit)来的,所以就是2的32次方个字节了,也就是4GB。
 
这里谈一下对于打开CPU PAE功能从而能扩展OS内存支持的原理:
 
物理地址扩展PAE)是指x86和x86-64处理器的一个特色,即如果操作系统提供适当支持,则可以在32位的系统中使用超过4G的内存PAE为Intel Pentium Pro及以上级别的CPU(包括除了总线频率为400MHz的这个版本的奔腾M之外的所有新型号奔腾系列处理器)所支持,其它兼容的处理器,如速龙(Athlon)和AMD的较新型号的CPU也支持PAE。
x86的处理器增加了额外的地址线以选择那些增加了的内存地址,所以支持的内存寻址大小从32bit增加到36bit。最大支持内存由4G增加到64G,32位的虚拟地址则没有变,所以一般的应用软件可以继续使用地址为32位的指令;
如果用平面内存模式的话,这些软件的地址空间也被限制为4G
[注]:"平面内存模式"
8086体系的CPU一开始是20根地址线, 寻址寄存器是16位, 16位的寄存器可以访问64K的地址空间, 如果程序要想访问大于64K的内存, 就要把内存分段, 每段64K, 用段地址+偏移量的方法来访问.后来386CPU出来之后, 采用了32条地址线, 地址寄存器也扩为32位, 这样就可以不用分段了, 直接用一个地址寄存器来线性访问4G内存. 这就叫平面模式.
操作系统用页表将这4G的地址空间映射到大小为64G的物理内存空间,而这个映射对各个进程一般是不一样的。这样一来,即使不能为单单一个程序所用,那些增加了的物理内存仍然可以发挥作用。
对于需要超过4G内存的应用软件来说,除了一般的PAE支持,还需要操作系统提供另外的特殊的技术。
在Windows上,这种技术叫做Address Windowing Extensions(AWE)。而在类Unix的系统上则有多种技术在使用,例如使用mmap()按需要把一部分文件映射到地址空间;但是,这还没有成为一个标准。
Linux内核从2.6版本开始全面支持PAE,这使得在32位的机器上可以访问64GB的内存。启用了PAE的Linux内核还需要同样支持PAE的CPU。从2008年起,很多一般的发布的Linux版本都默认使用启用了PAE的内核。
Solaris从版本7开始支持PAE。但是,版本7的那些没有专门支持PAE的第三方驱动程序在支持PAE的系统上可能会发生错误,甚至完全崩溃。不过现在都早已是soloaris 10的时代. 如今基本不会有什么问题。
 
OS内存管理模式
除了前面提及的平面模式外,还有如下两种
 
“保护模式”
386的线性内存访问功能只在一种叫"保护模式"的状态上使用, 在这种状态下, 一切程序都可以用线性地址(不分段)访问自己所拥有的4G的内存空间, 但是不能访问其他程序的空间. 如果有程序要访问不该访问的内存(一般只有病毒才会这么作), 就会出系统错误, CPU就用中断通知OS, 这样的进程会被OS发现, 并杀死, 不会影响其他程序. 
在windows里常见的系统错误"某某内存不能读写"就是这种问题, 这都不是windows系统的问题, 而是一些程序的问题. 
在这种情况下, 实际是CPU和OS一起保护了程序的内存, 因此叫做保护模式.
 
“实模式”
实际上内存是不可能有4个G的(见
http://blog.chinaunix.net/space.php?uid=15724196&do=blog&cuid=1976044 )而且是每个程序都要有4G的空间. 为了为每个程序都提供4G内存, 386及以后的CPU采用"页"的方式来管理内存, 把内存分为一个个的页, 页的物理地址与每个程序虚拟的4G线性地址的对应关系用一个表格保存。
程序用线性地址访问一块内存. 如果这个内存还没有用过, 就找一个内存页来假装涉及的线性内存段. 如果这个内存长期不用, 操作系统就把内存页存到硬盘上去, 就叫虚存交换文件. 
如果这个内存所在的页已经分配过, 但是没有在实存里, 那么CPU就出现一个缺页中断, 此时就由操作系统把存储在硬盘上的交换文件里的页内数据读出来, 在实存中找一块写进去, 修改页地址和线性地址的对应表格, 然后请程序继续运行.
 
页表结构
在传统的32位的保护模式中,x86处理器使用一种两级的转换方案。在这种方案中,控制暂存器CR3指向一个长4K的页目录(page directory);页目录又分为1024个每个4K的页表(page table);最后页表又分为1024个每个长4K的页。
启用PAE(通过设置控制暂存器CR4的第5位来启用)会改变上面的方案。默认情况下,每页的大小是4K的。页表和页目录中的表项都从32位扩为64位(8字节)以使用附加的地址位。但是,页表和页目录的总大小不变。
所以,页表和页目录现在都只有512个表项。因为这变成了原来方案的一半,所以另外的一个级加了进来:CR3现在指向的是页目录指针表,即一个包含4个页目录指针的表。
页目录里的表项的第7位叫做PS(Page Size)。如果这个位设为1,则页目录的表项不再指向页表,而是指向一个2M的页。页目录里还有另外一个叫NX位元的标志位。它是第63位,表示No eXecute。
因为页表项最高的12位,要么是这种标识位,要么是和操作系统相关的数据,所以最多可有52位,在将来用于在252字节物理内存中寻址。
现在,x86架构只使用该52位中的36位。对于在长模式(long mode)中的x86-64处理器,PAE是必须的;其中使用了52位中的40位。
CPU对PAE模式的支持可以通过CPUID标志PAE来识别。
 
4种页表结构:

未启用PAE, 4 KB的页、未启用PAE, 4 MB的页、启用PAE, 4 KB的页、启用PAE, 2MB的页

图示可参见http://zh.wikipedia.org/wiki/PAE

### PAE技术详解 PAEPhysical Address Extension,物理地址扩展)是IA-32架构中的一种内存管理技术,允许32位处理器访问超过4GB的物理内存。在标准32位寻址模式下,处理器能够直接寻址的最大内存为4GB。通过启用PAE,可以将物理地址空间扩展到36位,从而支持最多64GB的物理内存[^2]。 #### PAE技术的核心机制 1. **页表结构扩展**: 在标准分页机制中,页目录和页表各占10位,形成一个两级页表结构。启用PAE后,增加了页目录指针表(Page Directory Pointer Table, PDPT),形成了三级页表结构。CR3寄存器不再存储页目录基址,而是存储页目录指针表基址[^2]。 2. **页目录指针表(PDPT)**: 每个PDPTE(Page Directory Pointer Table Entry)占用64位,其中高20位用于指向页目录的基址。这种设计使得页表结构更加灵活,能够支持更大的物理地址空间[^2]。 3. **标志位设置**: - CR0寄存器中的PG标志必须开启以启用分页机制。 - CR4寄存器中的PAE标志必须开启以启用PAE机制。 当这两个标志都被设置时,处理器进入PAE模式,CR3寄存器被重新定义为页目录指针表基址(PDPTR)[^2]。 4. **硬件支持**: 启用PAE的前提是CPU支持该特性。可以通过执行`CPUID`指令检查EDX寄存器的第6位是否为1来确认CPU是否支持PAE[^2]。 #### PAE测试方法 以下是进行PAE相关测试的具体方法: 1. **检查CPU是否支持PAE**: 使用`CPUID`指令或工具检测CPU是否支持PAE特性。例如,在Linux系统中可以运行以下命令: ```bash grep pae /proc/cpuinfo ``` 如果输出包含`pae`,则表示CPU支持PAE[^2]。 2. **验证操作系统是否启用了PAE**: 在Linux系统中,可以通过内核参数或模块加载情况判断是否启用了PAE。例如: ```bash uname -r ``` 如果内核名称中包含`pae`,则表示启用了PAE模式。此外,也可以通过以下命令检查: ```bash dmesg | grep PAE ``` 3. **测试大内存环境下的性能**: 构建一个超过4GB的物理内存环境,并运行应用程序测试其性能表现。例如,使用`memtest86+`工具对内存进行压力测试,观察是否存在错误或不稳定现象。 4. **驱动程序接口测试**: 通过编写或调用驱动程序接口,加载并解析页目录指针表(PDPT)、页目录表(PDT)和页表(PT)的内容。例如,参考引用中提到的MFC程序可以调用驱动程序接口加载PDPTE,并展示有效表项[^1]。 #### 示例代码:检查CPU是否支持PAE 以下是一个简单的C语言程序,用于检测CPU是否支持PAE特性: ```c #include <stdio.h> int main() { unsigned int eax, ebx, ecx, edx; // 获取 CPUID 信息 __asm__ volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); if (edx & (1 << 6)) { printf("CPU supports PAE.\n"); } else { printf("CPU does not support PAE.\n"); } return 0; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值