mmu是内存管理单元,负责虚拟地址到物理地址的映射和内存访问权限检查。本文只讲地址映射,地址映射长度有段1mb、大页64kb、小页4kb、极小页1kb,本文只讲段1mb的情况,其它类似。我们每个进程的空间都是4g,不同的进程的变量地址有可能一样,这就是虚拟地址,其实它们对应到物理地址是不一样的。这种虚拟地址到物理地址的转换就是mmu做的事。所以开启mmu之后,cpu发出的地址就是虚拟地址,关闭mmu,cpu发出的地址就是物理地址,关闭mmu的时刻,一般是boot阶段。
首先要建立一张映射表,按1m映射的话,4g共有4096个1m的段,每个需要4字节存储映射的地址,所以映射表的大小是4096*4字节(即16k),映射表的地址放在内存起始地址0x30000000。比如要把gpb的寄存器0x56000000映射到0xa0000000,0xa000000/1m=2560,所以在映射表的2560*4地址,存放0x56000000。然后把表格的首地址,即0x30000000告诉mmu,启动mmu即可。后面操作虚拟地址0xa0000000就是操作物理地址0x56000000。
unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
/*
* 0x56000000是gpio寄存器的起始物理地址,
* gpbcon和gpbdat这两个寄存器的物理地址0x56000010、0x56000014,
* 为了在第二部分程序中能以地址0xa0000010、0xa0000014来操作gpbcon、gpbdat,
* 把从0xa0000000开始的1m虚拟地址空间映射到从0x56000000开始的1m物理地址空间
*/
virtuladdr = 0xa0000000;
physicaladdr = 0x56000000;
*(mmu_tlb_base (virtuladdr >> 20)) = (physicaladdr & 0xfff00000) |
mmu_secdesc;
启动mmu的代码需要使用协处理器,需要了解arm核,暂不深入研究。
『本文转载自网络,九游会j9的版权归原作者所有,如有侵权请联系删除』