微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 关于ARM9的MMU重要理解

关于ARM9的MMU重要理解

时间:11-28 来源:互联网 点击:
MMU给我感觉是个很复杂的东西,网上看了一些资料,勉强知道了一些表面的东西。它有两个作用:1、把虚拟地址映射到物理地址;2、对内存访问提供控制机制。

原文地址:

http://blog.chinaunix.net/u1/58780/showart_468065.html

在ARM中,MMU另外提供了一张映射表(MVA),用于程序虚拟地址(VA)到物理地址(PA)的映射。MVA称为变换后的VA。在程序运行时,CPU只看到VA,而MMU和cache们只看到PA和MVA。应该说,在进程运行切换过程中,映射关系是动态变化的,因为不同进程和内存之间需要不同的映射关系,就需要不断的重做映射表,这个代价是很大的。所以,有必要让映射表中需要更新的内容很少,以减少性能开支,这就出现了“变换后的”VA,即MVA,如果VA<32M,需要使用进程标识号PID(通过读CP15的C13获得)来转换为MVA。

VA与MVA的转换方法如下(这是硬件自动完成的):

if(VA32M)
MVA=VA|(PID<25);//VA<32M,即PID*0x02000000作为该进程起始地址
else
MVA=VA;//VA>=32M

如:假设两个进程1、2运行时的VA都是0-32M,则他们的MVA分别是0x02000000-0x03ffffff、0x04000000-0x05ffffff,这样进程切换就省事多了,不必进行重建页表等工作。

但 是,这同时带来了中断跳转的问题。当发生异常时,需要跳到0x0位置的异常向量表,这个0x0应该是VA,且小于32M,如果开启了MMU,就会被转换为 MVA,而不同的PID产生不同的MVA,这就导致异常向量表的地址不统一了。所以,Linux采取了将0x0位置的向量表映射到高地址 0xffff0000处,就没有上述的问题了,看了半天原来是这么回事。。。

因为,在32位的CPU系统上,虚拟地址空间为2^32 = 4G
而VA和MVA的转换公式为:
if(VA < 32M) then
MVA = VA | PID < 25;
else
MVA = VA;
这样,只要每个进程的VA都在32M之内,就可以保证每个进程的MVA不会发生重叠。
2^25 = 32M。另外,可以计算出进程最多为2^(32-25) = 128个

如果说这个是规定来的,你信不信?呵呵如果是64M的话,那么公式就要改成MVA = VA | PID < 26;
那么PID就只有6位了,linux操作系统能够支持的进程最多只有2^6=64个了,这样不划算

B指令的的机器代码结构为
31 2827 26 25 24 230
cond101Lsigned_imed
若L为0则为直接跳转B,若L为1则为连接跳转BL,signed_imed为24位有符号立即数,这个值为跳转的偏移量。
24位有符号数值的范围是-8M ~ +8M,而指令中偏移量为1时代表从当前PC开始向下跳1个字,即偏移量的单位为4个字节
因此,B指令向前和向后寻址的最大范围为32M

你可以试下如下代码:
BNEXT
NEXT
NOP
NOP
看一下那条跳转指令它的机器代码,最低24位立即数的值应该是-1
跟字对齐有点关系,因为ARM指令集的指令都是四字节的,所以偏移量的单位是4个字节。
如果当前跳转的偏移量为-1,那么PC会向前跳4个字节,如果偏移量为-8M,那么PC会向前跳-32M个字节


恩,最低24位是0xffffff,偏移量就是 -1

BNEXT
NOP
NOP
NEXT
NOP
B跳转是针对当前PC来计算的,而当前PC值等于当前正在执行指令的下下一条指令的地址值
向下跳,偏移量为正数,向上跳,偏移量为负数。这个上下方向是针对程序执行的方向来说的。


恩,是这样的


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top