8种转换
由于页表被映射到了0xc0000000 开始的4MB地址空间。
所以我们也可以象CPU那样完成虚拟地址到物理地址的转换。
系统按照对应虚拟空间的先后顺序,把一个进程的页表映射在0xc0000000 开始的4MB地址空间中,把页目录映射在0xc0300000 开始的4KB地址空间中。于是我们可以做如下几种地址的相互转换。
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));
}
}
}
4 一个PDE的地址->相应的虚拟地址范围
VirtualAddressStart=((PDE_Address-0xC0300000)/4)<<22
VirtualAddressEnd=VirtualAddressStart+0x003FFFFF
5 一个PTE的地址->相应的虚拟地址范围
VirtualAddressStart=((PTE_Address-0xC0000000)/4)<<12
VirtualAddressEnd=VirtualAddressStart+0x00000FFF
6 物理地址->虚拟地址
一个物理地址常常会对应多个虚拟地址。转换方法就是遍历所有页表和页目录,如果有效就比较该项的高20bit是否等于我们提供的物理地址的高20bit,如果相等,就找到了一个。比如该项是第i个PDE的,第j个PTE,那么虚拟地址等于,i*4M+j*4K+物理地址的低12bit。遍历所有页表和页目录找到每一个。
7 一个PTE的地址->相应PDE的地址
一个PTE的地址可以找到相应的虚拟地址范围,就可以找到虚拟地址对应的PDE地址
PDE_Address=(VirtualAddress>>22)*4+0xC0300000
PDE_Address=((((PTE_Address-0xC0000000)/4)<<12)>>22)*4+0xC0300000
8 一个PDE的地址->相应PTE的地址范围
一个PDE的地址可以找到相应的虚拟地址范围的开始地址,就可以找到该虚拟地址对应的PTE地址,
一个PDE对应1024个PTE,4K大小。
PTE_AddressStart=(VirtualAddress>>12)*4+0xC0000000
PTE_AddressStart=((((PDE_Address-0xC0300000)/4)<<22)>>12)*4+0xC0000000
PTE_AddressEnd=PTE_AddressStart+0x00000FFF
无效页与 Page Fault
访问的虚拟地址所在页在物理内存中时,该虚拟地址所在页相应的 PDE,PTE 都有效,CPU 自动根据相应的PDE,PTE把虚拟地址转换成物理地址,完成访问。一个虚拟地址所在页不在物理内存中时,比如在硬盘上的交换文件中,该虚拟地址所在页相应的 PDE,PTE 都无效,访问该虚拟地址将引起 Page-Fault 异常(Exception)。从而使 CPU 转去执行异常处理程序,异常处理程序会做相应的处理。对于发现访问的虚拟地址所在的页在硬盘上的交换文件中,就从交换文件中读入该页到物理内存,重新使PTE有效,并指向正确的物理页。最后 CPU 重新执行引起异常的指令,这时该指令所访问的虚拟地址已经在物理内存中了,并且该虚拟地址的PTE也有效
由于页表被映射到了0xc0000000 开始的4MB地址空间。
所以我们也可以象CPU那样完成虚拟地址到物理地址的转换。
系统按照对应虚拟空间的先后顺序,把一个进程的页表映射在0xc0000000 开始的4MB地址空间中,把页目录映射在0xc0300000 开始的4KB地址空间中。于是我们可以做如下几种地址的相互转换。
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));
}
}
}
4 一个PDE的地址->相应的虚拟地址范围
VirtualAddressStart=((PDE_Address-0xC0300000)/4)<<22
VirtualAddressEnd=VirtualAddressStart+0x003FFFFF
5 一个PTE的地址->相应的虚拟地址范围
VirtualAddressStart=((PTE_Address-0xC0000000)/4)<<12
VirtualAddressEnd=VirtualAddressStart+0x00000FFF
6 物理地址->虚拟地址
一个物理地址常常会对应多个虚拟地址。转换方法就是遍历所有页表和页目录,如果有效就比较该项的高20bit是否等于我们提供的物理地址的高20bit,如果相等,就找到了一个。比如该项是第i个PDE的,第j个PTE,那么虚拟地址等于,i*4M+j*4K+物理地址的低12bit。遍历所有页表和页目录找到每一个。
7 一个PTE的地址->相应PDE的地址
一个PTE的地址可以找到相应的虚拟地址范围,就可以找到虚拟地址对应的PDE地址
PDE_Address=(VirtualAddress>>22)*4+0xC0300000
PDE_Address=((((PTE_Address-0xC0000000)/4)<<12)>>22)*4+0xC0300000
8 一个PDE的地址->相应PTE的地址范围
一个PDE的地址可以找到相应的虚拟地址范围的开始地址,就可以找到该虚拟地址对应的PTE地址,
一个PDE对应1024个PTE,4K大小。
PTE_AddressStart=(VirtualAddress>>12)*4+0xC0000000
PTE_AddressStart=((((PDE_Address-0xC0300000)/4)<<22)>>12)*4+0xC0000000
PTE_AddressEnd=PTE_AddressStart+0x00000FFF
无效页与 Page Fault
访问的虚拟地址所在页在物理内存中时,该虚拟地址所在页相应的 PDE,PTE 都有效,CPU 自动根据相应的PDE,PTE把虚拟地址转换成物理地址,完成访问。一个虚拟地址所在页不在物理内存中时,比如在硬盘上的交换文件中,该虚拟地址所在页相应的 PDE,PTE 都无效,访问该虚拟地址将引起 Page-Fault 异常(Exception)。从而使 CPU 转去执行异常处理程序,异常处理程序会做相应的处理。对于发现访问的虚拟地址所在的页在硬盘上的交换文件中,就从交换文件中读入该页到物理内存,重新使PTE有效,并指向正确的物理页。最后 CPU 重新执行引起异常的指令,这时该指令所访问的虚拟地址已经在物理内存中了,并且该虚拟地址的PTE也有效