页目录和页表重合与分页地址转换

写得不错,转下,来自JIURL大牛的

 

 

 

页目录的地址为什么是C0300000,1个页目录加上1024个页表为什么只使用了1024*4K的地址空间

    对于要映射整个4G地址空间,是需要1024个页表和1个页目录的,每个都是4KB大小,也就是 1024*4KB+1*4KB=4MB+4KB。而实际中Win2k把每个进程的页目录和页表映射到了从 0xC0000000到0xC03FFFFF 这4MB的地址空间中(页目录在0xC0300000开始的4K)。注意是4MB地址空间而不是4MB+4KB。1024个页表和1个页目录,应该是需要 (1024+1)*4KB的地址空间的。而现在Win2k只使用了1024*4KB的地址空间这是为什么?

    原因就是页表被映射到了进程的地址空间。
    如果页表和页目录没有被映射到进程的地址空间中,而一个进程的4GB地址空间又都映射了物理内存的话,那么就确实需要1024个物理页来存放页表,和另外1个物理页来存放页目录,也就是需要(1024+1)*4KB的物理内存。
但是页表被映射到了进程的地址空间中,这导致了一个页表的内容和页目录的内容是完全一样的,正是这种完全相同,使得将1024个页表加1个页目录映射到地址空间只需要1024*4KB的地址空间,其中的一个页表和页目录完全重合了。
    一个页表1024项,每项对应4KB地址空间,一个页表对应4MB的地址空间。1024个对应了整个4GB地址空间。1024个页表也被映射到了从 0xC0000000到0xC03FFFFF 的4MB地址空间中。这4MB地址空间也是由一个页表来对应的。我们来看对应于从 0xC0000000到0xC03FFFFF 这4MB的地址空间的页表。该页表有1024项,每项对应一页的地址空间,表明是否在物理内存中,如果在,物理地址是多少。而这个页表是对应页表所在的 4MB地址空间的,所以它的每一项对应的一页,正是每个页表所在的页。也就是说这个页表的每一项指出了一个页表是否有物理内存映射,如果有的话,物理地址 是多少。这正是页目录所做的工作。把1024个页表映射到了地址空间,导致了1024个页表中的一个的内容和页目录完全重合,它既是页目录又是页表。所以 1个页目录加上1024个页表只使用了1024*4K的地址空间。

    页表被映射到地址空间的什么地方,是由操作系统的设计者决定的,他会综合考虑各种问题,作出最后的决定。不过一旦页表所在的地址空间的地址决定了,那么页目录的地址也就决定了,除非他打算多使用一页的地址空间保存和现在一个页表中完全相同的内容。

    Win2k中把页表映射到了从 0xC0000000到0xC03FFFFF 的4MB地址空间中,我们来计算一下负责这4M地址空间的那个页表的地址,那个页表就是和页目录重合的页表。4MB地址空间的首地址0xC0000000 显然是由该页表的第一项负责的,我们用这个地址来计算。PTE_Address=(VirtualAddress>> 12)*4+0xC0000000,
(0xC0000000>>12)*4+0xC0000000=0xC0000*4+0xC0000000=0x300000+0xC0000000=0xC0300000
正是页目录的虚拟地址。


=====================

 

1 虚拟地址->虚拟地址对应的PDE地址

PDE_Address=(VirtualAddress>>22)*4+0xC0300000 

2 虚拟地址->虚拟地址对应的PTE地址

PTE_Address=(VirtualAddress>>12)*4+0xC0000000 

3 虚拟地址->物理地址

如果 虚拟地址大于等于0x80000000 并且小于0xa0000000(在 Large Page 部分),
直接用虚拟地址减去0x80000000就得到了物理地址。
其他情况
取得该虚拟地址的PDE,判断是否有效。
有效的话,取得该虚拟地址的PTE,判断是否有效。
有效的话,将PTE的低12位清0加上虚拟地址的低12位就得到了物理地址。
由于页表和页目录在系统地址空间中,访问需要程序运行在ring0,所以要测试的话,需要写驱动程序。

unsigned int PDE;
unsigned int PTE;

if(VirtualAddress>=0x80000000 && VirtualAddress<0xa0000000)
{
PhysicalAddress=VirtualAddress-0x80000000;
}
else
{
PDE=*(unsigned int*)((VirtualAddress>>22)*4+0xC0300000);
if(PDE&0x00000001)
{
PTE=*(unsigned int*)((VirtualAddress>>12)*4+0xC0000000);
if(PTE&0x00000001)
{
PhysicalAddress=((PTE&0xFFFFF000)+(VirtualAddress&0x00000FFF));//
((PTE&0xFFFFF000)这里是取PTE的高20位,是物理地址的起始,(VirtualAddress&0x00000FFF)取得偏移
}
}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值