arm mmu原始碼分析

迷霧綠洲發表於2015-07-30

arm7以上帶有mmu模組,這個模組可以進行單位大小的地址的重新對映,這是擴充套件地址空間,增加程式碼靈活性的一個模組。以下是一個原始碼

void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
{

unsigned int i;
    unsigned int reg;
    unsigned int low,high,ram;
    low = (0xa1000000 - 0xa0000000)>>20;
    high = (0xfffffffff - 0xa1000000)>>20;
    ram  = (0x20000000 -0x10000000)>>20;

    for(i=0;i<low;i++){
    reg = 0x10000000 +(i<<20);
    reg +=   0xc12;
    *(int *)(0xa1000000 +i*4) =reg;
    }

    for(i=0;i<ram;i++){
    reg = 0x10000000 +(i<<20);
    reg +=   0xc12;
    *(int *)(0xa1000000+(0x10000000>>20)*4 +i*4) =reg;
    }

    for(i=0;i<high;i++){
    reg = 0xa0000000+(i<<20);
    reg +=   0xc12;
    *(int *)(0xa1000000 + (0xa0000000>>20)*4 +i*4) =reg;
    }


    mmu_setttbase((UINT32)0xa1000000);

    mmu_enable();

}
開始階段我們要建立一張地址的對映表,這個表供cpu在拿到程式碼的地址訪問請求是進行地址的定址,在這個表裡拿到的地址才是真正的實體地址。而我們程式碼給cpu的請求地址現在已經變成虛擬地址,他必須經過mmu進行一次轉換。這樣我們就可以做到多個虛擬地址對應一個實體地址,一塊共享記憶體也就可以硬體實現了。這張表應該是長這個樣子的
00000c12 00100c12 00200c12 00300c12…..
這裡可以看出這是個一級頁表的對映,他的單位是1m地址對映。
0 ———-》0000
1m ———->1M
這裡就是一個原地址的對映關係
如果是
00100c12 在這張表的0地址
就是 0——–》1M 零地址對應了0x100000的地址了,這時候我們訪問0地址 其實會獲得0x1OOOOO地址的N內容。
void mmu_setttbase(register rt_uint32_t i)
{
register rt_uint32_t value;

value = 0;
asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value));

value = 0x55555555;
asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i));

}

這裡完成了整張表的初始化之後就要將這張表的首地址告訴給cpu了,也就是上面的協處理器的彙編程式碼了。這個想知道具體意義可以去查arm官方的文件。
有個問題需要注意:這張表的地址不能夠對映到其他地方,一定是給協處理器的地址,不然連cpu都找不到這張表,你的地址也就無法查到了。
最後就是開啟這個mmu了 ,通知cpu不要直接傳送地址而要去mmu進行轉換了,
void mmu_enable()
{
register rt_uint32_t i;

/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));

i |= 0x1;

/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));

}
這裡也是協處理器的彙編也就設定了一個bit。
後面進行cache相關。

相關文章