2 修改异常级别
在ARMv7架构中,当发生异常,处理器模式可能被特权软件控制或自动改变。当异常产生时,core保存当前的异常状态和返回地址,进入要求的模式,并可能关闭硬件中断。
在下列表中做了总结。应用运行在最低特权级,PL0,之前无权限模式。操作系统运行在PL1,在系统中虚拟化的扩展的hypervisor运行在PL2。secure monitor,作为从secure和非secure world移动的网关,也运行在PL1。
ARMv7 processor modes
Mode | Function | Secure state | Privilege level |
User | 大多数应用运行的非特权级模式 | Both | PL0 |
FIQ | 进入FIQ中断异常 | Both | PL1 |
IRQ | 进入IRQ中断异常 | Both | PL1 |
SVC | 进入reset或当SVC在执行时 | Both | PL1 |
MON | 当SMC执行时或当处理器产生了配置安全处理的异常时。用于在安全和非安全状态之间的切换 | Secure only | PL1 |
ABT | 进入内存访问异常 | Both | PL1 |
UND | 进入一个未定义指令的执行 | Both | PL1 |
SYS | 特权模式,与用户模式共享寄存器 | Both | PL1 |
HYP | 进入hypervisor 调用和hyp trap异常 | 非安全 | PL2 |
在AArch64中,处理器模式被映射到异常模式如下图所示。因为在ARMv7中,当异常发生时,处理器修改到支持处理异常的异常级别。
异常级别的变化遵循如下规则:
(1)移动到更高的异常级别,比如从EL0到EL1,表明增加了软件异常特权。
(2)异常不能发生在更低的异常级别。
(3)在EL0中没有异常处理,异常必须处理在更高的异常级别。
(4)异常会导致一些程序流程的修改。异常处理开始执行在异常级别高于EL0,从一个定义的与异常相关的向量表。异常包括:
- 如IRQ和FIQ中断
- 内存系统abort
- 未定义指令
- 系统调用。这允许非特权软件通过系统调用到操作系统
- secure monitor或hypervisor陷入
(5)结束异常处理并通过执行ERET指令发出返回之前的异常级别。
(6)从异常返回可以保持在相同的异常级别或进入到一个更低的异常级别。它不能移动到更高的异常级别。
(7)安全状态随着异常级别的修改改变,除了当从EL3返回到非安全状态。看switching between secure and non-secure state。
3 修改执行状态
存在你必须修改你的系统的执行状态。比如,如果你运行在64bit的操作系统,想要运行32bit的应用在EL0。为实现它,系统必须修改为AArch32。
当应用完成或执行返回到OS,系统可以切回到AArch64。下图显示了你不能做这个使用其他方法。AArch32操作系统不能控制64bit应用。
为了在相同异常级别修改执行状态,你必须切换到更高的异常级别,然后返回到原始的异常级别。比如,你可能有32bit和64bit应用运行在64bit OS下。在这种情况下,32bit应用可以执行并产生SVC指令,或接受中断,导致切换到EL1和AArch64。OS然后进行任务切换并返回到AArch64的EL0。通常来说,这意味着你不能有32bit和64bit应用混合,因为没有直接方式来直接在它们之间进行调用。
你只能通过改变异常级别来改变执行状态。异常可能从AArch32切换到AArch64,并返回时从AArch64切换到AArch32。
在EL3上的代码不能让异常进入更高异常级别,因此不能修改执行状态,除了通过reset。
当在AArch64和AArch32之间进行执行状态变化时,下列为一些点的总结:
(1)AArch64和AArch32执行状态有类似的异常级别,但它们在安全和非安全操作方面有一些异常。当异常产生时处理器的执行状态可以限制对其他异常级别有用的异常级别。
(2)变化到AArch32要求从更高异常级别到更低的异常级别。这是通过执行ERET指令执行异常处理的结果。看Exception handling instructions。
(3)变化到AArch64要求从更低的异常级别到更高的异常级别。这是由于指令的执行或外部的信号导致的。
(4)当进入到一个异常或从异常返回,若异常级别仍保持相同,执行状态不会改变。
(5)当ARMv8处理器运行在某个异常级别的AArch32执行状态时,它使用与ARMv7相同的异常模式来进入到异常级别。在AArch64执行状态时,它使用异常处理模式。
两个状态的内部工作由secure monitor,hypervisor或操作系统发出。执行在AArch64状态的hypervisor或操作系统支持AArch32运行在更低的特权级别。这意味着运行在AArch64的OS可以控制AArch32和AArch64 guest操作系统。但是,一个32位操作系统不能控制64位应用且一个32位hypervisor不能控制64位guest操作系统。
对于更高实现的执行异常级别(Cortex-A53上的EL3和Cortex-A57),当异常被修复,执行状态被用于每个异常级别。通过复位处理器,可以修改异常级别。对于EL2和EL1,它由系统寄存器来控制。