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);//這個函數就是用來刪除之前創建的臨時映射內存