一篇搞懂ARM、MMU(有这一篇就够了~)

MMU概念介绍

MMU分为两个部分: TLB 维护和地址转换

一篇搞懂ARM、MMU(有这一篇就够了~)

MMU的作用,主要是完成地址的翻译,无论是main-memory地址(DDR地址),还是IO地址(设备device地址),在开启了MMU的系统中,CPU发起的指令读取、数据读写都是虚拟地址,在ARM Core内部,会先经过MMU将该虚拟地址自动转换成物理地址,然后在将物理地址发送到AXI总线上,完成真正的物理内存、物理设备的读写访问。

下图是一个linux kernel系统中宏观的虚拟地址到物理地址转换的视图,可以看出在MMU进行地址转换时,会依赖TTBRx_EL1寄存器指向的一个页表基地址。其中,TTBR1_EL1指向特权模式的页表基地址,用于特权模式下的地址空间转换;TTBR0_EL0指向非特权模式的页表基地址,用于非特权模式下的地址空间转换。刚刚我们也提到,CPU发出读写后, MMU会自动的将虚拟地址转换为为例地址,那么我们软件需要做什么呢?我们软件需要做的其实就是管理这个页表,按照ARM的技术要求去创建一个这样的页表,然后再将其基地址写入到TTBR1_EL1或TTBR0_EL1。当然,根据实际的场景和需要,这个基地址和页表中的内容都会发生动态变化。例如,两个user进程进行切换时,TTBR0_EL1是要从一个user的页表地址,切换到另外一个user的页表地址。

一篇搞懂ARM、MMU(有这一篇就够了~)


MMU地址翻译的过程

使用一个64KB的粒度与42位的虚拟地址空间,地址翻译的过程(只用到一级页表的情况):

一篇搞懂ARM、MMU(有这一篇就够了~)

使用二级页表的情况举例:

一篇搞懂ARM、MMU(有这一篇就够了~)

更多linux内核视频教程文档资料免费领取后台私信【内核】自行获取.

一篇搞懂ARM、MMU(有这一篇就够了~)

一篇搞懂ARM、MMU(有这一篇就够了~)

Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈-学习视频教程-腾讯课堂

在secure和non-secure中使用MMU

TTBRx_EL1是banked的,在linux和optee双系统的环境下,可同时开启两个系统的MMU。在secure和non-secure中使用不同的页表.secure的页表可以映射non-secure的内存,而non-secure的页表不能去映射secure的内存,否则在转换时会发生错误。

一篇搞懂ARM、MMU(有这一篇就够了~)

在不同异常等级中使用MMU

在ARMV8-aarch64架构下,页表基地址寄存器有:

  • TTBR0_EL1 – 银行
  • TTBR1_EL1 – 银行
  • TTBR1_EL2
  • TTBR1_EL3

在EL0/EL1的系统中,MMU地址转换时,如果虚拟地址在0x00000000_ffffffff - 0x0000ffff_ffffffff范围,MMU会自动使用TTBR0_EL1指向的页表,进行地址转换;如果虚拟地址在0xffff0000_ffffffff - 0xffffffff_ffffffff范围,MMU会自动使用TTBR1_EL1指向的页表,进行地址转换。

在EL2系统中,MMU地址转换时,会自动使用TTBR2_EL1指向的页表。

在EL3系统中,MMU地址转换时,会自动使用TTBR3_EL1指向的页表

一篇搞懂ARM、MMU(有这一篇就够了~)


内存属性介绍

translation tables为每一块region(entry)都定义了一个memory attributes条目,如同下面这个样子(以linux kernel为例,在创建页表的时候,应该会设置这个memory attributes,有待看代码去验证):

一篇搞懂ARM、MMU(有这一篇就够了~)


• 无特权执行从不 (UXN) 和特权执行从不 (PXN) 是执行权限。• AF 是访问标志。• SH 是可共享属性。• AP 是访问权限。•NS是安全位,但仅在EL3和安全EL1。----安全权限配置 • Indx 是MAIR_ELn

在这块region(entry)的memory attributes条目中的BIT4:2(index)指向了系统寄存器MAIR_ELn中的attr,MAIR_ELn共有8中attr选择。

一篇搞懂ARM、MMU(有这一篇就够了~)


而每一个attr都有一种配置:

一篇搞懂ARM、MMU(有这一篇就够了~)


内存标记介绍

启用标记寻址支持后,处理器将忽略虚拟地址的前八位 [63:56]。它在内部设置位 [55] 以将地址签名扩展为 64 位格式。然后,前 8 位可用于传递数据。对于寻址和转换错误,将忽略这些位。TCR_EL1具有用于 EL0 和 EL1 的单独使能位

如果使用memory tagging, 虚拟地址的[63:56]用于传输签名数据,bit[55]表示是否需要签名.TCR_EL1也会有一个bit区分是给EL0用的还是给EL1用的

启用hypervisor

如果启用了hypervisor那么虚拟地址转换的过程将有VA—>PA变成了VA—>IPA—>PA, 也就是要经过两次转换.在guestos(如linux kernel)中转换的物理地址,其实不是真实的物理地址(假物理地址),然后在EL2通过VTTBR0_EL2基地址的页表转换后的物理地址,才是真实的硬件地址。

国际音标:中间物理地址

一篇搞懂ARM、MMU(有这一篇就够了~)


访问权限

访问权限通过转换表条目进行控制。访问权限控制区域是可读还是可写,或者两者兼而有之,对于非特权,可以分别设置为 EL0,对于特权访问,可以分别设置为 EL1、EL2 和 EL3,如下表所示

参考 :SCTLR_EL1.WXN、单反相机UWXN执行权限:

一篇搞懂ARM、MMU(有这一篇就够了~)


  • 不可执行(从不执行 (XN))
  • 无特权执行从不 (UXN)
  • 特权从不执行 (PXN)

MMU/cache相关的寄存器总结

MMU(地址转换 /TLB 维护)、缓存维护相关的寄存器

  1. 地址转换

address translation 共计14个寄存器

一篇搞懂ARM、MMU(有这一篇就够了~)


2. 断续器维护

TLB maintenance数十个寄存器

一篇搞懂ARM、MMU(有这一篇就够了~)


3. 缓存维护

一篇搞懂ARM、MMU(有这一篇就够了~)


4. 基本系统寄存器

系统寄存器中, 和MMU/Cache相关的寄存器有:

TTBR0_ELx TTBR1_ELx

(aarch64)

  • TTBR0_EL1
  • TTBR0_EL2
  • TTBR0_EL3
  • TTBR1_EL1
  • VTTBR_EL2

(aarch32)

  • 断续器
  • 断续器
  • 断续器
  • 断续器

TCR_ELx

(aarch64)

  • TCR_EL1
  • TCR_EL2
  • TCR_EL3
  • VTCR_EL2

(aarch32)

  • 断续器(NS)
  • 高温高压
  • 断续器
  • VTCR

MAIR_ELx

  • MAIR_EL1
  • MAIR_EL2
  • MAIR_EL3

系统寄存器 — TCR寄存器介绍

在ARM Core中(aarch64),还有几个相关的系统寄存器:

  • TCR_EL1银行
  • TCR_EL2
  • TCR_EL3
一篇搞懂ARM、MMU(有这一篇就够了~)


一篇搞懂ARM、MMU(有这一篇就够了~)


  1. T1SZ、T0SZ
  • T1SZ, bits [21:16] 通过TTBR1寻址的内存区域的大小偏移量,也就是TTBR1基地址下的一级页表的大小
  • T0SZ, 位 [5:0]

2. ORGN1、IRGN1、ORGN0、IRGN0

一篇搞懂ARM、MMU(有这一篇就够了~)


其实可以总结为这样:

一篇搞懂ARM、MMU(有这一篇就够了~)


3. SH1、SH0

一篇搞懂ARM、MMU(有这一篇就够了~)


其实可以总结为这样:

一篇搞懂ARM、MMU(有这一篇就够了~)


Shareable的很容易理解,就是某个地址的可能被别人使用。我们在定义某个页属性的时候会给出。Non-Shareable就是只有自己使用。当然,定义成Non-Shareable不表示别人不可以用。某个地址A如果在核1上映射成Shareable,核2映射成Non-Shareable,并且两个核通过CCI400相连。那么核1在访问A的时候,总线会去监听核2,而核2访问A的时候,总线直接访问内存,不监听核1。显然这种做法是错误的。

对于Inner和Outer Shareable,有个简单的的理解,就是认为他们都是一个东西。在最近的ARM A系列处理器上上,配置处理器RTL的时候,会选择是不是把inner的传输送到ACE口上。当存在多个处理器簇或者需要双向一致性的GPU时,就需要设成送到ACE端口。这样,内部的操作,无论inner shareable还是outershareable,都会经由CCI广播到别的ACE口上。

4. TG0/TG1 - 颗粒尺寸

一篇搞懂ARM、MMU(有这一篇就够了~)


5. 环迅支付

一篇搞懂ARM、MMU(有这一篇就够了~)


6. 环保署1、环保署0

一篇搞懂ARM、MMU(有这一篇就够了~)


7. TBI1、TBI0

一篇搞懂ARM、MMU(有这一篇就够了~)


8. 答1

一篇搞懂ARM、MMU(有这一篇就够了~)


9. 如

一篇搞懂ARM、MMU(有这一篇就够了~)


除了以上介绍的bit之外,剩余的bit都是特有功能使用或保留的

一篇搞懂ARM、MMU(有这一篇就够了~)


代码使用示例展

设置inner/outer cache的属性(只写模式/回写模式/write allocate/No-write allocate)

#define TCR_IRGN_WBWA  ((UL(1) << 8) | (UL(1) << 24))   //使用TTBR0和使用TTBR1时后的inner cache的属性设置

#define TCR_ORGN_WBWA  ((UL(1) << 10) | (UL(1) << 26))   //使用TTBR0和使用TTBR1时后的outer cache的属性设置

#define TCR_CACHE_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA   // inner + outer cache的属性值


ENTRY(__cpu_setup)
......
 /*
  * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
  * both user and kernel.
  */
 ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
   TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0 | TCR_A1
 tcr_set_idmap_t0sz x10, x9

......
 msr tcr_el1, x10
 ret     // return to head.S
ENDPROC(__cpu_setup)

属性设置了1,也就是回写模式、写分配模式。

一篇搞懂ARM、MMU(有这一篇就够了~)


一篇搞懂ARM、MMU(有这一篇就够了~)

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章