MMU配置与使用
1.通过点亮LED使用虚拟地址来使用MMU,采用段页映射方式
2.任务步骤:1.建立一级页表 2.写入TTB 3.打开MMU
代码编写
1.虚拟地址的段地址0xA0000000,一级页表的起始地址0x30000000(通常放在内存的起始地址),物理地址的段地址0x56000000
2.表项的位置等于一级页表的起始地址加上虚拟地址的高12位
3.表项的内容
Section base address:段基地址
SBZ:保持0
AP:访问权限,设置为11表示任意情况可读可写,在ARM核手册有相关描述
Domain:域,ARM处理器分为16个域,每个域的访问权限由AP和域中的R S共同决定
C:是否使用Cache
B:是否使用Write Buffer
4.CP15,C1寄存器的0位设置MMU,设置成1,表示使能MMU;C2寄存器设置TTB,设置成0x30000000,表示转换表的基地址为0x30000000;C3寄存器设置Domain,设置成0xFFFFFFFF,每个域都为0b11表示不检测权限
5.当MMU打开后,不管是访问内存的地址还是访问外设的地址都要经过MMU的转换。内存的虚拟地址采用与物理地址相同
6.MMU(存储管理单元)的作用是使大程序能分段在小内存中不同地方运行。在操作系统中,转换表通常由操作系统来维护,添加表项和控制页的换出和换出。页表本身访问的地址空间不会变大,但能把大程序分段通过虚拟地址来访问在,看起来内存变大了。通常在引导中是不需要打开的。
/******************************************************************** *名称:enable_mmu *功能:使能存储管理单元 *********************************************************************/ .global enable_mmu enable_mmu: //初始化转换表 ldr r0, =TTB ldr r1, =VADDR ldr r2, =PADDR loop_init_table: cmp r1, #EADDR //如果虚拟地址等于结束地址,那么结束循环 beq end_init_table //设置表项地址 mov r3, r1, lsr#20 //取出虚拟地址的高12位 mov r3, r3, lsl#2 //计算虚拟地址相对于基地址的偏移地址,地址4字节,左移2位相当于乘以4 add r3, r0, r3 //计算表项地址 //设置表项值 ldr r4, =0xFFF00000 and r4, r2, r4 //取出物理地址的高12位 ldr r5, =SECTION_FLAG orr r5, r4, r5 //设置转换表项 str r5, [r3] add r1, r1, #SECTION_SIZE add r2, r2, #SECTION_SIZE b loop_init_table end_init_table: //设置转换表基地址 ldr r0, =TTB mcr p15, 0, r0, c2, c0, 0 //设置访问域权限 mvn r0, #0 //设置访问域不检测权限 mcr p15, 0, r0, c3, c0, 0 //打开存储管理单元 mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0x00000001 //打开MMU,设置M[0]:1 mcr p15, 0, r0, c1, c0, 0 mov pc, lr
注意:在计算表项地址时,加的地址偏移要乘以4个字节,因为表项地址在转换表是32位