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; 
}

 

posted @ 2018-01-29 23:12  sanshijvshi  阅读(906)  评论(0编辑  收藏  举报