您的位置:首页 > 其它

arm mmu源码分析

2015-07-30 08:33 239 查看
arm7以上带有mmu模块,这个模块可以进行单位大小的地址的重新映射,这是扩展地址空间,增加代码灵活性的一个模块。以下是一个源码

void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)

{

unsigned int i;
unsigned int reg;
unsigned int low,high,ram;
low = (0xa1000000 - 0xa0000000)>>20;
high = (0xfffffffff - 0xa1000000)>>20;
ram  = (0x20000000 -0x10000000)>>20;

for(i=0;i<low;i++){
reg = 0x10000000 +(i<<20);
reg +=   0xc12;
*(int *)(0xa1000000 +i*4) =reg;
}

for(i=0;i<ram;i++){
reg = 0x10000000 +(i<<20);
reg +=   0xc12;
*(int *)(0xa1000000+(0x10000000>>20)*4 +i*4) =reg;
}

for(i=0;i<high;i++){
reg = 0xa0000000+(i<<20);
reg +=   0xc12;
*(int *)(0xa1000000 + (0xa0000000>>20)*4 +i*4) =reg;
}

mmu_setttbase((UINT32)0xa1000000);

mmu_enable();


}

开始阶段我们要建立一张地址的映射表,这个表供cpu在拿到代码的地址访问请求是进行地址的寻址,在这个表里拿到的地址才是真正的物理地址。而我们代码给cpu的请求地址现在已经变成虚拟地址,他必须经过mmu进行一次转换。这样我们就可以做到多个虚拟地址对应一个物理地址,一块共享内存也就可以硬件实现了。这张表应该是长这个样子的

00000c12 00100c12 00200c12 00300c12…..

这里可以看出这是个一级页表的映射,他的单位是1m地址映射。

0 ———-》0000

1m ———->1M

这里就是一个原地址的映射关系

如果是

00100c12 在这张表的0地址

就是 0——–》1M 零地址对应了0x100000的地址了,这时候我们访问0地址 其实会获得0x1OOOOO地址的N内容。

void mmu_setttbase(register rt_uint32_t i)

{

register rt_uint32_t value;

value = 0;
asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value));

value = 0x55555555;
asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i));


}

这里完成了整张表的初始化之后就要将这张表的首地址告诉给cpu了,也就是上面的协处理器的汇编代码了。这个想知道具体意义可以去查arm官方的文档。

有个问题需要注意:这张表的地址不能够映射到其他地方,一定是给协处理器的地址,不然连cpu都找不到这张表,你的地址也就无法查到了。

最后就是开启这个mmu了 ,通知cpu不要直接发送地址而要去mmu进行转换了,

void mmu_enable()

{

register rt_uint32_t i;

/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));

i |= 0x1;

/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));


}

这里也是协处理器的汇编也就设置了一个bit。

后面进行cache相关。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  arm