2016-11-18
記得之前看windows內核原理與實現的時候,在內存管理部分,看到涉及到PAE模式的部分,提到此模式下可以讓系統在虛擬地址還是32位寬的情況下,支持64GB的物理內存或者更多。當時就沒怎么想明白,今天突然想起就結合intel手冊仔細研讀了一番,但是手冊所講主要是其尋址過程以及各級頁表和entry的結構,對如何支持這一說還真沒有提到。於是乎,google、上論壇等等,初步對其有了認識,難免讓人失望,因為其着實沒有我想的那么玄乎,下面還是分享下:
PAE模式是基於分頁模式的,如果CR.PG=1,CR4.PAE=1,則表示PAE模式被啟用。
根據手冊介紹,PAE模式下,一個32位的線性地址(虛擬地址)被翻譯成一個52位的物理地址,這句話才是整個PAE模式的精髓。52是最大支持的位數,所以按照PAE的思想,其實不只可以支持64GB,還可以更多。至於這個限制,而為何要限制於64GB,這點恐怕又和PAE的工作模式相關。
PAE模式如何支持大於32GB的物理內存?
PAE模式下,系統中的進程任意時刻還是只能訪問4GB的地址空間,這是虛擬地址寬度所限,但是考慮到一般的頁表項結構,低12位做各種標志,高20位作為物理頁框號,這樣滿打滿算也就可以定位2^20=1M個物理頁面,也就是在普通模式下無論如何最高只能支持4GB物理內存。
PAE模式下就不同了,其稍微改變了下頁表結構,把一個32位的虛擬地址分成4個部分:
0-11:頁內偏移
12-20:頁表(Page Table)
21-29:頁表目錄表(Page Table Directory)
30-31:頁目錄指針表(Page Directory Pointer Table)
可以看到,這里PAE的分頁把頁表項做成了8個字節,即64Bit,除去低12位做標志,還有52位可以用作尋址物理頁框,這正是PAE模式的核心。
細心的人可能會發現,即使如此,虛擬地址一共就32位,你2^2*2^9*2^9*4KB仍然是4GB 呀,怎么說就支持大於4GB的呢?沒錯,這也正是我開始疑惑的地方。但是人家根本沒把思想放在這方面,這也正是前面提到任意時刻,一個進程最高只能使用4GB的原因。重要的在於操作系統是多任務的,如果是在普通模式下,我現在有8GB的物理內存,而當前系統運行5個進程和系統進程,如果每個進程當前都需要1GB的物理內存,則在此模式下使行不通的,這6個進程只能平分8GB中的4GB,其他的只能通過不停的換入換出來實現。
而在支持PAE模式的情況下就不同了,上面6個進程均可分到1GB物理內存,並且在需要的時候還可以增加。這就是PAE帶來的好處。
話說說到這里,可能還有人不明白。分頁機制中有個重要的概念就是物理頁框號,頁表能夠層層遞進正是在頁表項中記錄了物理頁框號。物理頁框號可是全局的,即在整個系統中不會有重復的物理頁框。在普通模式下,只有20位用於物理頁框號,那么最高也就是支持2^20=1M個頁,即4GB物理內存。其他的有再多的內存尋址不到啊!
在PAE模式下,使用36根地址線,最大可以索引到64GB的物理內存。由於頁表項中有52位可以作為頁框號,所以其可以定位更多的物理頁框。即使礙於虛擬地址寬度所限,一個進程只能訪問4GB空間,但是放大格局。站在系統的角度,則是在其他的進程需要的時候,可以減少換出內存的次數,這是后備力量的加強!!
說到這里應該說的比較明白了,下面看PAE工作模式:
說到PAE的工作模式,其實本質上和普通的頁表沒什么區別,仍然是一級一級尋址而已,只是在具體尋址方法上有了細微的差別。
PAE模式下的不同之處:
1、CR3的值。PAE模式下,CR3存儲的是頁目錄指針表的地址,頁目錄指針表是32字節對齊的,其大小為32字節,所以此模式下的CR3結構如下:
其中每個表項是8個字節,共有四個表項,每個表項對應1GB的內存空間。對應於這四個表項,處理器為每個表項維護一個寄存器稱為PDPTE0,PDPTE1,PDPTE2,PDPTE3。處理器在適當的時候從
頁目錄指針表中加載值到這些寄存器,在訪問的時候使用寄存器來訪問,也減少了一次內存訪問哈!具體的時機如下:
1、PAE模式被啟用時。
2、進程任務切換時,即CR3的值改變的時候。
3、在VMX模式轉換的時候(虛擬化相關),本質上還是CR3值的變化。
所以此模式下,雖然CR3的作用依然如故,但是在尋址的時候可以直接利用PDPTE寄存器來定位具體的頁目錄了。PDPTE結構如下:
最下面的的M表示的是是實際的物理地址位寬,假如說是64GB即36位,那么M=36。通過12~(M-1)可以定位一個具體的物理頁框。
根據虛擬地址的21-29位作為偏移定位一個頁目錄頁表項,表項的第7位(從0開始)表明該表項是指向一個頁表還是一個2MB 的頁。
當表項指向一個2M的頁時,具體表項結構如下:
當表項指向一個頁表時,結構如下:
而具體的地址翻譯過程,看下圖:
參考:
1、intel手冊
2、stackOverflow論壇