深入讲解ARMv8 异常处理简介

内核稳定性问题复杂多样,最常见的莫过于“kernel panic”,意为“内核恐慌,不知所措”。这种情况下系统自然无法正常运转,只能自我结束生命,留下死亡信息。诸如:

“Unable to handle kernel XXX at virtual address XXX”

“undefined instruction XXX”

“Bad mode in Error handler detected on CPUX, code 0xbe000011 -- SError”

......

这些死亡信息是系统在什么状态下产生?如何产生?以及如何处理?本文主要从这三个方面介绍ARMv8架构下CPU的异常处理流程。

一、ARMv8异常简介

1.异常级别

不同于Armv7架构采用CPU模式切换的方式进行异常处理,Armv8架构定义了一组全新的异常级别进行异常处理,即EL0至EL3,有如下特性:

  • 如果ELn为异常级别,则n的值增加表示软件执行特权增加。
  • EL0处的执行称为无特权执行,不能处理异常。
  • EL2提供对虚拟化的支持。
  • EL3提供了在两个安全状态(安全状态和非安全状态)之间切换的支持。

一个实现可以不包括所有的异常级别,但都必须包括EL0和EL1。EL2和EL3是可选的。

如下是典型的异常级别使用模型:

2. 同步异常和异步异常

如果满足以下所有条件,则将异常描述为同步的:

  • 由于直接执行某个指令而产生异常。
  • 异常处理程序的返回地址可以表明导致该异常的指令。
  • 异常是精确的。

如果满足以下任一条件,则将异常描述为异步的:

  • 不是因为直接执行某条指令而产生异常。
  • 异常处理程序的返回地址不可以表明导致该异常的指令。
  • 异常是不精确的。

3. 主要寄存器

(1)通用寄存器R0-R30

在基本指令集处理指令时,将使用通用寄存器组。它包括31个通用寄存器R0-R30。这些寄存器可以作为31个64位寄存器X0-X30或31个32位寄存器W0-W30进行访问。

(2)堆栈指针寄存器SP

在AArch64状态下,除了通用寄存器外,还为以下每个异常级别实现了专用的堆栈指针寄存器,

堆栈指针寄存器为:

  • SP_EL0和SP_EL1。
  • 如果实现包括EL2,则为SP_EL2。
  • 如果实现包括EL3,则为SP_EL3。

堆栈指针寄存器选择:

在EL0上执行时,处理器使用EL0堆栈指针SP_EL0。在其他任何异常级别执行时,可以将处理器配置为使用SP_EL0或配置为对应该异常级别的堆栈指针SP_ELx。默认情况下,采用目标异常级别的堆栈指针SP_ELx。例如,EL1的异常选择SP_EL1,软件可以在目标异常级别执行的时候通过更新PSTATE.SP来指向SP_EL0的堆栈指针。

可以通过异常级别的堆栈指针后缀表明所选的堆栈指针:

t表明使用SP_EL0堆栈指针。

h表明使用SP_ELx堆栈指针。

t和h后缀基于线程(thread)和处理程序(handler)的首字母。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值