内存管理单元
MMU 的一个重要功能是使得系统可以运行多任务,作为一个独立的程序运行在它的私有虚拟地址空间上。这些独立程序不需要知道系统的物理内存映射,也就是那些实际被硬件使用的地址,也不用关心其他程序正在运行的程序。
有了 MMU ,我们可以使得每个应用程序都使用相同的虚拟地址。也可以使用连续的虚拟地址映射,即使这些物理内存是分离的。当将代码放置在内存中时,虚拟地址是那些被程序员、编译器和链接器使用的地址空间。而物理地址是那些被实际硬件系统使用的地址。
基于分页的虚拟内存
在 RT-Smart 操作系统中采用了基于分页机制的内存设计与实现,而页表是分页机制中的关键部分,负责记录虚拟页到物理页的映射关系,操作系统负责对页表进行配置。
在以往较简单的宏内核版本中,我们往往将虚拟地址和物理地址配置成一一映射,也就是说 CPU 尝试访问指定位置的虚拟地址,经过 MMU 翻译,实际上也访问了实际的物理地址。但是这种方式在支持多进程的 RT-Smart 中是不够的,要想支持多进程,就需要让不同进程在访问相同虚拟地址时,实际上访问了不同的物理地址。
在 AArch64 架构下,我们使用多级页表的方式来解决多进程的内存分配问题,常见的设置是虚拟地址低 48 位参与地址翻译,页表级数为 4 级,虚拟页大小为 4 KB。在这种情况下,物理内存被划分为连续的、4 KB 大小的物理页,一个虚拟页可以映射对应一个物理页。正因为页的大小为 4 KB,所以虚拟地址的低 12 位对应于页内偏移量。
虚拟地址的翻译过程
建立页表是内存管理的一个关键过程,后续用一个专题来仔细研究一下 ARMv8 下多级页表的建立过程,下图展示了如何逐级查询页表最终找到一个正常的 64KB 物理页的过程。
每一个二级页表可以与一个或者多个一级页表所关联,我们可以用多个一级页表描述符指向同一个二级表,这也就是说可以让多个虚拟地址指向相同的物理地址。
安全与非安全地址
从理论上来说,安全和非安全的物理地址空间是相互独立且同时存在的。一个系统可以被设计成有两个完全分离的内存系统。然而大部分实际的系统将安全和非安全当做一个访问控制的属性。普通世界只能访问非安全的物理地址空间。安全世界可以访问两种物理地址空间。这些访问权限是被转换表配置控制的。
Memory Ordering
在操作系统的开发过程中,需要编写一些与硬件交互或者执行在其他核上的代码,或者直接加载或者写入要被执行的指令(例如加载应用程序),或者修改页表,在这些情况下都需要考虑内存访问顺序问题,也可以理解为观察值和实际执行情况的顺序差。
在上述情况下,程序员必须保证编写的代码有着清晰的内存访问顺序,可以通过正确地利用屏障(barriers)来实现这个目标。
在 ARMv8 架构中使用了内存弱序模型。总的来说,这就意味着内存访问的顺序并不用要求与程序的加载(load)和存储(store)操作一致。处理器可以重新调整内存读、写操作。这样做的结果是,使用一些硬件优化方法,例如 cache 和写缓冲区可以优化处理器的性能,这就意味着处理器和外部内存之间的带宽要求可以降低,而且与外部内存访问相关的延时可以被隐藏。
对普通内存的读写可以被硬件重新排序,只受数据依赖和显示的内存屏障指令的影响。在某些情况下需要更强的排序规则。程序员可以通通过描述该内存的转换表项的内存类型属性,向处理器核心提供相关信息。
一些非常高性能的系统支持包括内存读推测、多发指令或者乱序执行以及其他技术,提供了更进一步的可能性使得硬件重新调整内存访问顺序。
多条指令产生
乱序执行
执行预测
预测加载
加载和存储优化
外部内存系统
缓存一致性与多核处理
编译器优化
内存类型
所有的内存区域都被配置成两种类型之一,普通内存和设备内存。第三种内存类型,强序内存,是 ARMv7 架构的一部分。强序内存与设备内存的区别很小,因此在 ARMv8 中被省略了。
除了内存类型,属性还提供了对 cacheability、shareability、access 和执行权限的控制。可共享和可缓存属性仅适用于普通内存。设备区域永远是不能缓存和不能共享的。
屏障指令
ARM 架构在特定点使用屏障指令来强制指定访问顺序和访问完成。在一些其他架构中,也有类似的指令被称为 fence。
ARMv8 架构提供了三种类型的屏障指令:
指令同步屏障(ISB)
数据内存屏障(DMB)
数据同步屏障(DSB)
内存属性
系统的内存内存映射被分为许多区域,每一个区域都需要不同的内存属性,例如对不同优先级、内存类型、缓存策略的读写访问权限。
内存属性还包括 cacheable 和 shareable,关于 shareable 细分下来还有 Non-shareable、Inner shareable、Outer shareable 以及 full system。
安全系统
一个系统提供一个特定的安全等级,一个受信的系统,是一个用来保护有价值的数据,例如密码和加密秘钥,信用卡数据,避免受到攻击,避免他们被复制、毁坏或者丢失。
在一个开放的系统中很难保证安全,因为在平台上会运行各种各样的软件,也会下载一些恶意的程序,这些程序可能会篡改系统。
ARM 处理器包括特殊的硬件扩展来构建一个受信的系统。软件以及硬件工具可以被分为如下三类:
软件攻击
简单硬件攻击
实验室硬件攻击
Trust Zone 技术就是被设计用于保护软件和简单硬件攻击。
TrustZone 硬件架构
TrustZone 架构为系统设计者提供一种方法来帮助安全系统,使用 TrustZone 安全扩展和安全外设。ARM 安全模型分为设备硬件和软件资源,他们存在于安全世界为安全子系统,或者普通世界为非安全系统。系统硬件可以保证安全世界的数据都不可以被普通世界访问到。一个安全的设计会将所有敏感的资源放在安全世界。
利用中断切换安全世界
因为代码会在两个世界中执行,因此需要利用硬件的异常机制,通过 SMC 指令来进行环境切换。下图展示了在非安全世界的上下文切换过程:
下图展示安全世界中的上下文切换过程:
在安全态和非安全态切换
使用 ARMv7 安全扩展,monitor 模式被软件使用与在安全和非安全态进行切换。这个模式与其他模式在安全态下有着同等的优先级。
对于 ARMv8 架构,当 EL3 在使用 AArch32 系统时与 ARMv7 完全兼容,安全状态的特权模式运行在 EL3,如下图所示:
下图展示了在 AArch64 架构下使用 EL3 提供安全监视器的情况。在 EL3 态下是不能运行 AArch32 的,按时 EL1 可以用作安全操作系统。当 EL3 在使用 AArch64,EL3 级别被用于执行切换安全态与非安全态的代码,如下图所示:
关于 ARM 的安全状态,后续还是要仔细研究的,因为通过 ATF 将系统从 EL3 切换到 EL1 的非安全状态后,才可以正常的运行 RT-Smart 操作系统,所以对 ATF 的研究是必不可少的。