MMU功能解析、深入剖析、配置与使用
MMU = memory management unit
1、把虚拟地址转化成物理地址,防止地址冲突
2、访问权限管理
MMU把一个虚拟地址的20位到31位作为取出来,建立
一张表,叫做translation table base,也叫做一级页表
索引,根据每个地址的最后两位进行分类,在进行段式
转换、粗叶地址转换和细叶地址转换。
段式转换是将最后两位是10的虚拟地址的高12位作为基
地址,剩余20位作为偏移地址
细叶地址转换是将最后两位是11的虚拟地址的高12位作为
一级页表,第10到第19位作为二级页表,0到11位作为偏移
地址。
#define GPBCON (volatile unsigned long *)0xA0000010 #define GPBDAT (volatile unsigned long *)0xA0000014 #define MMU_FULL_ACCESS (3<<10) // 访问权限 #define MMU_DOMAIN (0<<5) // 属于哪个域 #define MMU_SPECIAL (1<<4) // 必须是1 #define MMU_CACHEENABLE (1<<3) // cacheable #define MMU_BUFFERABLE (1<<2) // bufferable #define MMU_SECTION (2<<0) // 表示这是段描述符 #define SECDESC (MMU_SECTION|MMU_SPECIAL|MMU_SPECIAL|MMU_FULL_ACCESS) #define SECDESC_WB (MMU_SECTION|MMU_SPECIAL|MMU_SPECIAL|MMU_FULL_ACCESS|MMU_CACHEENABLE|MMU_BUFFERABLE) void creat_page_table() { unsigned long *ttb = (unsigned long *)0x30000000; unsigned long vaddr,paddr; vaddr = 0xA0000000; paddr = 0x56000000; *(ttb + (vaddr >> 20)) = ((paddr & 0xfff00000)|SECDESC); vaddr = 0x30000000; paddr = 0x30000000; while(vaddr += 0x34000000) { *(ttb + (vaddr >> 20)) = ((paddr & 0xfff00000)|SECDESC); vaddr += 0x10000; paddr += 0x10000; } } void mmu_init() { __asm__( //设置TTB "ldr r0, =0x3000000\n" "mcr p15,0,r0,c2,c0,0\n" //不进行权限检查 "mvn r0,#0\n" "mcr p15,0,r0,c3,c0,0\n" //使能MMU "mrc p15,0,r0,c1,c0,0\n" "orr r0,r0,#0x0001\n" "mcr p15,0,r0,c0,c1,0\n" : : ); } int gboot_main() { creat_page_table(); mmu_init(); *(GPBCON) = 0x15400; *(GPBDAT) = 0x0; return 0; }