mmu以及页表 UBOOT(1)

mmu的主要作用就是实现进程隔离

主要功能是

1 虚拟地址到物理地址的转换

访问某个进程1的虚拟地址A。mmu转换为物理地址B访问。

访问某个进程2的虚拟地址A。mmu转换为物理地址C的访问。

保证不同空间上的同一个虚拟地址访问映射到不同的物理内存。


2 内存权限控制的实现

在页表项中将某些不需要的bit项变成访问控制位,控制内存的访问。


在ARM中使用CP15协处理来控制MMU。

CR0 (有两个物理寄存器) 分别用于记录ARM的架构以及CACHE类型等等信息

CR1  控制寄存器,控制各种行为,包括开启关闭 MMU ,CACHE控制,控制异常向量的位置(0X0还是0XFFFF0000)

CR2  一级页表基地址

CR3 域的访问权限

...

....

以及其他CRx寄存器



UBOOT 部分:

下面的主要参考树莓派的BCM2835芯片,arm的架构是arm1176。

参考的手册是

arm1176jzfs.pdf   ARM手册

BCM2835-ARM-Peripherals.pdf 芯片手册

MMU提供4K 16K 1M 16M段管理


首先来看以1M作为映射。

每一个页表条目(4字节)代表的每一个页面是1M大小,为了表示4GB的空间,所以一共需要 4096MB/1MB * 4字节页表条目=4KB的大小。

也就是从page_table开始的4KB大小的内存每四个字节存放一个页表条目,一共4096项,每一项代表1MB的空间。如下图

(对于arm1176jzfs CP15的c1寄存器的bit23控制AP位,AP位开,地址转换兼容ARMV4 V5,AP关,地址转换采用ARMV6架构 )



具体的每个条目的每一项参看芯片手册比较好,这里只讲两个重要的。

[0:1] 表示当前条目的类型    00表示无效映射  10表示段页1M或者16M,具体是16M还是1M由第18bit控制

[2:3]表示缓冲缓存类型

[11:10] 表示当前页面的访问权限

[31:20] 表示这个条目映射的 物理空间的内存地址,因为条目是1M为单位,因此后20bit一定是0,恰好可以用来做一些标记位


用树莓派uboot初始化的时候页表操作来演示,如果开启MMU,则调用了

for (i = 0; i < 4096; i++)
set_section_dcache(i, DCACHE_OFF);

执行第一次的初始化


其中set_section_dcache函数如下

void set_section_dcache(int section, enum dcache_option option)
{

	u32 *page_table = (u32 *)gd->arch.tlb_addr;
	u32 value = TTB_SECT_AP;//0XC00

	/* Add the page offset */
	//#define MMU_SECTION_SHIFT  20
	value |= ((u32)section << MMU_SECTION_SHIFT);

	/* Add caching bits */
	value |= option;

	/* Set PTE */
	page_table[section] = value;
}

首先value=TTB_SEC_AP=0xC00

DCACHE_OFF =0x12=0b  1(4bit) 0(3bit) 0(2bit) 1(1bit) 0(0bit)

1:0bit 是 10 表示当前条目是段页
3:2bit是   00表示无缓存
4bit是向后兼容 最好为1

由于section是从0执行到4095的,并且option是0X12

所以执行完毕后,0-4095页表项 每个页表项就是
0XC00 | 0X12 | SECTION<<20



0x0000c12 0x0010c12 0x0020c12 0x0030c12 0x0040c12...... 0xFFE0c12 0xFFF0c12

一共4096项


设置完毕以后。又调用dram_bank_mmu_setup这次主要是将有效的内存设置为DCACHE_WRITEBACK

前面我们设置页表的时候,一共设置了4GB大小的内存空间,但是这其中很多是无效或者其他IO空间。

比如树莓派一共有512M内存,除去 64MB大小的GPU空间,那么剩下448MB的内存,因此将这448M空间设置为DCACHE_WRITEBACK。


随后直接开启了MMU,这样就进入了虚拟地址空间,因为物理地址和虚拟地址是一一对应的,因此不需要考虑代码重定位的问题。


对于1M段mmu 虚拟地址到物理地址的转换。
  1. 虚拟地址的[31:20]位存放一级页表的入口index[19:0]位存放段偏移;

  2. TTBRtranslation table base register,协处理器CP15中的一个寄存器,用于存放一级页表的基址)寄存器中获取一级页表的基址;

  3. 一级页表基址+ VA[31:20] = 该虚拟地址对应的页表描述符的入口地址;

  4. 页表描述符的[31:20]位为该虚拟地址对应的物理段基址;

  5. 物理段基址+ VA[19:0]段偏移物理地址


比如当前的虚拟地址是 0X123ABCDE。

1 那么0X123就是一级页表的索引 ABCDE就是段内的偏移

2  取得c2寄存器,一级页表的地址0XA0000000。

3 一级页表的地址0XA0000000+VA[31:20](0X123)=0XA0000123(物理地址)

4 0XA0000ABC物理地址中得到 关于该段的四字节描述 0X1230C12。 得到页表描述的[31:20]为0X123

5 物理段基地址+va[19:0]偏移 得到真实访问的物理地址 0X123+0XABCDEF得到最终的物理地址 0X123ABCDEF

实际上 虚拟地址和物理地址 是一样的。

那既然虚拟地址和物理地址是一样的,为什么又要开启MMU多此一举呢?我认为可能是为了使用DCACHE和ICACHE功能,这样能够加速UBOOT的启动和一些执行。


对于多级页表,道理是差不多的。


在UBOOT里面由于是一对一映射,所以就和访问物理地址是一样的。比如有一些IO地址,只需要直接访问就可以了。

所以UBOOT里面直接操作串口输出是没有问题的。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值