[国嵌攻略][048][MMU配置与使用]

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位

原文地址:https://www.cnblogs.com/d442130165/p/4935162.html