MMU功能解析、深入剖析、配置与使用

时间:2023-03-10 04:05:11
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 >> )) = ((paddr & 0xfff00000)|SECDESC); vaddr = 0x30000000;
paddr = 0x30000000; while(vaddr += 0x34000000)
{
*(ttb + (vaddr >> )) = ((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 ;
}