OK6410MMU内存管理单元

在介绍MMU之前先来个小插曲,为MMU的初始化做一个铺垫:

在之前驱动LED的程序中,启动代码里有一句话:


这句话不知道大家有没有注意到,那么这句话作用是什么呢:


这是ARM11的手册里规定的,通过这句话,进行外围端口的映射。所以说,每一句程序都不是空穴来风,一定是从芯片手册得到的!(一句很重要的废话)


接下来就是“硬菜”了,在我看来这部分内容是繁琐的,先来看看芯片手册对MMU的内容分为哪些内容:


当然,我只会选一部分内容,把我的理解写下来,如果以上内容都想了解到的话,还是要自己看芯片手册,我想要分享的内容包括以下几个部分:


一、MMU概述

MMU的作用,主要有俩点:

1.将虚拟地址转化为物理地址

2.设置内存的访问权限

虚拟地址到物理地址的转换的意义在于:

a.CPU看到的连续地址,在物理内存不一定是连续的,可以提高内存的利用率


如上图,已经没有足够的整块的物理内存存放C,但是通过虚拟内存,可以让CPU看到连着的地址,但是物理内存插空存放。

b.为各进程分配的内存之和可能会大于实际可用的物理内存,虚拟内存管理使得这种情况下各进程仍然能够正常运行,因为为进程分配的是虚拟内存,可以将虚拟内存零时存到磁盘上,调用进程的时候,再将页面换入到物理内存。


设置内存访问权限可以保护进程安全的执行,比如可以设置进程的代码段只读,普通程序不能访问系统内存等等,保护进程的安全(PS:所以在Linux里会设定进程间通信)


二、内存访问权限的设定

如下图,S3C6410有16个域,CP15寄存器C3中每俩位对对应的域进行访问权限的设定:


00: 无访问权限,任何访问都会导致异常

01:访问时进行权限检查

11:保留

11:不做权限检查

在段描述符中的Domain就是用来选择要访问的域,4位刚好对应16个域


Domain用来确定访问哪一块,APX和AP决定如何进行怎样的访问



三、内存映射

1.由图中可以清楚的看到,4种方式,大段、小段、大页、小页



如何映射是从描述符的后俩位确定的



这点从第一张图也可以看出来,这里就不细说了

2.这张是选择TTB,具体使用哪个,看第二张图,通过设定N的值,可以区分使用TTB0还是TTB1,使用俩个TTB的好处在于,可以通过俩个TTB区分特权模式和用户模式



3.这张图,对照描述符后俩位,就可以知道这个是1级1M段映射,这个不详细说,会把重点放在2级4K页,因为4K是最常用的


4.我们重点看一下这张图,流程是a.得到Translation base取31~14位+虚拟地址31~20位得到一级描述符地址

b.由一级描述符描述符地址,得到一级描述符

c.由一级描述符最后俩位可以看出,是俩级描述

d.一级描述符31~10位+虚拟地址19~12位得到二级描述符地址

e.由二级描述符地址得到二级描述符

f.由二级描述符最后俩位可以得到页大小为4K

g.二级描述符31~12位+虚拟地址11~0位(偏移),得到最后的物理地址



四、TLB和Cache

TLB用来存放近期用到的页表条目,避免每次转换都要从主存中查找

Cache用来存放正在执行的指令附近的指令,供CPU使用

TLB和Cache都是用来提高运行速度的。


五、使能MMU

1.编程所有相关的CP15寄存器正确的值

2.编程建立所要求的一级页表,二级页表

3.关闭I-cache

4.使能MMU


六、程序代码

启动代码startup.s:

mmu_init:
	mov r0, #0		;关掉指令和数据缓存
	mcr p15,0,r0,c7,c7,0	
	mcr p15,0,r0,c7,c10,4	;清空写缓存
	mcr p15,0,r0,c8,c7,0	

	mov r4,#0x51000000	;映射表存放地址
	mcr p15,0,r4,c2,c0,0	;设置页表基址寄存器

	mrc p15,0,r0,c3,c0,0	;设置访问权限
	orr r0,r0,#3
	mcr p15,0,r0,c3,c0,0

	mrc p15,0,r0,c1,c0,0	
	orr r0,r0,#0x0001	;使能MMU
	mcr p15,0,r0,c1,co,0	

	mov pc,lr

mmu.c

#define MMU_BASE 0x51000000
#define MMU_FULL_ACCESS     (3 << 10)   // 访问权限  AP

#define MMU_DOMAIN          (0 << 5)    // 属于哪个域 Domain

#define MMU_SPECIAL         (1 << 4)    // 必须是1  XN 

#define MMU_CACHEABLE       (1 << 3)    // cacheable C

#define MMU_BUFFERABLE      (1 << 2)    // bufferable B

#define MMU_SECTION         (2)         // 表示这是段描述符 10

#define MMU_SECDESC_NCNB        (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)

#define MMU_SECDESC_WB      (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)



void create_page_table(void)

{
    
    volatile unsigned long *table=(volatile unsigned long *)MMU_BASE;
    table[0] = 0|MMU_SECDESC_WB;			//虚拟地址0映射到物理地址0
    table[0x100] = 0x7f000000|MMU_SECDESC_NCNB;		//虚拟地址0x10000000映射到物理地址0x7f000000
    table[0xc00] = 0x50000000|MMU_SECDESC_WB;		//虚拟地址0xc0000000映射到物理地址0x50000000
    table[0xc02] = 0x50200000|MMU_SECDESC_WB;		//虚拟地址0xc0200000映射到物理地址0x50200000
}


以上内容如果有什么错误或者不合适的地方,欢迎指正,想知根知底推荐自己看芯片手册。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值