上一篇介绍了MMU的由来与作用,现在我们以JZ2440v2开发板为例做一个MMU的虚拟地址映射实验。
一、有MMU参与的寻址过程简介
首先需要了解3个总线地址概念:虚拟地址(VA,Virtual Address)、转换后的虚拟地址(MVA,Modified Virtual Address)、物理地址(PA,Physical Address)。
JZ2440v2使用2片16bit位宽、32MB容量的SDRAM组合成“一片”32bit位宽、64MB容量的内存来使用,之所以说成是一片,是因为CPU只把它们当成一个整体,即单片32bit位宽、64MB容量的SDRAM,前文也介绍过。
JZ2440v2将这2片内存接在存储管理器的BANK6和BANK7上,所以,对于64MB内存,它占用物理总线地址0x30000000~0x33FFFFFF,为什么是这个值,请参见[ARM嵌入式]三、S3C2440A的存储控制器及启动过程。
除了存储控制器占用的物理总线地址0x000000000~x40000000以外,0x48000000~0x5FFFFFFF这段地址被各个寄存器使用,此外,使用Nand Flash启动时,片内SRAM占用0x400000000~x48000000这段物理总线地址,其余的物理总线地址均未被使用。
关于存储控制器和内存管理单元的差别:存储控制器用于直接操控外设,它能根据总线地址在相应的外设上寻址和读写数据,它只使用物理地址PA;而内存管理单元的作用,仅仅是转换虚拟地址和物理地址以及权限控制,不参与外设操控,实际上还是要将转换好的物理地址PA传递给存储控制器。
作为CPU核,它根本不关心到底接了什么外设,它只管把指令和地址应该扔给谁去处理,在没有启动MMU时,CPU使用物理地址PA,将相应的的物理地址PA交给存储控制器;启动MMU之后,CPU使用虚拟地址VA,在硬件上会自动转换成MVA交给MMU,MMU经过一系列处理转换成PA,然后根据权限,让存储控制器去操作。
小小提示一下,CPU一上电,默认从0x00000000处开始执行指令,执行完第一条就会按顺序执行下一条指令,CPU可不管到底是VA还是PA,所以关于VA和PA,其实还是由程序员在编写程序就固定在指令里面的。
关于转换后的虚拟地址(MVA,Modified Virtual Address),它是由硬件自动完成的,其转换关系类似于以下代码:
if(VA<32M) Then
MVA = VA | (PID<<25)
else
MVA = VA
PID是进程编号,涉及到操作系统进程管理,不做太多说明,在学Linux时会学到,一般情况下,说到的都是MVA,MVA的作用是供cache和MMU使用,在MMU中被转换为PA。
在MMU启动后,对于转换过程,主要有以下几个特点:
(1)、CPU核看到的、用到的只是虚拟地址VA。
(2)、VA在MMU处理之前就已经转换成MVA了,它是通过硬件自动完成的。
(3)、caches和MMU是看不到VA的,它们直接利用MVA转换得到PA。
(4)、实际设备看不到VA和MVA,读写它们时使用的是物理地址PA。
二、段映射的寻址过程
段映射比较简单,本实验也是以段映射为目标进行研究。
前文曾介绍过段映射,段映射将虚拟空间划分成4096个单元,每个单元占用1MB,每个虚拟空间单元对应物理空间的一个单元,同样也是1MB。
段描述符的作用就是用来建立这种对应关系,它与虚拟空间的顺序一一对应,每个描述符占用4Byte,4096个描述符占用16KB。
请看以下两图: