1. 程式人生 > >控制器中如何設計MMU--虛擬記憶體管理機制

控制器中如何設計MMU--虛擬記憶體管理機制

高階處理器CPU一般都會實現記憶體管理單元(MMU),其也是Linux等高階作業系統執行的必備條件。虛擬記憶體管理是linux作業系統的基本元件之一,其目的是讓每個應用程式都單獨擁有足夠大的(G位元組級別)邏輯空間,並共享同一塊較小的實體記憶體空間。虛擬記憶體管理正是依賴記憶體管理單元(MMU)來實現的。各程序在記憶體中的頁表和MMU中的TLB(相當於頁表的cache)是虛擬記憶體管理中的重要概念。

        在很多場景下的產品並不需要高階處理器那麼強的計算能力,而基於控制器的SOC更具競爭力,更低功耗,更省成本!但是基於MMU的虛擬記憶體管理思想對於輕量化的多工作業系統來說至關重要。假如,我們希望在基於控制器的SOC中實現MMU單元,然後通過定製作業系統的虛擬管理模組來實現記憶體管理,該怎麼做呢?

一、記憶體管理單元(MMU)的工作機制

    在闡述控制器領域的記憶體管理設計之前,還是要先介紹處理器領域的虛擬記憶體管理機制,前者很大程度上是對後者核心機制精髓的借鑑。實現虛擬記憶體管理有幾個模組是協調工作的:CPU、MMU、作業系統、實體記憶體,如圖示(假設該晶片系列沒有cache):

我們根據上圖來分析一下CPU訪問記憶體的過程,假設定址是0x10000008,一頁大小為4K(12位元)。則虛擬地址會分成兩個部分:頁對映部分(20bit,0x10000)+頁內偏移(12bit, 0x8)。CPU通過匯流排把地址訊號(0x10000008)送給MMU,MMU會把該地址的頁對映部分(20bit)拿到TLB中匹配。

TLB是什麼東西?Translation Lookaside Buffer,網上有稱為“翻譯後備緩衝器”。這個翻譯都不知道它幹什麼。它的作用就是頁表的緩衝,我喜歡叫它為頁表cache。其結構圖如下:

可以想象,TLB就是索引地址陣列,陣列的每個元素就是一個索引結構,包含虛擬頁地址和物理頁地址。其在晶片內部表現為暫存器形式,一般暫存器都是32位,實際上TLB中的頁地址也是32位暫存器,只不過索引比較時是比較前20bit,後12bit其實也是有用的,例如可以設定某個bit是表示常駐的,即該索引是永遠有效的,不能更換,這種場景一般是為適合一些效能要求特別高的編解碼演算法而設計的。非常駐記憶體的一般在某個時刻(如TLB填滿時訪問一個新的頁地址)就會發生置換。

1)  假如 0x10000008的前20bit在TLB中第M個索引中命中,這時就表示該虛擬頁在實體記憶體中已經給它分配好對應的實體記憶體,頁表中也已經做好記錄。至於虛擬地址對應的內碼表是否從外儲存(flash,card,硬碟)的程式中載入到記憶體中還需要要另外的標記,怎麼標記呢?就是利用上面所講的TLB低12位的某一bit(我們稱為K)來標識,1標識程式碼資料已經載入到記憶體,0表示還沒載入到記憶體。假如是1,那就會用M中的實體地址作為高20bit,以頁內偏移0x8作為低12bit,形成一個實體地址,送到記憶體去訪問。此時該次訪問就會完成。

2)  假如 K是0,那意味著程式碼資料尚未載入到記憶體,這時MMU會向中斷管理模組輸出訊號,觸發一箇中斷進行核心態,由作業系統負責將對應的內碼表載入到記憶體。並修改對應頁表項的K位元和TLB對應項的K位元為1.

3)  假如 0x10000008的前20bit在TLB所有索引中都沒有命中,則MMU也會向中斷管理模組輸出一個訊號觸發中斷進入核心態,由作業系統將0x10000008右移12位(即除以4K)到頁表中去取得對應的物理頁值,假如物理頁值非0有效,說明程式碼已經載入到記憶體了,這時將頁表項的值填入到某一個空閒的TLB項中;假如物理頁值為0,說明尚未給這個虛擬頁分配實際的實體記憶體空間,這時會給它分配實際的實體記憶體,並寫好頁表的對應項(這時K是0),最後將這索引項寫入TLB的其中一條。

2)和3)其實都是在中斷核心態中完成的,為什麼不一塊做了呢?主要是因為一次中斷不應該做太多事情,以加大中斷延時,影響系統性能。當然如果有晶片將兩者做成一箇中斷也是可以理解的。我們再來看看頁表的結構。頁表當然也可以按TLB那樣做成索引陣列,但是這樣有兩個不好的地方:

1)頁表是要對映所有的虛擬頁面的,其維護在記憶體中也需要不小的空間。頁大小是4K時,那對映全部就是4G/4K=1M條索引,每條索引4*2=8個位元組,就是8M記憶體。

2)假如按TLB那種結構,那匹配索引的過程就是一個for迴圈匹配電路,效率很低,要知道我們做這個都是在中斷態完成的。

所以一般的頁表都是設計成一維陣列,即以整個線性虛擬地址空間按頁為單位依次作為陣列的下標,即頁表的第一個字(4位元組)就對映虛擬地址空間的最低4K,第二個字對映虛擬地址最低的第二個4K,以此類推,頁表的第N個字就對映虛擬地址空間的第N個4K空間,即(N-1)*4K~4KN的地址空間。這樣頁表的大小就是1M*4=4M位元組,而且匹配索引的時候只是一個偏移計算,非常快。

二、控制器領域SOC記憶體管理單元設計

在這裡,貼出前公司同事(彭洪、江小煒)的專利,主要闡述了控制器SOC中記憶體管理單元的設計過程,我在基於MIPS核的SOC中整合並驗證了該專利的可行性,並通過定製作業系統和重構應用程式來高效實現了虛擬管理。良好的軟、硬體協同設計也是該系列晶片成功量產上億顆的前提條件。

以下只是MMU的系統設計,有關適配該機制的虛擬記憶體管理和應用程式重構以後再做分解。大家也可以通過檢視“SOC軟體架構設計”系列學習更多的軟硬體協同設計知識。專利有點長,關鍵的地方就在於定址命中時要做什麼,不命中時要做什麼。