1、异常等级
ARMv8处理器运行时,运行在4种异常等级的其中一个等级。和ARMv7的特权等级类似,在AArch64运行状态,异常等级决定了特权等级。EL0~EL3,数字越高,异常等级越高。
EL0 | 普通用户应用 |
EL1 | 操作系统内核 |
EL2 | Hypervisor |
EL3 | 低层级固件(包括Secure Monitor) |
一般情况下,应用程序、操作系统内核、Hypervisor,占有一个单独的异常等级。但是有个例外,就是像KVM这样的在内核中的Hypervisor,会运行在EL1和2中。
2、安全状态
ARMv8提供了两种安全状态:Secure(Secure World)和Non-Secure (Normal World)。这使得一个操作系统,可以和一个可信赖的操作系统同时运行在同一个硬件上,并对软件或者硬件的攻击提供保护。
ARMv8同时也提供了对虚拟化的支持,但是仅仅在Normal World。也就是说,Hypervisor,或者VMM(Virtual Machine Manager) 能够运行并管理多个guest操作系统。每个操作系统互相不知道在和其他操作系统共享系统的时间片。
Normal World有如下的特权组件:Guest OS、Hypervisor
Secure World有如下特权组件:Secure firmware、Trusted OS。其中Secure firmware必须是启动时第一个启动的东西,它提供了平台初始化、Trusted OS的安装、对Secure Monitor的调用等服务。Truested OS为Normal World提供了安全服务、和可信赖的应用的运行环境。
Secure Monitor运行在最高的异常等级。
3、运行状态
AARMv8架构有两种运行状态:
1)AArch64
运行64bit宽通用寄存器。
AArch64的特权等级,由异常等级决定。因此运行在ELn的特权等级就是PLn。
在AArch64状态,处理器执行A64指令集。
2)AArch32
运行32bit宽通用寄存器。
AArch32保留了ARMv7的特权等级。
在AArch32状态,处理器执行A32或者T32(Thumb)指令集。
注意:Trusted OS在AArch32运行在EL3,但是在AArch64运行在EL1。
4、改变异常等级(EL0~EL3之间切换)
在ARMv7架构,处理器模式的改变可以通过如下两个途径:
1)特权软件控制
2)当异常发生
当异常发生时,处理器核会保留当前运行状态和返回地址,进入需要的模式,如果需要的话会禁止中断 。
在ARMv8上,可以对应成如下图:
异常等级之间的迁移,遵循如下规则:
1)从低等级迁移到高等级,比如EL0到EL1,表明增加软件执行特权。
2)异常不能从高等级,到低等级。
3)EL0没有异常处理,异常处理必须在更高等级执行。
4)异常包括如下几种
a、像IRQ、FIQ这样的中断
b、内存系统退出
c、未定义的指令
d、系统调用。允许非特权软件通过操作系统进行系统调用。
e、Secure Monitor或者Hypervisor陷阱。
5)执行ERET指令,可以在异常处理完成后,返回到之前的异常等级。
6)从一个异常处理返回后,可以保持原来的异常等级,也可以回到第一级的等级,但是不能到更高的等级。
7)只有从EL3返回到Non-Secure状态,才会改变安全状态,其他异常等级的改变不会改变安全状态。
5、改变运行状态(AArch64和AArch32互相切换)
有些时候你必须改变系统的运行状态,比如在64bit操作系统的EL0等级,运行32bit的应用程序,就必须迁移到AArch32。当这个应用程序运行完成,或者返回到OS运行时,就可以切回AArch64了。
AArch32的操作系统,不能运行64bit的应用程序。
在同一个异常等级,如果想在两种运行状态(AArch64和AArch32),必须先切换到更高的异常等级,然后再返回到原来的异常等级。例如,在64bit操作系统上,有32bit和64bit两种应用程序在运行,这种情况下32bit应用程序可以执行和产生一个SVC(Supervisor Call)指令,或者接收某个中断,导致切换到EL1和AArch64。OS会接下来做个任务切换并返回到EL0的AArch64。所以实际中,不能有一个32bit和64bit混合的应用程序,因为没有直接的方法在二者之间进行调用。
只能通过改变异常等级,来改变运行状态。发生一个异常后,或许可以将运行状态从AArch32改到AArch64;从异常返回,或许可以将运行状态从AArch64改回AArch32。
在EL3等级的话,因为不能通过异常进入更高异常等级,所以不能改变运行状态,除非重启。
AArch64和AArch32两个运行状态互相切换的一些总结:
1)AArch64和AArch32有类似的异常等级,但是在安全状态和非安全状态之间的操作是有些不同的。当异常发生时的运行状态,会限制可以切换到另一个运行状态的异常等级。
2)从AArch64变到AArch32,需要从更高的异常等级,到更低的异常等级。这是从某个异常处理返回的结果(通过执行ERET指令)。
3)从AArch32切换到AArch64,需要从更低的异常等级,到更高的异常等级。这个异常,可以是执行某个指令的结果,也可以是外部信号。
4)如果执行某个异常,或者从异常处理返回时,异常等级没有改变,那么运行状态也不会改变。
如下图所示
1)64bit的Hypervisor,可以运行64bit和32bit的OS
32bit的Hypervisor,不能运行64bit的OS
2)64bit的OS,可以运行64bit、32bit的应用程序
32bit的OS,不能运行64bit的应用程序。
6、改变安全状态
Secure World和Non-Secure World之间的切换,后续会做讲解。
=========================================================================
注意:本文为本人原创,版权所属为个人所有,欢迎转载,但是转载请注明出处。
=========================================================================