内存系列学习(三):ARM处理器地址变换过程

简介: 内存系列学习(三):ARM处理器地址变换过程

一、MMU简介

MMU是Memory Manage Unit的缩写,即存储管理单元的意思。

MMU实现以下功能:

  • 1)虚拟存储地址到物理存储地址的映射;
  • 2)控制存储空间访问权限;
  • 3)设置存储空间的缓冲特性。

与MMU相关的一些基本概念介绍如下:

1-页表(Translate Table)

页表又叫翻译表,用来将虚拟地址翻译成对应的物理地址它位于内存中,是实现MMU功能的重要组成部分,处理器通过查找页表中的描述符来获取虚拟地址对应的物理地址。

ARM处理器是按两级分页来管理内存的,所以页表包括一级页表和二级页表。

  • 一级页表中的每一项(1个字,4字节)对应于虚拟存储空间的一段(section),一段的大小为1MB(0x100000字节),该项包含了该虚拟存储段对应的物理存储段的基地址或者一段存储空间内每页的二级页表描述符组成的表的基地址、所属的内存域编号、缓冲特性等,一级页表的基地址保存在ARM处理器中CP15协处理器的C2寄存器中,该寄存器中保存的是一级页表的物理基地址,而不是虚拟地址。
  • 二级页表中的每一项(1word,4bytes)对应于虚拟存储空间的一页,一页的大小可以是4KB或1KB,该项包含了该虚拟存储页对应的物理存储页的基地址、该页的访问权限和该页的缓冲特性等。我们将页表中的每一项叫做一个地址变换条目(entry),也可以叫一个页表项。

2-翻译援助缓冲区(Translation Lookaside Buffer,TLB)

TLB在硬件上和cache一样是处理器内部的一小块高速SRAM内存,用于缓存,与cache不同的是,它专门缓存存放在内存中的页表,容量相对比较小,而cache则用于缓存普通内存,容量相对比较大

TLB也分为数据TLB和指令TLB,指令TLB用于取指令时的指令地址翻译而数据TLB用于其他存储访问操作时的地址翻译

有的处理器中数据TLB和指令TLB是分开的,有的处理器中这两者是统一的。

TLB是为了提高处理器查询页表的速度而设计的,所以TLB又叫快表

当处理器要查询页表时首先在TLB中查找,如果要查找的页表项不在TLB中,那么CPU从位于内存中的页表中查询,并把相应的结果添加到TLB中,这样CPU下次查找该页表项时就可以从TLB中直接获取。

二、系统访问存储空间的过程

系统访问存储空间的过程对于使能MMU和禁止MMU两种情况是不一样的ARM处理器中控制MMU功能的开关位是CP15协处理器的C1寄存器的bit[0],当该位为0时禁止MMU功能,当该位为1时使能MMU功能。

1 使能MMU时的情况

当CPU请求存储访问时,首先在TLB中查找虚拟地址,如果该虚拟地址对应的地址变换条目(页表项)不在TLB中,CPU从位于内存中的页表中查询对应于该虚拟地址的页表项,并把相应的结果添加到TLB中,这样CPU下次再访问该页表项时就可以直接从TLB中获取。如果TLB已经装满,还应该根据一定的淘汰算法进行替换

在得到了需要的页表项后,将进行以下操作:

  • 1)得到该虚拟地址对应的物理地址;
  • 2)根据页表项中的缓冲特性控制位C(Cachable)和B(Bufferable)的值决定是否缓存该存储访问的结果;
  • 3)根据存取权限控制位和所属存储域的权限设置情况确定该存储访问是否被允许;
  • 4)对于不允许缓存(uncached)的存储访问,使用上面步骤1)中得到的物理地址访问存储空间。对于允许缓存(cached)的存储访问,如果cache命中,则忽略物理地址;如果cache没有命中,则使用上面步骤1)中得到的物理地址访问存储空间,并把该数据块读到cache中。
有些VA所对应的PA并不是物理内存中的地址而是设备寄存器的地址,对这些寄存器进行读写并不是为了保存数据,而是对设备做特殊操作,这种VA通常是不允许缓存的,因为如果缓存了,对VA的读写将只在Cache中起作用,而不会传到设备寄存器对设备进行操作。

2 禁止MMU时的情况

如果系统禁止MMU功能,那么CPU的存储访问规则如下:

  • 1)当禁止MMU时,是否支持cache和Write Buffer由各具体芯片确定。如果芯片规定当禁止MMU的同时也禁止cache和Write Buffer,则存储访问不考虑缓冲特性控制位C和B的设置情况;如果芯片规定当禁止MMU时可以使能cache和Write Buffer,
  • 则数据访问时,C=0,B=0,
  • 指令读取时,如果使用数据和指令分开的TLB,则C=1,如果使用统一的TLB,则C=0。
  • 2)存储访问不进行权限控制,MMU也不会产生存储访问中止信号。
  • 3)所有的物理地址和虚拟地址相同,也就是使用所谓的平板存储模式

3 使能/禁止MMU时应注意的问题

在使能和禁止MMU时要注意以下几点:

  • 1)在使能MMU前,要在内存中建立好页表,同时CP15中的各相关寄存器必须完成初始化。
  • 2)如果使用的不是平板存储模式(物理地址和对应虚拟地址相等),在禁止/使能MMU时,虚拟地址和物理地址的对应关系会发生改变,此时应该清除cache中的当前地址变换条目(TLB)。(清楚当前的,要最新的,避免cache不是最新的,访问映射出错。)
  • 3)如果完成禁止/使能MMU的代码的物理地址和虚拟地址不同,禁止/使能MMU时将造成很大麻烦,因此强烈建议完成禁止/使能MMU的代码的物理地址和虚拟地址相同(或者与地址无关)。

三、ARM处理器地址变换过程

虚拟存储空间到物理存储空间的映射是以内存块为单位进行的,虚拟存储空间中的一块连续存储空间被映射成物理存储空间中同样大小的一块连续存储空间。

每一个地址变换条目(页表项)记录了一个虚拟存储空间的存储块的基地址与物理存储空间相应的一个存储块的基地址的对应关系。

根据存储块大小不同,可以有多种地址变换。

  • 1)段(section):大小为1MB的存储块。
  • 2)大页(Large Page):大小为64KB的存储块。
  • 3)小页(Small Page):大小为4KB的存储块。
  • 4)极小页(Tiny Page):大小为1KB的存储块。

通过采用适当的访问控制机制,还可以将大页分成大小为16KB的子页,也可将小页分成大小为1KB的子页,但极小页不能再细分,只能以1KB大小的整页为单位。

ARM处理器采用两级页表实现地址映射:

  • 1)一级页表中包含以段为单位的地址变换条目或者指向二级页表的指针,一级页表实现的地址映射粒度较大。
  • 2)二级页表中包含以大页、小页和极小页为单位的地址变换条目。

当以二级分页管理某段存储空间时,要同时设置一级页表项和二级页表项,

  • 一个一级页表项对应一段(1section=1MB)虚拟存储空间的映射关系,
  • 一个一级页表项对应一张二级页表,这张二级页表中的所有页表项合在一起对应了前面一级页表项所对应的一段虚拟存储空间的映射关系。

ARM处理器的二级页表分为粗粒度二级页表和细粒度二级页表,

  • 一张粗粒度二级页表的最大容量为1KB,
  • 一张细粒度二级页表的最大容量为4KB,

不管是粗粒度还是细粒度页表,每张页表都对应一段虚拟存储空间的映射关系。

所以粗粒度二级页表的页表项(页描述符)最小只能描述4KB大小(小页)虚拟存储空间的映射关系,如果再小就没有足够的页表空间来存放一段虚拟存储空间的全部页表项(因为粗粒度二级页表的最大容量为1KB),

而细粒度二级页表的页描述符最小可以描述1KB大小(极小页)的虚拟存储空间的映射关系。

综上所述,我们可以归纳出以下6种ARM处理器的地址变换方法:

  • 1)分段地址变换,这种变换只需要一级地址变换,而下面5种都需要两级地址变换;
  • 2)粗粒度大页地址变换;
  • 3)粗粒度小页地址变换(Linux通常使用的地址变换方法);
  • 4)细粒度大页地址变换;
  • 5)细粒度小页地址变换;
  • 6)细粒度极小页地址变换。

在讲解以上各种地址变换方法之前我们先介绍一下一级映射描述符和二级映射描述符的定义。

1 MMU的一级映射描述符

ARM处理器MMU的一级映射描述符编码格式如下所示:

2 MMU的二级映射描述符

ARM处理器MMU的二级映射描述符编码格式如下所示:

3 基于段的地址变换过程

4 粗粒度大页地址变换过程

5 粗粒度小页地址变换过程

6 细粒度大页地址变换过程

7 细粒度小页地址变换过程

8 细粒度极小页地址变换过程

四、ARM存储空间访问权限控制

在ARM处理器中,MMU将整个存储空间分成最多16个域,记作D0~D15,每个域对应一定的存储区域,该区域具有相同的访问控制属性。

在ARM处理器中,MMU中的每个域的访问权限分别由CP15的C3寄存器中的两位来设定,C3寄存器刚好可以设置16个域的访问权限。C3寄存器的域定义如表4-6所示。

C3寄存器的D0D15各占两位,它们分别控制D0D15共16域的访问类型,具体说明如表4-7所示。

当域访问权限控制位设置为上面的0b01即客户类型权限时,用户模式以及特权模式的访问权限则由CP15的C1控制寄存器中的R和S位以及页表中地址变换条目中的访问权限控制位AP两位来确定,具体说明如表4-8所示。

五、TLB操作

对TLB的操作是通过访问CP15的C8和C10寄存器来完成的,写CP15的C8/C10寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c8>, crm, <opcode_2>
        mcr p15, 0, <rd>, <c10>, crm, <opcode_2>

1 使TLB内容无效

使TLB中的内容无效是通过写CP15的寄存器C8来实现的,指令如表4-9所示。

2 锁定TLB内容

锁定TLB是通过写CP15的寄存器C10来实现的。锁定TLB中N条地址变换条目的操作步骤说明如下:

  • 1)确保在整个锁定过程中不会产生异常中断,可以通过禁止中断等方法实现;
  • 2)如果锁定的是指令TLB或者统一的TLB,将base=N、victim=N、P=0写入C10;
  • 3)使整个将要锁定的TLB无效;
  • 4)如果想要锁定的是指令TLB,确保与锁定过程所涉及的指令相关的地址变换条目已经加载到指令TLB中;如果想要锁定的是数据TLB,确保与锁定过程所涉及的数据相关的地址变换条目已经加载到指令TLB中;如果系统使用的是统一的数据TLB和指令TLB,上述两条都要保证;
  • 5)对于I=0到N-1,重复执行下面操作:
    将base=i、victim=i、P=1写入寄存器C10,将每一条想要锁定到快表中的地址变换条目读取到快表中。对于数据TLB和统一TLB可以使用ldr指令读取一个涉及该地址变换条目的数据,将该地址变换条目读取到TLB中。对于指令TLB,通过操作寄存器C7,将相应的地址变换条目读取到指令TLB中;
  • 6)将base=N、victim=N、P=0写入寄存器C10。

3 解除TLB中被锁定的地址变换条目

解除TLB中被锁定的地址变换条目,可以使用以下操作步骤:

  • 1)通过操作寄存器C8,使无效TLB中被锁定的地址变换条目;
  • 2)将base=0、victim=0、P=0写入C10寄存器。

六、存储访问失效

ARM处理器通过以下两种机制来检测存储访问失效,进而中止CPU的运行:

  • 1)MMU硬件模块检测与内存管理相关的存储访问失效,一旦MMU检测到存储访问失效,它向CPU发出通知,并将存储访问失效的相关信息保存到寄存器中,具体说就是将失效状态保存在CP15的C5寄存器中,将导致失效的地址保存在CP15的C6寄存器中,详见前面CP15的C5、C6寄存器说明。这种存储访问失效叫做MMU失效(MMU Fault)。
  • 2)外部存储系统向CPU报告存储访问失效,这种机制叫做外部存储访问中止(External Abort)。

1 MMU失效(MMU Fault)

  • 1)地址对齐失效:地址对齐失效只会发生在数据访问周期,比如
  • 访问字单元(4字节)时地址的bit[1:0]不全是0或者访问半字(双字节)单元时地址的bit[0]不等于0;
  • 访问字节单元不会产生地址对齐失效,指令预取周期也不会产生地址对齐失效。
  • 2)地址变换失效:
  • 当一级地址变换条目的bit[1:0]为0b00时,表示产生了基于段的地址变换失效;
  • 当二级地址变换条目的bit[1:0]为0b00时,表示产生了基于页的地址变换失效。
  • 3)域控制失效:如果所访问的存储地址对应的一级地址变换条目中bit[8:5]的值所指的存储域的两位控制位被设置为0,就说明产生了域控制失效,域控制失效可能是基于段的也可能是基于页的。
  • 4)访问权限控制失效:如果出现了访问权限冲突就产生访问权限控制失效。

以上4大类存储访问失效又可细分为15种类型,见前面CP15的C5寄存器说明

当发生存储访问失效时,存储系统可以中止3种存储访问:

  • cache内容预取、
  • 非缓冲的存储器访问
  • 页表访问。

2 外部存储访问失效(External Abort)

由外部存储系统向CPU报告存储访问失效。

外部存储访问失效通过一个外部存储访问失效引脚实现,下面的存储访问操作可以通过这种机制中止和重启动:

  • 1)读操作;
  • 2)非缓冲的写操作;
  • 3)一级描述符的获取;
  • 4)二级描述符的获取;
  • 5)非缓冲的存储区域中的信号量操作。

注意:在系统中标记为可外部终止的存储区域不要进行可缓存的写操作。

参考资料

《嵌入式系统Linux内核开发实战》

目录
相关文章
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
60 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
5月前
|
存储 C语言
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
326 1
|
5月前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
83 0
|
5月前
|
缓存 Java
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
50 0
|
5月前
|
JavaScript 前端开发
事件委托是JS技巧,通过绑定事件到父元素利用事件冒泡,减少事件处理器数量,提高性能和节省内存。
【6月更文挑战第27天】事件委托是JS技巧,通过绑定事件到父元素利用事件冒泡,减少事件处理器数量,提高性能和节省内存。例如,动态列表可共享一个`click`事件处理器,通过`event.target`识别触发事件的子元素,简化管理和响应动态内容变化。
46 0
|
5月前
|
编译器 C语言 C++
C语言学习记录——位段(内存分配、位段的跨平台、位段的应用)
C语言学习记录——位段(内存分配、位段的跨平台、位段的应用)
54 0
|
2月前
ARM64技术 —— MMU处于关闭状态时,内存访问是怎样的?
ARM64技术 —— MMU处于关闭状态时,内存访问是怎样的?
|
2月前
|
Ubuntu KVM 虚拟化
基于ARM64的Qemu/KVM学习环境搭建
基于ARM64的Qemu/KVM学习环境搭建
|
3月前
|
存储 JavaScript 前端开发
学习JavaScript 内存机制
【8月更文挑战第23天】学习JavaScript 内存机制
34 3