Windows中,无论是应用程序仍是内核程序,都不能直接访问物理内存,全部非IO指令都只能访问虚拟内存地址,如Mov eax, DWORD PTR[虚拟地址]形式,可是,有时候,咱们明明已经知道了某个东西固定在物理内存条某处,假如系统时间的值永远固定存放在物理内存条的物理地址0x80000000处,咱们已经知道了物理地址,如何访问得到系统时间值呢?这是个问题!Windows为了解决这样的直接访问物理内存操做提供了手段!其中之一即是:“为物理页面创建临时映射”,也便可以将某个物理页面映射到系统地址空间中的那段专用于临时页面映射的保留区域。app
系统地址空间中专用于临时映射的那段保留区的起始虚拟地址为:#define HYPERSPACE 0xC0400000函数
保留区的大小为:1024个虚拟页面,也即1024*4KB=4MB大小spa
函数MmCreateHyperspaceMapping用来将指定物理页面 临时 映射到保留区中的某个虚拟页面,返回获得的虚拟页面地址blog
Void* MmCreateHyperspaceMapping(pfn) { PTE* Pte=临时映射保留区的映射描述符们所在的二级页表;//也即第一个临时页面的映射描述符 Pte+=pfn%1024;//从这个虚拟页面的映射描述符开始,向后搜索第一个还没有映射的虚拟页面 For(i=pfn%1024; i<1024; i++,Pte++)//先遍历后面的那些PTE { If(*pte == 空白) { *pte.pfn=pfn; Break; } } If(i==1024)//若是后面部分未找到一个空闲PTE,又从前面部分开始查找 { PTE* Pte=临时映射保留区的映射描述符们所在的二级页表;//回到开头 For(i=0; i<pfn%1024;i++,Pte++) { If(*pte == 空白) { *pte.pfn=pfn; Break; } }//end for }//end if(i==1024) //上面是一个简单的闭式hash表的查找过程,找到一个还没有映射的临时保留虚拟页面后,就返回 Return HYPERSPACE + i*4kb; }
既然叫临时映射,那用完后,就得撤销映射:MmDeleteHyperspaceMapping(pfn);//这个函数就是用来删除之前创建的临时映射内存