首页 > 代码库 > [转载]PAE下的虚拟内存映射 分析

[转载]PAE下的虚拟内存映射 分析

转自:http://user.qzone.qq.com/31731705/blog/1323414733



PAE 即为物理地址扩展(Physical Address Extension),详细的内容请Google。技术分享 

我的电脑是Win7,CPU是双核处理器,信息如下,
0: kd> !sysinfo cpuinfo 
[CPU Information]
~MHz = REG_DWORD 2527
Component Information = REG_BINARY 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Configuration Data = http://www.mamicode.com/REG_FULL_RESOURCE_DESCRIPTOR ff,ff,ff,ff,ff,ff,ff,ff,0,0,0,0,0,0,0,0
Identifier = REG_SZ x86 Family 6 Model 23 Stepping 10
ProcessorNameString = REG_SZ Intel(R) Core(TM)2 Duo CPU     P8700  @ 2.53GHz 
Update Signature = REG_BINARY 0,0,0,0,7,a,0,0
Update Status = REG_DWORD 6
VendorIdentifier = REG_SZ GenuineIntel
MSR8B = REG_QWORD a0700000000

 
看看PAE有没有打开?
1: kd> r cr4 
cr4=000406f9
0000 0000 0000 0100 0000 0110 1 1 11 1001
 
PGE/PAE/PSE = 1
内存映射说起来复杂,其实一二张图就能清楚的表述。在PAE模式,1页(Page)大小4K的情况下,内存是这样映射的,
虚拟地址(VA,32位,这里全用0表示) 00,000000000,000000000,000000000000
高2位:页目录指针的索引,接下来9位:页目录的索引,再接下来9位:页表索引,低12位:页内偏移,每个页目录项或者页表项占8个Bytes。
下图表示了从虚拟地址到物理地址的转化过程。
技术分享
 
整个4G内存从0xC0000000映射,假设使用1G为单位,分成4块,
0xC0000000-->0x00000000
0xC0200000-->0x40000000
0xC0400000-->0x80000000
0xC0600000-->0xC0000000
如下图所示:
技术分享
 
2M的页表可映射1G的内存,对于4G的内存来说,总共需要8M的页表。
也就是说,页表(PTE)放在0xC0000000到0xC07FFFFF区域,映射了整个内存区域。
每4K内存映射到8个Byte上,得到这样的公式:页表的地址PTE = 0xC0000000 + VA >> 12 << 3
让我们放大,看下0xC0000000这块,因为它既是被映射的内存,同时又是页表,形成了自己映射自己的事实。
0xC0600000-->0xC0000000
0xC0601000-->0xC0200000
0xC0602000-->0xC0400000
0xC0603000-->0xC0600000
0xC0600000,0xC0601000,0xC0602000,0xC0603000这4页不仅是页表,还是页目录(PDE),因为它的内容是页表的地址。每个4K的页目录映射到2M的页表,总共有4个页目录,16K。
 
再次放大,仔细看看0xC0603000开始的内容,
0xC0603000-->0xC0600000
0xC0603008-->0xC0601000
0xC0603010-->0xC0602000
0xC0603018-->0xC0603000
0xC0603020-->0xC0604000
......
0xC0604000-->0xC0800000
0xC0603000开始的页是特别的,前4项指向了4个页目录,意味着这页,是页表(PTE),是页目录(PDE),实际上还是PAE模式下特有的PDPE,只有4项,4*8 = 32Byte。
0xC0603020开始指向后面的普通页表了,而0xC0604000开始指向的是普通的页,到0xC0800000页表结束,映射了总共4G的内存。

[转载]PAE下的虚拟内存映射 分析