1、mmu的作用
1.1 將虛擬位址轉化為實體地址
虛擬位址(va)是軟體程式能表達的非物理的實體地址,實體地址(pa)是儲存單元對應的實際位址。在沒有啟動mmu之前,訪問的位址都是實體地址,我們訪問0位址,就要寫(int*)0x00,啟動mmu之後就可以將虛擬位址0x50000000對映到實體地址0x00,則訪問0位址就可以這樣寫(int *)x0x50000000。
1.2 訪問許可權管理
mmu決定一塊記憶體是否允許讀、是否允許寫。這由cp15暫存器c3(域訪問控制)、描述符的域(domain)、cp15暫存器c的r/s/a位、描述符ap位聯合決定。(等具體用到在詳細說明)
mmu進行位址對映涉及到兩種頁表,一級頁表(first level page table)和二級頁表(coarse page table)
「ttb base」代表一級頁表的位址,將它寫入協處理器cp15的暫存器c2即可。
使用mva[31:20]來索引一級頁表得到乙個描述符,一級頁表的描述符格式如下:
一級描述符的最低兩位,可以分為以下4種:
(1)[1:0]=00b:無效。
(2)[1:0]=01b:粗頁表(coarse page table)
位[31:10]稱為粗頁表基址(coarse page table address),此描述符的低10位填充0後就是乙個二級頁表的實體地址。
(3)[1:0]=10b:段(section)
位[31:20]稱為段基址(section base),此描述符的低20位填充0後就是一塊1mb實體地址空間的起始位址。mva[19:0]用來在這1mb空間中定址。所以,描述符的位[31:20]和mva[19:0]就構成了這個虛擬位址mva對應的實體地址。
轉化過程如下圖:
位[31:20]稱為細頁表基址(fine page table base address),此描述符的低12位填充0後就是乙個二級頁表的實體地址。
根據二級描述符的最低兩位,可分為以下4種情況:
(4.1)[1:0]=00b:無效
(4.2)[1:0]=01b:大頁描述符
位[31:16]稱為大頁基址(large page base addresss),大頁基址和mva[15:0]組成乙個32位的物理的位址,這就是mva對應的實體地址va。
轉化構成如圖:
(4.3)[1:0]=10b:小頁描述符
位[31:12]稱為小頁基址(small page base address),小頁基址和mva[11:0]組成乙個32位的實體地址,這就是mva對應的實體地址pa。
轉化過程跟大頁的比較相似故不做說明。
(4.4)[1:0]=11b:極小頁描述符
位[31:10]稱為極小頁基址(tiny page base address),小頁基址和mva[9:0]組成乙個32位的實體地址,這就是mva對應的實體地址pa。
轉化過程跟大頁的比較相似故不做說明。
1、任務分解
整個過程分為三個步驟:1.建立一級頁表
2.寫入ttb(把位址寫入cp15的c2暫存器中)
3.開啟mmu
下面是mmu段訪問方式的**
#define gpkcon (volatile unsigned long*)0xa0008000 /* gpkcon暫存器的位址 */
#define gpkdat (volatile unsigned long*)0xa0008808 /* gpkdat暫存器的位址 */
/**用於段描述符的一些巨集定義
*/#define mmu_full_access (3 << 10) /* 訪問許可權 */
#define mmu_domaln (0 << 5) /* 屬於哪一域 */
#define mmu_special (1 << 3) /* 必須是1 */
#define mmu_cacheable (1 << 2) /* cacheable */
#define mmu_bufferable (1 << 3) /* bufferable */
#define mmu_section (2) /* 表示這是段描述符 */
#define mmu_secdesc (mmu_full_access | mmu_domain | mmu_special | mmu_section)
#define mmu_secdesc_wb (mmu_full_access | mmu_domain | mmu_special | mmu_cacheable | mmu_bufferable | mmu_section)
void create_page_table(void)
}/*
*下面這個函式是mmu的初始化
*這裡就用到了c、彙編混合程式設計了
*/void mmu_init(void)
int main(void)
下面就對**一一分析:
unsigned long ttb = (unsigned long )0x50000000;
定義建表的的物理位置,就是ttb表在記憶體空間的起始位址。6410的記憶體的起始位址是0x50000000,2410的記憶體的起始位址是0x3000000.
*(ttb + (vaddr >> 20)) = (paddr & 0xfff00000) | mmu_secdesc;
這是把虛擬位址對應到實際的實體地址,(vaddr>>20)是表示取vaddr的[19:0]位其餘位補0,0xfff00000表示1m的段物理空間。mmu_secdesc是段空間的描述符。一會具體說明。
while(vaddr < 0x54000000)
總映**54mb的位址,54mb的是根據while(vaddr < 0x54000000) 可以得之的,因為段粒度是以1mb為單位的,所以每次迴圈vaddr += 0x100000;paddr += 0x100000; 0x100000換算後就是1mb的位址空間。mmu_secdesc_wb是段空間的描述符。
下面看看section descriptor:
具體每乙個的作用如下:
仔細看e文吧 我水平有限看的也不太懂,所以就不翻譯的。
注意:這些描述是在arm920t上描述的,我在arm1176jzfs上沒有找到,這樣應該是相同的。
/* 使能mmu */
"mrc p15, 0, r0, c1, c0, 0\n"
"orr r0, r0, #0x0001\n"
"mcr p15, 0, r0, c1, c0, 0\n"
第一句是讀出控制暫存器的值,把c1中的內容放入到r0中,如果通過設定r0的值,然後在把r0的內容放回到c1中,這樣就改變了c1的值了。
下面看看控制器低16位含義:
/* 控制暫存器的低16位含義為:. rvi . . rs b … . cam
* r:表示換出cache中的條目時使用的演算法,
* 0 = random replacement; 1 = round robin replacement
* v:表示異常向量表所在的位置,
* 0 = low addresses = 0x00000000; 1 = high addresses = 0xffff0000
* i : 0 = 關閉icaches; 1=開啟icaches
* r、s:用來與頁表中的描述符一起確定記憶體的訪問許可權
* b: 0 = cpu為小端模式; 1=cpu為大端模式
* c: 0 = 關閉dcaches; 1 = 開啟dcaches
* a: 0 = 資料訪問時不進行位址對齊檢查;1 = 資料訪問時進行位址對齊檢查
* m: 0 = 關閉mmu; 1 = 開啟mmu
*/ 到這裡就對mmu的使用跟配置就完成了,我介紹的也不是很全面具體可以檢視arm11核的手冊,全是e文啊,看著真費勁!
世界一下變大了 MMU 的使用
memory management unit 記憶體管理單元 有mmu單元是arm晶元和微控制器的重要區別之一。1 將虛擬位址轉化為實體地址 2 訪問許可權管理 當mmu關閉時,虛擬位址等於實體地址,但是當程式比較複雜時,必須使用mmu,程式中使用的都是虛擬位址。mmu的使用如下圖所示 2440 6...
讓我的大腦停一下!
今天呆在實驗室裡,什麼都沒乾,上午聽了一會兒英語,中午吃了飯也沒有回去,一直呆在這裡看電影。要說看呢,看了兩部吧。大學新生 和 雪狗兄弟 大學新生 講的是乙個剛進入大學的女生,為競選學生會主席所做的努力。另一部呢講的就是一群小可愛的黃毛狗不小心到了阿拉斯加後發生的一些事。狗狗太可愛了,讓我想起了我家...
算一下你來到這個世界多少天
a 案例演示 需求 算一下你來到這個世界多少天?將生日 和 當前時間儲存在string字串中 定義日期格式化物件 將日期字串轉換成日期物件 通過日期物件獲取時間毫秒值 將兩個時間值相減除以1000 在除以60 60 24 string date1 1993年12月19日 string date2 2...