1.MMU简介
MMU负责完成虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。现代的多用户多进程操作系统通过MMU使得各个用户进程都拥有自己独立的地址空间:地址映射功能使得各个进程拥有"看起来"一样的地址空间,而内存访问权限的检查可以保护每个进程所使用的内存不会被其他进程所破坏。MMU增加了底层的复杂性,但是为上层程序开发提供了极大的方便。
2.虚拟地址与物理地址
虚拟地址最终需要转换为物理地址才能读写实际的数据,这通过将虚拟地址空间、物理地址空间划分为同样大小的一块块空间(称为段或页),然后为这两类小空间建立映射关系来实现。由于虚拟地址空间远大于物理地址空间,有可能多块虚拟地址空间映射到同一物理地址空间,或者有些虚拟地址空间没有映射到具体的物理地址空间(在使用到时再映射)。
ARM CPU上的地址转换过程涉及到3个概念:虚拟地址(VA)、变换后的虚拟地址(MVA)和物理地址(PA)。当没有启动MMU时,CPU核、cache、MMU、外设等所有部件使用的都是物理地址。启动MMU之后,CPU核对外发出虚拟地址VA;VA被转换为MVA供cache和MMU使用,cache和MMU完成MVA到PA的转换;最后使用PA读写具体的实际设备。
(1)CPU核看到的、用到的只是VA(启动MMU之后),VA到PA的转换对于CPU核来说是透明的。
(2)cache和MMU是看不见VA的。
(3)实际设备看不到VA和MVA。
注:MVA是除CPU核外的其他部分看见的虚拟地址。
3.VA和MVA之间的转换
之所以要设置一级VA和MVA之间的转换,是为了提高系统运行的效率。在2440中,VA和MVA之间的转换关系为:如果VA<32M,需要使用进程标识号PID(通过读CP15的C13获得)来转换为MVA,VA与MVA的转换方法如下(由硬件自动完成):
if(VA < 32M) then
MVA = VA | (PID << 25);
else
MVA = VA;
利用PID生成MVA的目的是为了减少切换进程时的代价:不使用MVA而直接使用VA的话,当两个进程的虚拟地址空间VA重叠时(因为对于每个上层应用来说都是拥有独立的4G空间,所以对于VA的使用一般都是从小地址往大地址占用),在切换进程时为了把重叠的VA映射到不同的PA上去,需要重建页表、使无效cache和TLBS等,代价极大。
而使用了MVA之后,切换进程将会简化许多。操作系统中一般小于32M的小进程居多,而真正的大进程反而较少,假设现在有20个小于32M的小进程,有5个超过32M的大进程,那么一共拥有25个不同的PID,这20个小进程会被映射到不同的MVA(因为其均未超过32M),而这5个大进程的低32M的VA也会被映射到不同的MVA,超过的部分会使用到重建页表等来完成映射。
MVA将4G的内存分为2^7=128个32M的空间(PID<<25),如果这128个进程使用的VA都是0~32M之间,则他们的地址都不会重叠,这样在进程切换时付出的代价是极小的。
4.VA到PA的转换过程
将一个虚拟地址转换为物理地址一般有两种方法:第一,使用一个数学公式进行转换;第二,用表格存储虚拟地址对应的物理地址。这类表格被称为页表,页表由一个个条目组成,每个条目存储了一段虚拟地址对应的物理地址及其访问权限,或下一级页表的地址。ARM中使用的是页表方法。
2440最多会用到两级页表:以段(1M)的方式进行转换时只用到一级页表,以页的方式进行转换时用到两级页表。页的大小有三种:大页(64KB)、小页(4KB)和极小页(1KB)。
大概的转换过程如下:
(1)根据给定的VA找到一级页表中的条目;
(2)如果此条目是段描述符,则返回物理地址,转换结束;
(3)如果此条目是二级页表描述符,继续利用虚拟地址在此二级页表中找到下一个条目;
(4)如果第二个条目是页描述符,则返回物理地址,转换结束;
(5)其他情况出错。
32位的CPU的虚拟地址空间达到4GB,一级页表中使用4096个描述符来表示这4GB空间——每个描述符对应1MB的虚拟地址,要么存储了它对应的1MB物理空间的起始地址,要么存入了下一级页表的地址。MMU根据MVA的[31:20]一共12位来得到这4096个描述符中的一个,每个描述符占用4B,所以一级页表占用了4KB。
根据一级描述符的最低两位,可以分为四种情况。
(1)0b00:无效。
(2)0b01:粗页表。
位[31:10]称为粗页表基址,此描述符的低10位填充0后就是一个二级页表的物理地址。此二级页表含有256个条目(10个bit表示,粗页表占用空间为1KB),粗页表中的每个条目代表4KB的物理地址空间,所以256*4KB=1MB的空间。
(3)0b10:段。
位[31:20]称为段基址,此描述符的低20位填充0之后就是一块1MB物理地址空间的起始地址。MVA[19:0]用于在这1MB空间中寻址。所以描述符的位[31:20]和MVA[19:0]就构成了这个虚拟地址MVA最终对应的PA。
(4)0b11:细页表。
位[31:12]称为细页表基址,此描述符的低12位填充0之后就是一个二级页表的物理地址。此二级页表含1024个条目(每个条目4B,一共占用4KB),其中每个条目代表1KB的物理地址空间,1024*1KB=1MB。
以大页(64K)、小页(4K)或极小页(1K)进行地址映射时,需要用到两级页表。二级页表分为上述的粗页表和细页表两种,根据二级描述符的最低两位,可以分为以下四种情况。
(1)0b00:无效。
(2)0b01:大页描述符。
位[31:16]称为大页基址,此描述符的低16位填充0后就是一块64KB物理地址空间的起始地址。粗页表中每个条目只能表示4KB的物理空间,如果大页描述符保存在粗页表中,则连续16个条目都保存同一个大页描述符。类似的,细页表中每个条目只能表示1KB的物理空间,如果大页描述符保存在细页表中,则连续64个条目都保存同一个大页描述符。
(3)0b10:小页描述符。
位[31:12]称为小页基址,此描述符的低12位填充0后就是一块4KB物理地址空间的起始地址。粗页表中每个条目表示4KB的物理空间,如果小页描述符保存在粗页表中,则只需要用一个条目来保存一个小页描述符。类似的,细页表中每个条目只能表示1KB的物理空间,如果小页描述符保存在细页表中,则连续4个条目都保存在同一个小页描述符中。
(4)0b11:极小页描述符。
位[31:10]称为极小页基址,此描述符的低10位填充0之后就是一块1KB的物理地址空间的起始地址。极小页描述符只能保存在细页表中,用一个条目来保存一个极小页描述符。
5.MVA到PA总结
从段、大页、小页和极小页的地址转换过程可知:
(1)以段进行映射时,通过MVA[31:20]结合页表得到的一段(1MB)的起始物理地址,MVA[19:0]用来在段中寻址。
(2)以大页进行映射时,通过MVA[31:16]结合页表得到一个大页(64KB)的起始物理地址,MVA[15:0]用来在大页中寻址。
(3)以小页进行映射时,通过MVA[31:12]结合页表得到的一个小页(4KB)的起始物理地址,MVA[11:0]用来在小页中寻址。
(4)以极小页进行映射时,通过MVA[31:10]结合页表得到的一个极小页(1KB)的起始物理地址,MVA[9:0]用来在极小页中寻址。
MMU负责完成虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。现代的多用户多进程操作系统通过MMU使得各个用户进程都拥有自己独立的地址空间:地址映射功能使得各个进程拥有"看起来"一样的地址空间,而内存访问权限的检查可以保护每个进程所使用的内存不会被其他进程所破坏。MMU增加了底层的复杂性,但是为上层程序开发提供了极大的方便。
2.虚拟地址与物理地址
虚拟地址最终需要转换为物理地址才能读写实际的数据,这通过将虚拟地址空间、物理地址空间划分为同样大小的一块块空间(称为段或页),然后为这两类小空间建立映射关系来实现。由于虚拟地址空间远大于物理地址空间,有可能多块虚拟地址空间映射到同一物理地址空间,或者有些虚拟地址空间没有映射到具体的物理地址空间(在使用到时再映射)。
ARM CPU上的地址转换过程涉及到3个概念:虚拟地址(VA)、变换后的虚拟地址(MVA)和物理地址(PA)。当没有启动MMU时,CPU核、cache、MMU、外设等所有部件使用的都是物理地址。启动MMU之后,CPU核对外发出虚拟地址VA;VA被转换为MVA供cache和MMU使用,cache和MMU完成MVA到PA的转换;最后使用PA读写具体的实际设备。
(1)CPU核看到的、用到的只是VA(启动MMU之后),VA到PA的转换对于CPU核来说是透明的。
(2)cache和MMU是看不见VA的。
(3)实际设备看不到VA和MVA。
注:MVA是除CPU核外的其他部分看见的虚拟地址。
3.VA和MVA之间的转换
之所以要设置一级VA和MVA之间的转换,是为了提高系统运行的效率。在2440中,VA和MVA之间的转换关系为:如果VA<32M,需要使用进程标识号PID(通过读CP15的C13获得)来转换为MVA,VA与MVA的转换方法如下(由硬件自动完成):
if(VA < 32M) then
MVA = VA | (PID << 25);
else
MVA = VA;
利用PID生成MVA的目的是为了减少切换进程时的代价:不使用MVA而直接使用VA的话,当两个进程的虚拟地址空间VA重叠时(因为对于每个上层应用来说都是拥有独立的4G空间,所以对于VA的使用一般都是从小地址往大地址占用),在切换进程时为了把重叠的VA映射到不同的PA上去,需要重建页表、使无效cache和TLBS等,代价极大。
而使用了MVA之后,切换进程将会简化许多。操作系统中一般小于32M的小进程居多,而真正的大进程反而较少,假设现在有20个小于32M的小进程,有5个超过32M的大进程,那么一共拥有25个不同的PID,这20个小进程会被映射到不同的MVA(因为其均未超过32M),而这5个大进程的低32M的VA也会被映射到不同的MVA,超过的部分会使用到重建页表等来完成映射。
MVA将4G的内存分为2^7=128个32M的空间(PID<<25),如果这128个进程使用的VA都是0~32M之间,则他们的地址都不会重叠,这样在进程切换时付出的代价是极小的。
4.VA到PA的转换过程
将一个虚拟地址转换为物理地址一般有两种方法:第一,使用一个数学公式进行转换;第二,用表格存储虚拟地址对应的物理地址。这类表格被称为页表,页表由一个个条目组成,每个条目存储了一段虚拟地址对应的物理地址及其访问权限,或下一级页表的地址。ARM中使用的是页表方法。
2440最多会用到两级页表:以段(1M)的方式进行转换时只用到一级页表,以页的方式进行转换时用到两级页表。页的大小有三种:大页(64KB)、小页(4KB)和极小页(1KB)。
大概的转换过程如下:
(1)根据给定的VA找到一级页表中的条目;
(2)如果此条目是段描述符,则返回物理地址,转换结束;
(3)如果此条目是二级页表描述符,继续利用虚拟地址在此二级页表中找到下一个条目;
(4)如果第二个条目是页描述符,则返回物理地址,转换结束;
(5)其他情况出错。
32位的CPU的虚拟地址空间达到4GB,一级页表中使用4096个描述符来表示这4GB空间——每个描述符对应1MB的虚拟地址,要么存储了它对应的1MB物理空间的起始地址,要么存入了下一级页表的地址。MMU根据MVA的[31:20]一共12位来得到这4096个描述符中的一个,每个描述符占用4B,所以一级页表占用了4KB。
根据一级描述符的最低两位,可以分为四种情况。
(1)0b00:无效。
(2)0b01:粗页表。
位[31:10]称为粗页表基址,此描述符的低10位填充0后就是一个二级页表的物理地址。此二级页表含有256个条目(10个bit表示,粗页表占用空间为1KB),粗页表中的每个条目代表4KB的物理地址空间,所以256*4KB=1MB的空间。
(3)0b10:段。
位[31:20]称为段基址,此描述符的低20位填充0之后就是一块1MB物理地址空间的起始地址。MVA[19:0]用于在这1MB空间中寻址。所以描述符的位[31:20]和MVA[19:0]就构成了这个虚拟地址MVA最终对应的PA。
(4)0b11:细页表。
位[31:12]称为细页表基址,此描述符的低12位填充0之后就是一个二级页表的物理地址。此二级页表含1024个条目(每个条目4B,一共占用4KB),其中每个条目代表1KB的物理地址空间,1024*1KB=1MB。
以大页(64K)、小页(4K)或极小页(1K)进行地址映射时,需要用到两级页表。二级页表分为上述的粗页表和细页表两种,根据二级描述符的最低两位,可以分为以下四种情况。
(1)0b00:无效。
(2)0b01:大页描述符。
位[31:16]称为大页基址,此描述符的低16位填充0后就是一块64KB物理地址空间的起始地址。粗页表中每个条目只能表示4KB的物理空间,如果大页描述符保存在粗页表中,则连续16个条目都保存同一个大页描述符。类似的,细页表中每个条目只能表示1KB的物理空间,如果大页描述符保存在细页表中,则连续64个条目都保存同一个大页描述符。
(3)0b10:小页描述符。
位[31:12]称为小页基址,此描述符的低12位填充0后就是一块4KB物理地址空间的起始地址。粗页表中每个条目表示4KB的物理空间,如果小页描述符保存在粗页表中,则只需要用一个条目来保存一个小页描述符。类似的,细页表中每个条目只能表示1KB的物理空间,如果小页描述符保存在细页表中,则连续4个条目都保存在同一个小页描述符中。
(4)0b11:极小页描述符。
位[31:10]称为极小页基址,此描述符的低10位填充0之后就是一块1KB的物理地址空间的起始地址。极小页描述符只能保存在细页表中,用一个条目来保存一个极小页描述符。
5.MVA到PA总结
从段、大页、小页和极小页的地址转换过程可知:
(1)以段进行映射时,通过MVA[31:20]结合页表得到的一段(1MB)的起始物理地址,MVA[19:0]用来在段中寻址。
(2)以大页进行映射时,通过MVA[31:16]结合页表得到一个大页(64KB)的起始物理地址,MVA[15:0]用来在大页中寻址。
(3)以小页进行映射时,通过MVA[31:12]结合页表得到的一个小页(4KB)的起始物理地址,MVA[11:0]用来在小页中寻址。
(4)以极小页进行映射时,通过MVA[31:10]结合页表得到的一个极小页(1KB)的起始物理地址,MVA[9:0]用来在极小页中寻址。