MMU笔记(一)

一、ARM中对于存储管理的协处理器CP15

CP15可以包含1632bit的寄存器,分别标记为015。但是对于同一个寄存器的物理寄存器可能会对应多个。

实际上对于CP15的访问的指令相当简单,只有MCRMRC。并且这两个指令的格式是相同的。

MCR/MRC{<cond>} p15, 0 ,<Rd>,<CRn>,<CRm>{<opcode_2>}

其中Rd ARM的寄存器,CRnCRm为协处理寄存器。CRn为主,而CRmopcode_2为辅助寄存器,主要区分同一编号的不同寄存器。如果不需要的情况下CRmC0,而opcode_20

 

其中c1寄存器的bit0为禁止或者使能MMU

如使能MMU

MRCP15,0,R0,C1,C0,0

ORR R0,#01

MCRP15,0,R0,C1,C0,0

二、MMU的地址变换

ARMTTB(Translation Table Base)中存储了段描述符的物理地址,它必须与16KB对齐,所以低14bit都是零。如下图所示


它将4GB的空间划分为4096X32bit的区域虚拟寻址。这种寻址方式又分为两个步骤进行,分别为一级页表查询和二级页表查询。

       下图为整个寻址方式的总框图:

 

 

从图中我们可以清楚的看到页表的查询分为直接的section base查询和基于二级页表的查询。下面将对这两种查询方式分别讨论和讲解。

基于section base的段基地址查询方式

       这种方式是MMU里面最为简单的,也是用的最多的一种查询方式,它没有二级页表,在虚拟到物理地址的转换过程中加载了一部分访问权限。

       CPU从CP15-C2寄存器中读取TTB地址之后,如上图所示,将通过virtual address[31:20]进行索引,这个索引所需要的地址当然也就是由这两部分合成的地址。具体的合成方法如下:

 

 

如图所示,最后的索引值(也就是所谓的地址转换条目地址)高16bit是由TTB的高16bit组成,而[13:2]virtual address的高12bit,剩下的[1:0]保持为0(实际如果你对ARM创建这些东西原因有所研究就不难发现这其实就是为了32bit对齐而准备的)。通过这个地址索引便可以找到我们需要的一级描述符,也就是我们框图中的TranslationTable

       而这个一级描述符可能存在几种格式,这几种格式又会代表不同的地址查询方法,如下图所示:

 

 

如果[1:0]00,则表示访问失效,这个时候MMU没有适用这个地址,当然软件就可以使用这块内存了。

如果[1:0]01,则表示这是二级页表粗颗粒方式(coarse pagetable

如果[1:0]10,则表示段组寻址(section base),是我们讨论的重点。

如果 [1:0] 11 ,则表示这是二级页表细颗粒方式( fine page table

基于二级页表的地址查询方式

       Coarsepage 索引了一个二级页表,这个页表描述查询是用大页,小页还是极小页。 

同样细颗粒所索引的二级页表也能包括大页,小页和极小页。但是它把1M空间分为10241KB。无论是粗颗粒还是细颗粒,都会在一级描述符中返回一个二级描述符,指向不同的控制页面。这些页面又会分为大页(large page),小页(small page)和极小页(tiny page)。具体是哪一种页面根据二级描述符的[1:0]定义,定义如下:

 

其中大页是64KB对齐,小页是4KB对齐,而极小页是1KB对齐的。对于粗颗粒只提供大页和小页对齐,而细颗粒可提供极小页对齐。

下面将是一个细页寻址的流程,从图中我们可以清楚的看到它的查询方式:


通过20位至31位寻址一级页表, 一级页表的12位至31位为二级页表的基地址,加上1911位为偏移就找到了物理基地址,物理基地址+剩下的作为页内偏移就是它的物理地址了。


创建页表

void create_page_table(void)

{

         //对我的GPIO进行映射

   unsigned long *ttb = (unsigned long *)0x20000000;//建立段描述符的基地址

   unsigned long vaddr, paddr; //虚拟地址,物理地址

 

   vaddr = 0xA0000000;

   paddr = 0xE0200000;

   *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC;

         //取虚拟地址高12位    将物理基地址取出         权限等的设置        

/***********************************************************/

//对我的内存进行映射     

   vaddr = 0x20000000;

   paddr = 0x20000000;

   while (vaddr < 0x24000000)

    {

       *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) |MMU_SECDESC_WB;

//使用MMU时通常打开Cache,Write buffer

       vaddr += 0x100000; //每一个表项只能映射1M

       paddr += 0x100000;

    }

}

Cache

用于将常用数据储存便于快速访问

Write buffer

用于内存区暂时无法写入数据时,将数据储存起来,在可以写入数据时,自行写入内存。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值