MMU是硬件内存管理的支持,具体来说,每个处理器有一些差异,但每个处理器在不同架构之间的实现也有差异,技术有所进步,但实际需求、性能的提高、使用场景的复杂化,都是其开发

MMU的主要功能之一是从虚拟地址到物理地址的转换,这需要软硬件协同完成,软件需要针对不同的硬件进行策略。 在此主要分析ARMv7-A架构下MMU的基本原理。

ARM官方数据表下载链接:

arm V7-a _ and _ r _ architecture _ reference _ manual :

3359 developer.arm.com/docs/ddi 0406/latest

在此数据表中,

B3虚拟内存系统体系结构(vmsa )

风中薯片介绍了虚拟内存系统的相关内容

VMSA是一种用于ARMv7-A体系结构的虚拟内存系统体系结构,其中包括支持VMSA的PMSA。 这是ARMv7-R系列处理器支持的内存保护系统体系结构。 不在此讨论,只需了解ARMv7-A系列的相关内容即可。

1 .概述ARMv7的VMSA包括安全扩展、多核处理器扩展、最大物理地址扩展、可信区域扩展和虚拟化扩展。 要支持较大的物理地址,必须支持多核处理器。 要支持虚拟化,必须支持较大的物理地址、多核处理器和信任区域。 除了这些扩展外,相应的虚拟到物理地址隐藏功能(MMU )的结构也发生了很大的变化。 本文首先分析了进行扩展的MMU的整体结构,然后详细介绍了用于地址转换的短描述符格式(32位)和长描述符格式(64位),以及实现从虚拟地址到物理地址的查询的方法。

在ARMv7的VMSA中,MMU控制地址转换(虚拟到物理)、权限控制。 MMU的控制通过系统控制寄存器进行,支持系统控制注册(当然,也支持MMU功能的关闭。

ARMv7-R结构的VMSAv7的支持情况因处理器实施和具体情况而异,可分为多种情况,每种情况分为不同的stage。

扩展的VMSAv7分为安全和不安全。

安全状态对于内存系统控制只有一个stageNon-Secure state,对于内存系统控制,当处理器位于PL2时,只有一个stage是PL0

安全pl 10 stage1MMU non -安全pl2stage1MMU non -安全pl 10 stage1MMU non-secure pl 10 stage2MMU .同时用于单个CPU的实现

不支持在PL2上运行。 在非安全下,对于仅支持非安全pl10 stage 1的MMU,请参见ARMv7体系结构东面:

ARMv7体系结构支持大内存、虚拟化和安全。

1. 大内存(Large Memory):

由于处理器性能更高,而且运行的软件也更复杂,因此对于大内存的需求可能会在单个APP应用程序中超过32位体系结构所能支持的最大内存(4G ),这是导致大内存需求的原因但是,后面的CORTEX-a15(armv7架构)通过Large Physical Address Extensions (LPAE)技术,能够支持最多40bits的物理地址空间。 但是,受限于32位指令集,虚拟地址空间仍然只有32位(4g )。 如果有APP应用程序,是否需要更大的虚拟内存? 只能定义一个64位指令集,也就是使用常说的ARM64的新体系结构。

2. 虚拟化(Virtualization)和安全(Security):

ARM v6引入了安全扩展,将硬件资源划分为两个部分安全世界和正规世界。 当CPU在安全世界中运行时,您可以访问所有硬件资源;而当CPU在normal world中运行时,您只能访问normal world资源。

ARM v7引入了虚拟化扩展,在正规世界中添加了新的CPU模式: hyp模式。

当CPU以这种方式在正常世界中运行时,有三种模式: usr模式、SVC模式和HYP

mode,分别对应 PL0, PL1, PL2 (PL:privilege level),number越大,权限越高。

我对这里所说的权限的理解是:寄存器的访问和指令的执行。比如说一些特殊的寄存器(HVBAR)只能再HYP mode里面才能访问,一些特殊的指令(HVC)只能再SVC 或者 HYP mode执行。而CPU处于哪个模式是由CPSR这个寄存器决定的。

PL0进PL1通过SWI指令(system call),PL1回PL0通过复原CPSR。

类似的,hypervisor也是由HYP exception vector和handler。一个最简单的hypervisor就是HVBAR寄存器定义vector的位置,在offset 0x14的地方放一个eret指令。这样的hypervisor可以处理kernel发起的HVC call

与 PL0、PL1、PL2 对应的是 CPU mode

usr,只在PL0中使用,可以是安全或者非安全的,一般情况下,用户软件处于非安全态的usr下,而secure的应用程序则处于安全的usr下sys, und, fiq, irq, svc, abt,只在PL1中,可以是安全或者非安全的,一般情况下,非安全的os或者虚拟扩展下的guest os位于非安全的mode下,而secure os位于安全的mode下hyp, 只能在非安全态的PL2中,一般情况下,虚拟扩展的hypervisor实现在这个模式

 

2.  ARMv7-A MMU 特性 2.1 权限控制

对于指令和数据,支持:

no accessread-onlywrite-onlyread/write

 

2.2 地址翻译

地址翻译单元的输入是虚拟地址,输出是物理地址,由于存在几种不同的配置,所以 MMU 的地址转换分为如下几种情况:

而这几种模式下,修改的寄存器也不一样:

所以最后对应的图为:

安全模式的PL1&0隐射,页表控制寄存器TTBCR,页表基址寄存器TTBR0/TTBR1,这些寄存器需要在S模式的PL1设置;

非安全模式的PL2隐射,页表控制寄存器HTCR,页表基址寄存器HTTBR,需要在NS的PL2设置;

非安全模式的PL1&0的一级映射,页表控制寄存器TTBCR,页表基址寄存器TTBR0/TTBR1,需要在NS模式的PL1设置;

非安全模式的PL1&0的二级映射,页表控制寄存器VTCR,页表基址寄存器VTTBR,需要在NS的PL2设置

 

2.2.1 地址描述符

地址描述符分为两种:

短描述符和长描述符,长描述符是针对大物理地址扩展,这里仅仅简单分析短描述符

短描述符

在 datasheet 的 B3.5 风中的薯片有比较详细的描述,主要讲了短描述符的分类,寄存器的配置,以及怎么去进行 table walk 的

短描述符的分类:

(1) SuperSection:24位。16MB 的 blocks,可选的,主要是支持大物理地址扩展必须支持

(2) Section: 20位。1MB 的 blocks

(3) Large pages : 16位。64KB 的 blocks

(4) Small pages : 12位。4KB 的 blocks (Linux 用这种)

当使用短描述符的时候(short-descriptor)的 translation table format 的时候,硬件支持两级页表,主要描述这个的有几个寄存器:

TTBCR

TTBR0

TTBR1

如果 SuperSection 或者 Section 的话,只需要一级页表即可,如果支持 4KB 或者 64KB 的页面,需要用到二级页表。以 4KB 的页映射为例:

当 TLB Miss 的时候,处理器进行 table walk:

1. 根据 TTBCR 寄存器和虚拟地址来判断使用哪个页表基地址寄存器(TTBR0 或者 TTBR1)。其中放置了一级页表的基地址

2. 处理器根据虚拟地址的 bit[31:20]作为索引,在一级页表中查找页表项,一级页表一共有 4096 个 页表项(4K 个 entry)

3. 一级页表的表象中存放了二级页表的基地址,处理器根据虚拟地址的 bit[19:12]作为索引值,在二级页表中找到对应的表,二级页表一个 256 个表项

4. 二级页表的页表项里面存放了又 4KB 页的物理基地址,加上最后的 bit[11:0] 的offset,寻找到最终的物理内存。

 

4KB 映射的一级页表表项和二级页表的表项其实也是 32bits 的,只不过其他的一些 bit 被硬件用作其他作用:

一级表项:

二级页表项是:

 

TTBR0 或者 TTBR1 的选取:

根据 TTBCR.N 中的这个 N 的值来进行选取:

如果 N = 0 的话,则一直使用 TTBR0

如果 N > 0 的话,则 bits [31:31-N] 的虚拟地址部分,如果全部等于 0,则使用 TTBR0 ,否则使用 TTBR1

官方文档上的虚拟地址到物理地址的转换过程如下(这里仅仅分析 Small page 也就是 4K 的情况,其他的情况请自行阅读文档):

 

参考文献:

https://blog.csdn.net/zzk315/article/details/53075073

http://www.cnblogs.com/fozu/p/4601291.html

https://zhuanlan.zhihu.com/p/21300203

http://www.wowotech.net/armv8a_arch/armv8-a_overview.html

7码计划科学打法rong>设置;

 

2.2.1 地址描述符

地址描述符分为两种:

短描述符和长描述符,长描述符是针对大物理地址扩展,这里仅仅简单分析短描述符

短描述符

在 datasheet 的 B3.5 风中的薯片有比较详细的描述,主要讲了短描述符的分类,寄存器的配置,以及怎么去进行 table walk 的

短描述符的分类:

(1) SuperSection:24位。16MB 的 blocks,可选的,主要是支持大物理地址扩展必须支持

(2) Section: 20位。1MB 的 blocks

(3) Large pages : 16位。64KB 的 blocks

(4) Small pages : 12位。4KB 的 blocks (Linux 用这种)

当使用短描述符的时候(short-descriptor)的 translation table format 的时候,硬件支持两级页表,主要描述这个的有几个寄存器:

TTBCR

TTBR0

TTBR1

如果 SuperSection 或者 Section 的话,只需要一级页表即可,如果支持 4KB 或者 64KB 的页面,需要用到二级页表。以 4KB 的页映射为例:

当 TLB Miss 的时候,处理器进行 table walk:

1. 根据 TTBCR 寄存器和虚拟地址来判断使用哪个页表基地址寄存器(TTBR0 或者 TTBR1)。其中放置了一级页表的基地址

2. 处理器根据虚拟地址的 bit[31:20]作为索引,在一级页表中查找页表项,一级页表一共有 4096 个 页表项(4K 个 entry)

3. 一级页表的表象中存放了二级页表的基地址,处理器根据虚拟地址的 bit[19:12]作为索引值,在二级页表中找到对应的表,二级页表一个 256 个表项

4. 二级页表的页表项里面存放了又 4KB 页的物理基地址,加上最后的 bit[11:0] 的offset,寻找到最终的物理内存。

 

4KB 映射的一级页表表项和二级页表的表项其实也是 32bits 的,只不过其他的一些 bit 被硬件用作其他作用:

一级表项:

二级页表项是:

 

TTBR0 或者 TTBR1 的选取:

根据 TTBCR.N 中的这个 N 的值来进行选取:

如果 N = 0 的话,则一直使用 TTBR0

如果 N > 0 的话,则 bits [31:31-N] 的虚拟地址部分,如果全部等于 0,则使用 TTBR0 ,否则使用 TTBR1

官方文档上的虚拟地址到物理地址的转换过程如下(这里仅仅分析 Small page 也就是 4K 的情况,其他的情况请自行阅读文档):

 

参考文献:

https://blog.csdn.net/zzk315/article/details/53075073

http://www.cnblogs.com/fozu/p/4601291.html

https://zhuanlan.zhihu.com/p/21300203

http://www.wowotech.net/armv8a_arch/armv8-a_overview.html