首页 > 代码库 > 第三十五天:Tiny4412驱动开发之配置MMU

第三十五天:Tiny4412驱动开发之配置MMU

    MMU表示内存管理单元,负责虚拟内存映射到物理内存。

   虚拟地址映射到物理地址的关键是构建映射表。MMU就是利用映射表格将虚拟地址转换成物理地址。虚拟地址在32系统中为4G,地址占4字节,如果映射表格中虚拟地址和物理地址是一一对应的关系,一条记录就占8字节,那么映射表就要32G.这明显是不合理的。

   于是通过二级映射解决这个问题。地址共32位,把前12位作为基地址,后20位作为偏移量,将虚拟地址和物理地址作为的前12位一一对应,12位就是2的12次方为4k。 一条记录8字节,那么映射表格就只有32k,
  下图左边为虚拟地址,右边为物理地址。比如有个虚拟地址为0x00123456,基地址为001 偏移量为23456.先通过映射表找到对于的物理地址为0x60100000,然后加上偏移量就是实际的地址0x60123456。

0x001000000x60100000
0x002000000x60200000
0x003000000x60300000
0x004000000x60400000

在tiny4412中,内存映射表更加的简单。把因为表格也是存放在内存中的,内存也有地址。那么就把内存利用起来。看下图:

  

 0x70000000就表示映射表存储的位置,映射表格的内容就只有物理地址。虚拟地址就在表格的地址中体现。这样的话,内存映射表又缩减了一半,4G的虚拟地址只要16k的表格就能全部映射。

  先看Tiny4412的内存表:

 

从表中可以知道0x30000000地址是没有内容的。现在要开启MMU,将0x30000000内存映射到0x50000000地址去,如果能够访问到0x3000000,就表示映射成功。代码如下:

 1 int (*printf)(char *, ...) = 0xc3e114d8; 2  3 void init_ttb(unsigned long *ttb); 4  5 int main() 6 { 7     //0x32300000 -> 0x52300000; 8     unsigned long *pp = 0x52300000; 9     *pp = 0x22222222;10     printf("*pp is %x\n", *pp);11     //step 1: set mmu table12     unsigned long ttb = 0x70000000;13     init_ttb(ttb);14     //step 2: enable mmu table15     unsigned long mmu = 0;16     mmu = 1 | (1 << 3) | (1 << 8);17     __asm__ __volatile__(//开启mmu必须用汇编实现18         "mov r0, #3\n"19         "mcr p15, 0, r0, c3, c0, 0\n" //manager20         "mcr p15, 0, %0, c2, c0, 0\n" //ttb address21         "mcr p15, 0, %1, c1, c0, 0\n" //enable mmu22         :23         : "r" (ttb), "r" (mmu)24     );25 26     unsigned long *pv = 0x32300000;27     printf("*pv is %x\n", *pv);28 }29 30 void init_ttb(unsigned long *ttb)31 {32     unsigned long va = 0;33     unsigned long pa = 0;34     //0x00000000 ~0x14000000  -> 0x00000000 ~0x14000000 35     for(va=0x00000000; va<0x14000000; va+=0x100000){36         pa = va;37         ttb[va >> 20] = pa | 2;38     }39 40     //0x40000000 ~0x80000000  -> 0x40000000 ~0x80000000 41     for(va=0x40000000; va<0x80000000; va+=0x100000){42         pa = va;43         ttb[va >> 20] = pa | 2;44     }45     //0x30000000 ~0x40000000  -> 0x50000000 ~0x60000000 46     for(va=0x30000000; va<0x40000000; va+=0x100000){47         pa = va + 0x20000000;48         ttb[va >> 20] = pa | 2;49     }50 }

 

  

  可以访问0x32300000的内容,说明MMU开启成功。

  下面是关于汇编代码中开启MMU的介绍。先是在ARM开发手册中查找关于MMU控制的相关信息,下图是MMU配置的内容

上面代码16行就是MMU的配置,将第一位置1表示 开启MMU,第三位置一表示开启写缓存。

未完待续。。。(等水平提升了在继续写,剩下的汇编代码实在看不懂)

 

第三十五天:Tiny4412驱动开发之配置MMU