如果系統要保證某個線性位址是有效的,那麼必須為其填充正确的PDE與PTE.
如果我們想填充PDE與PTE,那麼必須能夠通路PDT與PTT,這樣就存在2個問題:
- 系統已經為我們通路PDT與PTT挂好了PDE與PTE,我們隻用找到這個線性位址就可以了
- 系統是怎麼幫我們挂好PDE與PTE的?
注意:
CR3中存儲的是實體位址,不能在程式中直接讀取的。如果想讀取,也要把Cr3的值挂到PDT和PTT中才能通路,那麼怎麼通過線性位址通路PDT和PTT呢?
一.頁目錄表基址
頁目錄表基址 = 線性位址:0xC0300000
怎麼來論證這個
0xC0300000
就是PDT的基址呢
首先随便找一個程序

拆分
0xC0300000
,尋找對應的實體頁
0xC0300000
1100 0000 0011 0000 0000 0000 0000 0000
1100 0000 00 //0x300
11 0000 0000 //0x300
0000 0000 0000 //0x0
可以發現 實體頁的内容 與 PDT表的内容 完全相同
是以我們可以得出結論
- 線性位址C0300000對應的實體頁就是頁目錄表
- 這個實體頁即頁目錄表本身也是頁表
- 這個實體頁是一張特殊的頁表,每一項PTE指向的不是普通的實體頁,而是指向其它的頁表
- 通路頁目錄表的公式:C0300000 + PDI*4(I=index)
[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址
二.頁表基址
上面我們找到了PDT的基址,但如果我們要設定某個線性位址的PDE和PET那麼還要能夠通路PTT,那麼如何通路呢?
頁表基址 = 線性位址:0xC0000000
還是那個程序,這是PDT裡的三張PTT表的基址
拆分
0xC0000000
十六進制:
0xC0000000
1100 0000 00 //0x300
0000 0000 00 //0x0
0000 0000 0000 //0x0
可以發現 每一項PTE所指向的實體頁的内容 與 每一個PDE所指向的PTT表的内容完全相同
檢視線性位址C0001000對應的PTT表
0xC0001000
1100 0000 0000 0000 0001 0000 0000 0000
1100 0000 00 //0x300
00 0000 0001 //0x1
0000 0000 0000 //0x0
發現線性位址C0001000指向的PTT表的第1項PTE為線性位址0xC0000000指向的PTT表的第2項PTE
通過上述的實驗我們總結一下可以得知
- 其實頁目錄表(PDT)本不存在,是抽象出來的.
- 頁表被映射到了從0xC0000000到0xC03FFFFF的4M位址空間
- 在這1024個表中有一張特殊的表:頁目錄表(PDT)
- 頁目錄被映射到了0xC0300000開始處的4K位址空間
- 通路頁表的公式:
0xC0000000 + PDI*4096 + PTI*4(I=index)
還是上面這個圖
總結
- 有了
和0xC0300000
0xC0000000
能做什麼:
掌握了這兩個位址,就掌握了一個程序所有的實體記憶體讀寫權
-
公式總結:
通路頁目錄表的公式:
通路頁表的公式:C0300000 + PDI*4(I=index)
0xC0000000 + PDI*4096 + PTI*4(I=index)