自己動手做OS之Raspberry Pi MMU initialization.


寫了一個簡單的bare metal啟動MMU的程式,
把實際位址0x20000000~0x210000000 對應到虛擬位址0xa0000000~0xa1000000

ARM MMU的部份在ARMv6之前跟之後的版本不同,
請看Technical Reference Manual。

Raspberry Pi MMU initialization example.

hackpad note:https://lbd.hackpad.com/MMU-initialization-Jl8YoJ3iUdf
source code:https://github.com/tzuCarlos/RaspberryPi/tree/master/labMMU

  • 為什麼需要MMU?
TODO:....


頁表(page table)是由頁表項(page table entry, PTE)組成的。 每一個PTE包含一段虛擬位址(page)映射到一段實體位址的資訊,而page的大小依ARM core版本不同,有不同的支持1K(tiny page), 4K(small page), 64k(large page), 1MB, 16MB。
page的大小決定了映射的粒度(granularity):
  •  如果我們把page切1MB,那64MB的記憶體就需要64MB/1MB的PTE,每個PTE是32bits(4bytes),64x4=256bytes頁表項空間。4G就是4096x6=16384=16K


切1K,4K,64K需要用二級查表,1MB,64MB用一級查差,二級差表用途是縮小PTE,以減少佔用記憶體空間,但降底了尋址的效率。 16M的page叫super section, 1M的叫section。 L1表還有個名稱叫page directory entry(PDE)。

ARM 的位址轉換涉及底下三種位址[1]:
  • 虛擬位址 (Virtual Address,VA): CPU 送出的位址。
  • 修改後的虛擬位址 (Modified Virtual Address,MVA): 快取和 MMU 看到的是 MVA。
  • 物理位址 (Physical Address,PA): 內存看到的是 PA。

ARM920T(ARMv4) Technical Reference Manual 三章[2]:
圖中的Translation table是第一級頁表最大4096x32bit entries=16KB,每一個對應到1MB的虛擬記憶體,也就是4G,
Coarse page table是第二級頁表。
Translation table base(TTB) register

尋址過程:
   MVA跟register中的translation table base算出translation table(section table entry),再找到實際對應的位址
   從這圖可以看出來section table找法=TTB&0xffffc000 | ((viraddr >> 20) << 2 )
    取TTB的前15bits合併MVA的前12bits
    
Section格式
Section entry
  • 31:20 bits,共 12bits表示實體位址的前12位,剩的20bits也是2^20=1MB,每個section可以定址1MB的實體空間。
  • 19:12 bits,必需是0
  • 11:10 bits,是AP(Access permission),控制權限。
  • 9 必需是0
  • 8:5 bits,Domain control bit, ARM定義了16個domain。
  • 必需是1
  • 3:2 跟cache、write buffer有關
  • 1:0 定義了page size。 以section來說這兩個bits的值是0x10。

ARM官方的文件,要啟動MMU需要做的事。
6.4.1 Enabling the MMU
To enable the MMU in one world you must:
1. Program all relevant CP15 registers of the corresponding world.
2. Program first-level and second-level descriptor page tables as required.
3. Disable and invalidate the Instruction Cache for the corresponding world. You can then
re-enable the Instruction Cache when you enable the MMU.
4. Enable the MMU by setting bit 0 in the CP15 Control Register in the corresponding world.

figure source: 嵌入式Linux学习笔记(四)-内存管理单元mmu
我們現在要做的事如下:
  • 透過CP15 register設定Base address. (圖中的A)
  • 寫好 translation table((section table entry)至對應的記憶體區段中. (圖中的B)

  • 在Raspberry Pi上啟用MMU:
首先,請把arm1176jzfs_TRM,MMU跟CP 15章節看過。

Translation table,16kb的對齊,所以Translation的base位址一定是要16384(0x4000)的倍數,ex:0x10000,14000,18000...

4GB的虛擬位址, 共有4096x32bits,每個enrty描述1MB的虛擬記憶體。
section一共有4096個,2^12表示0x000xxxxx~0xfffxxxxx的前三個位址index.

把page的base指定到14000上,我們將會用到0x14000開始的16k位置。
  •  static unsigned int *page_table=(unsigned int *const)0x14000;

page_table存的資料,前12bits對應是實體位置的前12bits,請參照Technical Reference Manual。
我想把 實體的位址0x20000000~0x210000000對應到虛定位址0xa0000000~0xa1000000上
0xa0000000取前12bits,是0xa00=2650,也就是說*page_table[2560]要對應的就是0xa0000000~0xa00fffff這1MB的空間。
  • if (i >= (0xa0000000 >> 20) && i <= ( 0xa1000000 >> 20))
  •   page_table[i] = (i-2048)<<20 | 0x0410 | 2;
這邊我們想要對應到的位址是0x20000000前12bits是0x200=512,2560-2048=512,所以我們把i減去2048。如此一來,
  •   page_table[2560]=0x2000412
  •   page_table[2561]=0x2010412
  •   page_table[2562]=0x2010412 
  • .........................

接下來要做的事就是把透過CP15 register設定base address、domain、 跟啟動MMU
  • asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r" (page_table) : "memory");
  • asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (~0));
  • asm("mrc p15, 0, %0, c1, c0, 0" : "=r" (reg) : : "cc"); 
  • reg|=0x1; asm 
  • volatile("mcr p15, 0, %0, c1, c0, 0" : : "r" (reg) : "cc");


  • TODO: I-Cache, D-Cache, cache鎖定






Reference:
[2]ARM920T Technical Reference Manual.

Addison Wesley - ARM System-on-Chip Architecture, 2Ed

  • 未整理資料:
mmu-> 
1.切割記憶體單位page,1M的話叫section.
2.page table是記綠page對應的表,也是存在記憶體中。
3.每次MMU都要先查page table->再讀實際位址=> 讀兩次。
4.TLB就是MMU的cache
5.ARM依核心不同,可以切64MB,1MB,64k,4k...
section 解決兩件事,1. 實體位址, 2.存取權限。

Software directly access peripherals must use virtual address
Software access peripheral using DMA must use bus address
Software access RAM directly must use physical address.

留言

這個網誌中的熱門文章

C語言,大數運算,階層筆記

Raspberry Pi (ARMv6)上自幹一個微小作業系統

Linux VLAN 筆記