概述

在ARMv8中,程序总是运行在四种异常状态中的一种。
在AArch64中,异常级别决定特权级别,与ARMv7中定义的特权级别类似。
异常级别决定特权级别,例如ELn对应PLn。n越大则特权等级越高。
在所有ARMv8架构中,特权等级的不同有着不同的操作权限,它类似于计算机中常见保护域的概念。
不用的特权级别如下所示

  • EL0 应用程序
  • EL1 操作系统内核
  • EL2 虚拟化
  • EL3 低级固件,包含安全监控等

    通常一个软件只在一个特权级运行,例如应用程序、操作系统内核、虚拟化,但KVM之类的内核虚拟机监控程序,它会在EL1和EL2上运行。
    ARMv8-A提供两种安全状态,安全和非安全。非安全状态也被称为正常世界。这使得操作系统可以和另一个trusted Os并行运行在同一个硬件上,并能针对某些软件、硬件入侵提供一定的保护。(笔者加:例如指纹识别数据就是运行在trustedOs中)。此技术可以支持系统被分割成安全世界和正常世界。就像ARMv7一样,安全监视器充当这个桥梁。

    ARMv8-A还提供了对虚拟化的支持,它只允许在正常状态下。这意味着虚拟机监控程序或虚拟机管理器可以在系统上运行, 并可以管理多个os。这些os运行在虚拟机中,但这对于这些os来说是完全隔离的,os间并不知晓,对于os来说它并不能区分自己是运行在真实的硬件上还是虚拟机环境中。

正常世界下具有以下同特权组件:

  • guest os 内核:这些内核包括在非安全EL1中运行的Linux或Windows或vxworks等支持虚拟化的os
  • 虚拟化:这是运行在EL2上的非安全区域,给os提供虚拟服务

安全世界下具有以下特权组件:

  • 安全固件:在应用程序处理器上,这个固件必须是在启动时运行的第一步。它提供多种服务,包括平台初始化、初始化trusted Os、启动安全监控
  • Trusted OS:为正常状态提供安全服务,并为执行安全或可信应用程序提供运行时环境

1、执行状态

ARMv8体系结构定义了两种执行状态:AArch64和AArch32,分别有64bit的寄存器和32bit的寄存器。虽然ARMv8 AArch32保留了ARMv7的特权定义,但在AArch64中,权限级别由异常级别确定。因此,在ELn执行状态对应于特权等级PLn。

当处于AArch64状态时,处理器执行A64指令集。当处于AArch32状态时,处理器可以执行A32(在体系结构的早期版本中称为ARM)或T32(Thumb)指令集。

ARM BIOS 授权公司 arm永久授权_arm开发

2、切换异常等级

在ARMv7体系结构中,处理器模式可以在特权软件控制下更改(CPSR寄存器),也可以在发生异常时自动更改。当发生异常时,内核保存当前执行状态和返回地址,进入所需模式,并可能禁用硬件中断。

应用程序以最低特权级别PL0(以前的非特权模式)运行。操作系统在PL1上运行,系统中的虚拟化扩展在PL2上运行管理程序。安全监视器作为在安全和非安全(正常)世界之间移动的网关,也可以在PL1上运行。

ARM BIOS 授权公司 arm永久授权_执行状态_02


ARM BIOS 授权公司 arm永久授权_arm开发_03


在AArch64中,处理器模式映射到异常级别,如图3-6所示

与在ARMv7(AArch32)中一样,当发生异常时,处理器将更改为支持异常处理的异常级别(模式)

ARM BIOS 授权公司 arm永久授权_arm开发_04


异常级别之间的切换遵循以下规则

  • 切换到更高的异常级别,例如从EL0到EL1,表示软件执行权限增加
  • 异常不能被切换到较低的异常级别
  • EL0级别没有异常处理,除非在高级的异常等级中需要处理
  • 异常会打破正常的程序流程,高于EL0的异常程序的执行入口是定义的异常向量表。异常包含如下情况,1、IRQ或FIQ中断 2、内存异常 3、未定义的指令 4、系统调用。允许用户对操作系统进行系统调用 5、安全监视器或陷入虚拟机监控程序
  • 通过执行ERET指令来结束异常处理并返回到上一个异常级别
  • 从异常返回可以保持在相同的异常级别,也可以输入较低的异常级别。无法切换到更高的异常级别
  • 安全状态会随着异常级别的变化而变化,从EL3重新调谐到非安全状态时除外

3、切换执行状态

有时你必须更改系统的执行状态。例如,如果你正在运行64位操作系统,并且希望在EL0上运行32位应用程序,则可能会出现这种情况。为此,系统必须更改为AArch32。当应用程序完成或执行返回操作系统时,系统可以切换回AArch64。AArch32操作系统无法加载64位应用程序。要在同一异常级别的执行状态之间进行更改,必须切换到更高的异常级别,然后返回到原始异常级别。例如,您可能有32位和64位应用程序在64位操作系统下运行。在这种情况下,32位应用程序可以执行并生成一条系统调用(SVC)指令,或接收一个中断,从而切换到EL1和AArch64。然后,操作系统可以执行任务切换并返回AArch64中的EL0。实际上,这意味着您不能混合使用32位和64位应用程序,因为它们之间没有直接的调用方式。您只能通过更改异常级别来更改执行状态。EL3处的代码无法将异常转移到更高的异常级别,因此无法更改执行状态,除非通过重置。
AArch64和AArch32执行状态之间更改时需要注意以下几点:

  • AArch64和AArch32执行状态都具有通常相似的异常级别,但安全操作和非安全操作之间存在一些差异。
  • 更改为AArch32需要从较高的异常级别转到较低的异常级别。这是通过执行ERET指令退出异常处理程序的结果
  • 如果在获取异常或从异常返回时,异常级别保持不变,执行状态无法更改
  • 当ARMv8处理器在特定异常级别的AArch32执行状态下运行时,它使用与ARMv7中相同的异常模型处理该异常级别的异常。在AArch64执行状态下,它使用异常处理模型见第10章AArch64异常处理

因此,这两种状态之间的转换是在安全监视器、虚拟机监控程序或操作系统级别执行的(特权级)。

在AArch64状态下执行的虚拟机监控程序或操作系统可以在较低的权限级别上支持AArch32操作。这意味着运行在AArch64中的操作系统可以同时承载AArch32和AArch64应用程序。类似地,AArch64虚拟机监控程序可以同时托管AArch32和AArch64 Guest Os,但AArch32不能支持64bit系统。

ARM BIOS 授权公司 arm永久授权_嵌入式硬件_05


对于实现的最高异常级别(Cortex-A53和Cortex-A57处理器上的EL3),异常时异常级别使用的执行状态是固定的。只能通过重置处理器来更改异常级别。

对于EL2和EL1,由第四章的系统寄存器控制