1.MMU功能
将虚拟地址转化为物理地址;
访问权限管理。
2.地址转化
2.1 总体分析
2.2 一级转换格式
位解释:(段设置)
B:表示是否使能write buffer;
C: 表示是否开启cache;
XN(The Execute-Never ):determines if the region is Executable (0) or Not-executable(1)。
Domain:the ARM1176JZF-S supports 16 Domains in the Secure world and 16 Domains in the Non-secure world. Domains provide support for multi-user operating systems.
P:If the P bit is supported and set for the memory region, it indicates to the system memory controller that this memory region has ECC enabled. ARM1176JZF-S processors do not support the P bit. (设为0)
AP:访问权限
APX:provides an extra access permission bit.
TEX:remap bit
S:determines if the translation is for Non-Shared (0), or Shared (1)memory.
nG:determines if the translation is marked as global (0), or process-specific (1) in the TLB.
NS:The Non-secure (NS) bit determines if the program execution is in the Secure or Non-secure world.
3.MMU配置与使用
3.1 建立一级页表
1 void create_page_table(void) 2 { 3 unsigned long *ttb = (unsigned long *)0x50000000; 4 unsigned long vaddr, paddr; 5 6 vaddr = 0xA0000000; 7 paddr = 0x7f000000; 8 *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC; 9 10 vaddr = 0x50000000; 11 paddr = 0x50000000; 12 while (vaddr < 0x54000000) 13 { 14 *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC_WB; 15 vaddr += 0x100000; 16 paddr += 0x100000; 17 } 18 19 }
3.2 初始化MMU
1 void mmu_init() 2 { 3 __asm__( 4 5 /*设置TTB*/ 6 "ldr r0, =0x50000000 " 7 "mcr p15, 0, r0, c2, c0, 0 " 8 9 /*不进行权限检查*/ 10 "mvn r0, #0 " 11 "mcr p15, 0, r0, c3, c0, 0 " 12 13 14 /*使能MMU*/ 15 "mrc p15, 0, r0, c1, c0, 0 " 16 "orr r0, r0, #0x0001 " 17 "mcr p15, 0, r0, c1, c0, 0 " 18 : 19 : 20 ); 21 }
3.3 主函数
#define GPKCON (volatile unsigned long*)0xA0008800 #define GPKDAT (volatile unsigned long*)0xA0008808 /* * 用于段描述符的一些宏定义 */ #define MMU_FULL_ACCESS (3 << 10) /* 访问权限 */ #define MMU_DOMAIN (0 << 5) /* 属于哪个域 */ #define MMU_SPECIAL (1 << 4) /* 必须是1 */ #define MMU_CACHEABLE (1 << 3) /* cacheable */ #define MMU_BUFFERABLE (1 << 2) /* 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) int main() { create_page_table(); mmu_init(); *(GPKCON) = 0x11110000; *(GPKDAT) = 0xa0; return 0; }