您的位置:首页 > 其它

启用PAE机制下虚拟地址到物理地址的转换

2009-12-18 16:55 351 查看
启用PAE机制下虚拟地址到物理地址的转换
最近突然想起用softice手工计算一下虚拟地址到物理地址的转换,理论的东西如段表、页表等还是好理解的,但真正实际操作就碰到了大问题,特别是分页机制,根本不是从cr3到页目录表到页表再到物理地址这么简单,后来读了一下《Intel® 64 and IA-32 Architectures
Software Developer’s Manual》(Volume 3A: System Programming Guide, Part 1)的第三章“PROTECTED-MODE MEMORY MANAGEMENT”,才发现原先的认识还停留在80386的基础上,没有考虑PAE、PSE-36等机制,所以这里用一个实际例子简单解释一下, 具体的内容还得去看上述的那本手册(强烈推荐)。
先写一个简单的用于实验的例子,只要用vc++6.0建一个MFC的对话框程序(我把工程取名为“memory”),界面只要留下默认生成的“确认”按钮,该按钮的消息函数写成这样:
void CMemoryDlg::OnOK()
{
// TODO: Add extra validation here
int test = 0x12345;
CDialog::OnOK();
}
生成一个应用程序memory.exe,就可以开始实验了。
开启softice后,用symbol loader转换memory.exe以实现源码调试。呼出softice窗口,键入file memorydlg.cpp(包含按钮消息函数的cpp),代码窗口即出现该cpp文件的源码,寻找代码中的CMemoryDlg::OnOk函数,对CDialog::OnOK()一句设断点。用ctrl-d隐藏窗口,即弹出memory.exe程序的对话框,单击“确定按钮”,即弹出sofice窗口。
1、输入 d test,察看数据窗口,发现test(即0x12345)在0023:0012f698处
2、键入 gdt,发现0023对应的段基址为0x00000000,因此test的线性地址为0012f698
3、如果是双核的机器,则如下操作:键入cpu,发现高亮行为cpu0(不一定,可能为cpu0,也可能为cpu1),再键入cpu0(若高亮行为cpu1,则键入cpu1),查找对应的CR4寄存器,发现有PSE、PAE标志,说明已启用了PAE机制(PSE被PAE屏蔽)。再看CR3,为0x06c80260。如果是单核的直接键入cpu即可。



4、因为启用了PAE,故如下分解线性地址:

0x0012f698 :
[00] (用于选择页目录指针表项) [00 0000 000](用于选择页目录表项) [1 0010 1111](用于选择页表项) [0110 1001 1000](偏移)
或者:
[00] (用于选择页目录指针表项) [00 0000 000](用于选择页目录表项) [1 0010 1111 0110 1001 1000](偏移)
到底取哪一种具体要看页目录表项的PS(Page Size)位。
5、页目录指针表项地址:06c80260(cr3按32byte对齐)+8(页目录指针表项为8字节长)*0(线性地址高2位) = 06c80260
peek d 06c80260: 0x2a1d7801
peek d 06c80264: 0x00000000
因此,页目录指针表项低字为0x2a1d7801,高字为0x00000000
6、页目录表项地址:2a1d7000(页目录指针表项按4k对齐)+8(页目录表项为8字节长)* 0(线性地址21-29位) = 2a1d7000
peek d 2a1d7000: 0x36a60867
peek d 2a1d7005: 0
因此,页目录表项低字为0x36a60867,高字为0x00000000
由于页目录表项的第7位(PS位)为0(......,1000,0000,0001),故页目录表项指向页表而非指向4M大小的页(即线性地址采用第一种分解方法)
7、页表项地址: 36a60000(页目录表项按4k对齐)+ 8(页目录表项为8字节长)* 0x12f(线性地址12-20) = 36a60978
peek d 36a60978: 0x25e25867
peek d 36a6097c : 0x80000000
(手册中说64页表项的高地址28被保留为零,但不知为何最高位是1,可能这几年最高位已被用作某种标志,我看的是06年的版本,知道的告诉我啊,这里且不管)
因此,页表项低字为0x36a60867,高字为0x00000000
8、物理地址:25e25000(页表项按4k对齐(63位的1暂且看作0吧)) +0x698(线性地址低12位) = 25e25698
于是我们得到了物理地址:0x25e25867
peek d 25e25698: 0x00012345
果然得到了在虚拟地址0023:0012f698处的变量test(0x12345) 的物理地址。
关于PAE机制下的线性地址转换和各种表项如下:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: