1. 程式人生 > >MMU記憶體管理單元學習

MMU記憶體管理單元學習

1、記憶體管理單元(Memory Manager Unit)

記憶體管理單元的功能是:虛擬地址對映和許可權管理

2、虛擬地址概念

我們在Linux型別作業系統中看到的(利用printf打印出來的地址)都是虛擬地址,都是經過MMU加工對映的。比如兩個程式碼

hello1.c:

#include <stdio.h>

int a = 1;

int main(void)
{
    printf("0x%x\n",&a);
    while(1);
    return 0;
}

hello2.c:

#include <stdio.h>

int a = 3;

int main(void)
{
    printf("0x%x\n",&a);
    while(1);
    return 0;
}

你會發現同時執行起來,兩個程式打印出來的a的地址都是一樣的,這就說明兩個程式執行的地址是一樣的。

這樣對於CPU來說,不用管程式的地址是虛擬地址還是實體地址,CPU只用關心我要從這個地址中去獲取資料,至於這個地址是實體地址還是虛擬地址,就看你是否使用了MMU,如果使用了MMU,那就說明這是虛擬地址,否則就是實體地址。

3、虛擬地址和實體地址轉化

虛擬地址用VA表示,實體地址使用PA表示,那麼實體地址和虛擬地址對映關係可以抽象成一個關係式:VA = func(PA)。在MIPS架構中,這和個func實際功能就是VA = PA + 固定偏移。而在arm中,func就是MMU的對映功能,MMU常見對映方法就是段對映:將4G虛擬記憶體和實際實體記憶體之間的對映(對應關係)通過一張頁表來表示(也可以是二級對映)。而頁表的每一個頁表項就表示的是虛擬地址和實體地址之間的對映關係:一個頁表項表示1M虛擬記憶體和實體地址的關係。

4、MMU實質

MMU的功能實質就是一段結構固定的記憶體地址空間,當中存放的是以1M為單位(一塊)的虛擬地址和實體地址對映關係。比如你在記憶體中的一段空間,大小是4GB(虛擬記憶體)/  1MB  =  4096,也就是4K個表項,每一個表項按順序存放的是當前這1MB的虛擬地址對應的1M實體地址空間。例如,你現在的虛擬地址是0xa0000000,那麼他對應的虛擬頁表項是0xa0000000/1M = 0xa00,在虛擬頁表中對應的頁表項地址就是:頁表首地址+0xa00 * 4(因為一個頁表項存放的就是一個32位地址佔4位元組)。

5、MMU實驗

程式一上電的時候就會先從flash載入到SOC的片內RAM,然後開始在SOC片內RAM中執行,這時候,我們要在程式開始執行之前先初始化好C語言的執行環境(其實就是棧指標初始化),接下來關閉看門狗(否則程式會處在一直重啟狀態),接下來初始化SDRAM(因為片內RAM大小有限,而SDRAM要想使用必須先初始化),接下來才是設定對映頁表,使用MMU。

測試實驗描述:使用虛擬地址(每個暫存器地址、程式連結地址)完成LED流水燈實驗。設計驗證MMU的對映功能實驗的思路就是:

(1)初始化C語言棧指標

(2)關閉WDT看門狗

(3)初始化SDRAM

(4)建立頁表

其實就是在指定的虛擬地址的頁表項新增對應物理空間地址。比如你去控制一個LED燈,就必須要設定相關暫存器,而暫存器地址本身是實體地址,你就需要找到自己想要對映的虛擬地址對應的頁表項的位置處,加入虛擬地址,但是要注意,你新增的虛擬地址只能是1M的整數倍。

(5)將頁表地址告訴MMU

需要初始化MMU,其實就是將你存放頁表的實體地址告訴MMU,以後MMU新增或者查詢虛擬地址和實體地址的對映關係的時候直接去定位。

(6)啟動MMU

一旦MMU啟動了,那麼CPU所有讀寫記憶體用到的地址就都會被MMU當成虛擬地址去查詢頁表對映關係進而定位實際實體記憶體地址。也就是說,CPU只知道自己訪問的是地址,不關心是實體地址還是虛擬地址,如果MMU啟動了,那麼這個地址就是虛擬地址,否則就是實體地址。