1. 程式人生 > >自己學驅動13——記憶體管理單元MMU(虛擬地址和實體地址)

自己學驅動13——記憶體管理單元MMU(虛擬地址和實體地址)

1.MMU簡介
    MMU負責完成虛擬地址到實體地址的對映,並提供硬體機制的記憶體訪問許可權檢查。現代的多使用者多程序作業系統通過MMU使得各個使用者程序都擁有自己獨立的地址空間:地址對映功能使得各個程序擁有"看起來"一樣的地址空間,而記憶體訪問許可權的檢查可以保護每個程序所使用的記憶體不會被其他程序所破壞。MMU增加了底層的複雜性,但是為上層程式開發提供了極大的方便。

2.虛擬地址與實體地址
    虛擬地址最終需要轉換為實體地址才能讀寫實際的資料,這通過將虛擬地址空間、實體地址空間劃分為同樣大小的一塊塊空間(稱為段或頁),然後為這兩類小空間建立對映關係來實現。由於虛擬地址空間遠大於實體地址空間,有可能多塊虛擬地址空間對映到同一實體地址空間,或者有些虛擬地址空間沒有對映到具體的實體地址空間(在使用到時再對映)。
    ARM CPU上的地址轉換過程涉及到3個概念:虛擬地址(VA)、變換後的虛擬地址(MVA)和實體地址(PA)。當沒有啟動MMU時,CPU核、cache、MMU、外設等所有部件使用的都是實體地址。啟動MMU之後,CPU核對外發出虛擬地址VA;VA被轉換為MVA供cache和MMU使用,cache和MMU完成MVA到PA的轉換;最後使用PA讀寫具體的實際裝置。
    (1)CPU核看到的、用到的只是VA(啟動MMU之後),VA到PA的轉換對於CPU核來說是透明的。
    (2)cache和MMU是看不見VA的。
    (3)實際裝置看不到VA和MVA。
    注:MVA是除CPU核外的其他部分看見的虛擬地址。

3.VA和MVA之間的轉換

    之所以要設定一級VA和MVA之間的轉換,是為了提高系統執行的效率。在2440中,VA和MVA之間的轉換關係為:如果VA<32M,需要使用程序標識號PID(通過讀CP15的C13獲得)來轉換為MVA,VA與MVA的轉換方法如下(由硬體自動完成):
if(VA < 32M) then
    MVA = VA | (PID << 25);
else
    MVA = VA;
    利用PID生成MVA的目的是為了減少切換程序時的代價:不使用MVA而直接使用VA的話,當兩個程序的虛擬地址空間VA重疊時(因為對於每個上層應用來說都是擁有獨立的4G空間,所以對於VA的使用一般都是從小地址往大地址佔用),在切換程序時為了把重疊的VA對映到不同的PA上去,需要重建頁表、使無效cache和TLBS等,代價極大。
    而使用了MVA之後,切換程序將會簡化許多。作業系統中一般小於32M的小程序居多,而真正的大程序反而較少,假設現在有20個小於32M的小程序,有5個超過32M的大程序,那麼一共擁有25個不同的PID,這20個小程序會被對映到不同的MVA(因為其均未超過32M),而這5個大程序的低32M的VA也會被對映到不同的MVA,超過的部分會使用到重建頁表等來完成對映。
    MVA將4G的記憶體分為2^7=128個32M的空間(PID<<25),如果這128個程序使用的VA都是0~32M之間,則他們的地址都不會重疊,這樣在程序切換時付出的代價是極小的。

4.VA到PA的轉換過程

    將一個虛擬地址轉換為實體地址一般有兩種方法:第一,使用一個數學公式進行轉換;第二,用表格儲存虛擬地址對應的實體地址。這類表格被稱為頁表,頁表由一個個條目組成,每個條目儲存了一段虛擬地址對應的實體地址及其訪問許可權,或下一級頁表的地址。ARM中使用的是頁表方法。
    2440最多會用到兩級頁表:以段(1M)的方式進行轉換時只用到一級頁表,以頁的方式進行轉換時用到兩級頁表。頁的大小有三種:大頁(64KB)、小頁(4KB)和極小頁(1KB)。
    大概的轉換過程如下:
    (1)根據給定的VA找到一級頁表中的條目;
    (2)如果此條目是段描述符,則返回實體地址,轉換結束;
    (3)如果此條目是二級頁表描述符,繼續利用虛擬地址在此二級頁表中找到下一個條目;
    (4)如果第二個條目是頁描述符,則返回實體地址,轉換結束;
    (5)其他情況出錯。
    32位的CPU的虛擬地址空間達到4GB,一級頁表中使用4096個描述符來表示這4GB空間——每個描述符對應1MB的虛擬地址,要麼儲存了它對應的1MB物理空間的起始地址,要麼存入了下一級頁表的地址。MMU根據MVA的[31:20]一共12位來得到這4096個描述符中的一個,每個描述符佔用4B,所以一級頁表佔用了4KB。
    根據一級描述符的最低兩位,可以分為四種情況。
    (1)0b00:無效。
    (2)0b01:粗頁表。
    位[31:10]稱為粗頁表基址,此描述符的低10位填充0後就是一個二級頁表的實體地址。此二級頁表含有256個條目(10個bit表示,粗頁表佔用空間為1KB),粗頁表中的每個條目代表4KB的實體地址空間,所以256*4KB=1MB的空間。
    (3)0b10:段。
    位[31:20]稱為段基址,此描述符的低20位填充0之後就是一塊1MB實體地址空間的起始地址。MVA[19:0]用於在這1MB空間中定址。所以描述符的位[31:20]和MVA[19:0]就構成了這個虛擬地址MVA最終對應的PA。
    (4)0b11:細頁表。
    位[31:12]稱為細頁表基址,此描述符的低12位填充0之後就是一個二級頁表的實體地址。此二級頁表含1024個條目(每個條目4B,一共佔用4KB),其中每個條目代表1KB的實體地址空間,1024*1KB=1MB。
    以大頁(64K)、小頁(4K)或極小頁(1K)進行地址對映時,需要用到兩級頁表。二級頁表分為上述的粗頁表和細頁表兩種,根據二級描述符的最低兩位,可以分為以下四種情況。
    (1)0b00:無效。
    (2)0b01:大頁描述符。
    位[31:16]稱為大頁基址,此描述符的低16位填充0後就是一塊64KB實體地址空間的起始地址。粗頁表中每個條目只能表示4KB的物理空間,如果大頁描述符儲存在粗頁表中,則連續16個條目都儲存同一個大頁描述符。類似的,細頁表中每個條目只能表示1KB的物理空間,如果大頁描述符儲存在細頁表中,則連續64個條目都儲存同一個大頁描述符。
    (3)0b10:小頁描述符。
    位[31:12]稱為小頁基址,此描述符的低12位填充0後就是一塊4KB實體地址空間的起始地址。粗頁表中每個條目表示4KB的物理空間,如果小頁描述符儲存在粗頁表中,則只需要用一個條目來儲存一個小頁描述符。類似的,細頁表中每個條目只能表示1KB的物理空間,如果小頁描述符儲存在細頁表中,則連續4個條目都儲存在同一個小頁描述符中。
    (4)0b11:極小頁描述符。
    位[31:10]稱為極小頁基址,此描述符的低10位填充0之後就是一塊1KB的實體地址空間的起始地址。極小頁描述符只能儲存在細頁表中,用一個條目來儲存一個極小頁描述符。

5.MVA到PA總結

    從段、大頁、小頁和極小頁的地址轉換過程可知:
    (1)以段進行對映時,通過MVA[31:20]結合頁表得到的一段(1MB)的起始實體地址,MVA[19:0]用來在段中定址。
    (2)以大頁進行對映時,通過MVA[31:16]結合頁表得到一個大頁(64KB)的起始實體地址,MVA[15:0]用來在大頁中定址。
    (3)以小頁進行對映時,通過MVA[31:12]結合頁表得到的一個小頁(4KB)的起始實體地址,MVA[11:0]用來在小頁中定址。
    (4)以極小頁進行對映時,通過MVA[31:10]結合頁表得到的一個極小頁(1KB)的起始實體地址,MVA[9:0]用來在極小頁中定址。