嵌入式单片机学习程序员

uboot step 11 内存一下子变大了 ----MMU的配

2016-08-12  本文已影响642人  2625K

uboot step 11 内存一下子变大了 ----MMU的配置与使用

本文结构如下:

在前面初始化的过程中,由于MMU与Cache会影响我们进行初始化的工作,因此关闭了MMU与Cache,在那篇文章中已经说过了MMU的作用,这里再重新说下:

首先还是先来简要说下相关与MMU相关的寄存器,先有个大概印象,后面用到了再去详细的看:


mmu3.png
名称 描述 简写
Translation Table Base Register 0 保存一级转换表的物理地址 TTBR0
Translation Table Base Register 1 保存一级转换表的物理地址 TTBR1
Translation Table Base Control Register 一级转换表控制相关 TTBCR
Domain Access Control Register 域访问权限控制
C1 Control Register MMU和cache使能

MMU使能

mmu enable.png

MMU 内存访问权限控制

MMU 页表描述

为了支持段和页的映射方式,MMU使用两级页表描述符,一级页表描述符决定访问的是一个分段还是一个分页式的表,如果访问的是一个分页式的页表,处理器MMU决定页表类型是大页还是小页并找到二级页表。

一级页表描述符地址

ARM1176 包含 两个转换表基地址寄存器TTBR0和TTBR1,一个转换表基地址控制寄存器,当一个TLB未命中时,虚拟地址最高位决定使用的基地址寄存器是哪一个,采用两个转换表基地址期望去减少OS上下文切换的花费,每个独立的任务或进程,有他自己的页表而不用消耗大量内存。整个虚拟内存空间被分为两个部分,用户空间和内核空间

 0x0 -> 1<<(32-N) that TTBR0 controls
  1<<(32-N) -> 4GB that TTBR1 controls.

N的值在TTBCR寄存器中进行设定,N的大小决定了内核空间和用户空间的分界线,当N=0时,表示只使用了TTBR0寄存器


N1.png
n2.png
一级页表描述符格式分析
mmu1.png

如上图所示:

二级页表描述符格式分析
mmu2.png

如上图所示,和一级页表描述符格式相似,相应的位的功能是一样的。不同的是最后两位代表了两种不同的分页类型。

虚拟地址到物理地址的转化

MMU对于刚接触的人可能会感觉到有些不知所措,因为它有那么多相关的寄存器,还有什么TLB,一级页表,二级页表,粗细粒度,等等,完全一个大写的懵,认为MMU的使用是个很难的过程,当你从了解地址转化流程开始入手学习,慢慢了解了之后,便会觉得其实还是蛮简单的,下面来看下S3c6410中MMU的地址转化流程:

下面分四种情况对映射转化过程作下说明:

1M分段式映射
1M.png
16M分段映射
16M.png

与1M的段映射相似,只是有些地址线的范围发生了改变,另外一级描述符的第18位为1表示16M的段映射,0表示1M段映射

64KB分页映射
64KB.png
4KB分页映射
4kb.png

代码实现-控制led

#define GPKCON (volatile unsigned long*)0xA0008800
#define GPKDAT (volatile unsigned long*)0xA0008808


/* 
* 用于段描述符的一些宏定义
 */ 
#define MMU_FULL_ACCESS     (3 << 10)   // 访问权限  AP
#define MMU_DOMAIN          (0 << 5)    // 属于哪个域 Domain
#define MMU_SPECIAL         (1 << 4)    // 必须是1  XN 
#define MMU_CACHEABLE       (1 << 3)    // cacheable C
#define MMU_BUFFERABLE      (1 << 2)    // bufferable B
#define MMU_SECTION         (2)         // 表示这是段描述符 10
#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)
{
    unsigned long *ttb = (unsigned long *)0x50000000;
    unsigned long vaddr, paddr;

    vaddr = 0xA0000000;
    paddr = 0x7f000000;
    *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC;  //将虚拟地址A000映射到led所对应的物理地址区间

    vaddr = 0x50000000;
    paddr = 0x50000000;
    while (vaddr < 0x54000000)//64M的区间地址虚拟地址与物理地址映射相同, 或者说相当于没有进行地址转化
    {
        *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC_WB;
        vaddr += 0x100000;
        paddr += 0x100000;
    }

}


void mmu_init()
{
   __asm__(
    
    /*设置TTB Base addr*/
    "ldr    r0, =0x50000000\n"                  
    "mcr    p15, 0, r0, c2, c0, 0\n"    
    
    /*不进行权限检查 Domain*/
    "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, c1, c0, 0\n"    
    : 
    : 
  );
}


int main()
{
    create_page_table();
    mmu_init();

    *(GPKCON) = 0x11110000;
    *(GPKDAT) = 0xa0;

    return 0;    
}

此去经年
zhaiyk@sina.cn
August 10, 2016

上一篇 下一篇

猜你喜欢

热点阅读