1. 程式人生 > >PAE——使32位系統支援最大64G記憶體

PAE——使32位系統支援最大64G記憶體

1 PAE

Physical Address Extension(PAE,中文譯名:實體地址擴充套件)技術最初是為了彌補32位地址在PC伺服器應用上的不足而推出的。我們知道,傳統的IA32架構只有32位地址匯流排,只能讓系統容納不超過4GB的記憶體,這麼大的記憶體,對於普通的桌面應用應該說是足夠用了。可是,對於伺服器應用來說,還是顯得不足,因為伺服器上可能承載了很多同時執行的應用。PAE技術將地址擴充套件到了36位,這樣,系統就能夠容納2^36=64GB的記憶體。同時,PAE技術的提出,也是為了解決在PSE技術中,大物理頁面必須為4MB的限制。通過前面的討論,我們知道PSE和PSE-36技術雖然滿足了部分應用對大記憶體頁面的需要,但是,從4KB到4MB的跳躍顯得太大了一些,現有的作業系統和應用對這種大頁面的採用勢必會導致嚴重的頁面內碎片,從而浪費記憶體。PAE技術在Pentium Pro以及以後的CPU中實現,AMD公司也在Athlon以及以後的CPU中普及了這一技術。

2 實現

與PSE、PSE-36技術類似,判斷一個CPU是否支援PAE,也可以通過CPUID指令的返回值來取得CPU對PAE的支援資訊。啟用CPU對PAE的支援,可以通過寫CR4的PAE使能位(第5位)來實現。 由於向下相容的原因,在擁有PAE技術支援的CPU上執行的作業系統以及應用程式被規定繼續沿用以前的32位虛擬地址,通過段式轉換,仍然得到32位的線性地址。而開啟PAE支援的頁式管理系統則負責把32位的線性地址對映到64GB物理空間的任何位置。在PAE技術支援下,系統可以擁有兩種大小的物理頁面:傳統的4KB和2MB頁面(注意,不是4MB)。同時,採用PAE技術的頁式地址轉換與傳統的IA32方式有了非常大的變化:首先,IA32中的兩級
頁表
在PAE中變成了三層,CR3指向的不再是頁目錄表,而被稱為頁目錄指標表(Page Directory Pointer Table),它其實是個短表,只包含了4個指向頁目錄表的指標(在Linux的實現裡,被稱為中間頁表PMD,Page Middle Directory),再由該頁目錄表指向可以選擇的頁表(也可以直接指向2MB的物理頁面)。其次,雖然頁目錄表和頁表仍然是4KB的大小,但是頁目錄項和頁表項(PDE和PTE)從以前的32位變為了64位。同時,頁目錄表和頁表所容納的頁目錄項或頁表項也從以前的1024個縮水到了512個。 在新的頁目錄表項中,如果PS位(第7位)被設定為1,則該頁目錄項所指向的就是一個2MB的物理頁面,否則,它所指向的就是下一級的
頁表
(注意,這與PSE、PSE-36技術是不同的,在前面的討論中,我們知道如果僅開啟PSE,且PS設定為1,則該頁目錄項指向的是一個4MB的物理頁面)。同時,在PAE中的頁目錄項新增加了一位,被稱為NX(No eXecute)位,它跟其他標誌位不同,被放在頁目錄項的高階(第63位)。我們知道,在傳統的IA32架構的頁目錄項(或者頁表項中),高20位儲存的是它指向的頁表或者物理頁面的首地址(因為頁表或物理頁面都是4KB對齊的,定址時只需要在這20位後面擴充12個0就是實體地址了),頁目錄項(或者頁表項)的低12位則儲存的是它指向的頁表或者物理頁面的屬性(包括PS位)。而使用PAE後,頁目錄項(或者頁表項)已經被擴充到了64位,這64位中能夠被用來儲存實體地址的位一共有:64-1(NX位)-12(屬性位)=51。也就是說,極端情況下,一個這樣的頁目錄項(或者頁表項)能夠覆蓋的實體記憶體範圍(如果我們不考慮在該實體地址後面填0來進一步擴充的話)為2^51=2PetaByte! 採用PAE技術的頁式地址對映機制如下圖所示: PAE with 4 KiB pages PAE with 2MB pages 3. 討論 應該說,PAE技術的引入,為x86在記憶體管理方面帶來了翻天覆地的變化。可是,這裡,我們要反問自己:為什麼要翻天覆地?在前面的討論中,我們知道PSE-36已經可以管理到64GB的記憶體,只是管理的方法比較矬而已(在4GB以上只能分配4MB的大頁面)。 首先,我們來分析傳統的IA32頁目錄或頁表項能否適應地址匯流排從32位到36位的變化。我們知道,在傳統的IA32頁目錄或頁表項中,除了儲存實體地址的20位外,本來還剩下了12位。除了儲存若干頁屬性的位,新增的PS位(第7位),以及必須為0的位(第8位)外,只剩下了3個可用位(第9-11位),也就是說該頁目錄或頁表項最多能容納23個地址位。假設保持4KB的物理頁面大小(實際上這個不可能改,因為要向下相容,也就是說要讓32位的作業系統不加改變就可以執行),這樣傳統的IA32頁表最大能夠管理的地址空間為:23+12=35,這與要達到的36個地址位的目標正好差了1位!這樣,在往36位甚至更高的64位擴充套件,而又要保證向下相容性的前提下,傳統的IA32頁式地址對映機制中頁目錄或頁表項的32位儲存空間就顯得太小,對它的擴充是必然的。 可是如果將這些表項的大小進行擴充,一個4KB的物理頁面能夠容納的表項的數目必然會變少。將其擴充1倍到64位,那麼一個4KB的物理頁面只能容納512個表項,也就是說每一級頁表或者頁目錄能夠覆蓋的地址位就從以前的10位變到了9位。這樣很自然的,32-12-9-9=2,也就是說還剩下2個地址位沒有被覆蓋,這樣就自然地催生了三級頁目錄、頁表結構,而最高的頁指標目錄就只用覆蓋2位,擁有4個表項就夠了。 從另一個角度來看這個問題。我們前面討論過,PSE和PSE-36技術擴充的大頁面只能是4MB,這跟傳統的4KB頁面相比,顯得跳躍太大,會浪費不少空間。而在三級頁表結構中,我們正好有了機會來修正這個錯誤:9+12=21,那麼2^21=2MB。所以,採用新的三級頁表結構,我們就可以支援2MB的大頁面了。那麼新的三級頁表結構能夠比較方便地實現同時支援4MB的大物理頁面嗎?這個問題留給讀者來思考。另一個問題是,如果我們要在三級地址對映的機制上支援4KB和1MB兩種頁面大小,頁式地址對映機制應該如何改變? 從以上的分析,我們可以看到,三級頁表結構雖然是不得已而為之,但確實達到了將地址匯流排寬度擴充套件到36位,且同時支援2MB的大物理頁面,這兩個目的,可謂一箭雙鵰!所以三級頁表結構絕不是Intel的工程師隨意為之,而是經過了慎重的思考和利益的權衡的。 隨著PAE技術的引入,如果系統使能了PAE,則傳統的IA32頁式地址對映機制,以及剛討論的PSE、PSE-36就都成了歷史。同時,PAE技術的引入,將頁目錄和頁表項擴充到了64位,這也為以後的x86-64的地址進一步擴充套件打下了基礎,雖然是無意的。 Linux核心對PAE的支援始於2.3.23,當然,為了管理更大的地址空間,必須在支援PAE的CPU上執行支援PAE的核心。到了2009年,支援PAE技術的核心已經成了Linux發行版的預設配置。 最後,需要特別指出的是,雖然PAE技術將系統實際的物理定址空間擴充套件到了36位,然而,對於作業系統和應用程式來說,它們能夠使用的邏輯地址仍然是32位的!也就是說,應用能夠用到的邏輯記憶體只有4GB(當然還要減去作業系統所佔的邏輯地址空間)。這要到x86-64技術推出後,情況才得以改觀。