您的位置:首页 > 其它

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

2016-06-09 14:23 337 查看
  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 table
12     unsigned long ttb = 0x70000000;
13     init_ttb(ttb);
14     //step 2: enable mmu table
15     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" //manager
20         "mcr p15, 0, %0, c2, c0, 0\n" //ttb address
21         "mcr p15, 0, %1, c1, c0, 0\n" //enable mmu
22         :
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,第三位置一表示开启写缓存。

未完待续。。。(等水平提升了在继续写,剩下的汇编代码实在看不懂)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: