Linux 内核的异常(1)

举报
云舒云卷 发表于 2020/05/18 11:45:09 2020/05/18
【摘要】 上一章中我们介绍了与 ARM64 体系中的异常与中断。这一期我们将介绍 Linux 4.19 内核中的异常向量表。

一、Linux 4.19内核的异常向量表

上一期中我们提到,异常向量被保存在异常向量表中。在 /openeuler/kernel/blob/kernel-4.19/arch/arm64/kernel/entry.S 

文件中我们可以找到定义异常向量表的汇编代码:

以上异常向量表共16项并被分为四组,每组包含四项并对应不同的异常处理情形。这四组表项从上到下对应的四种情形分别是[1,2]:

  • 异常级别 EL1 生成的异常,使用 SP_EL0 寄存器;内核不支持带有 invalid 后缀的异常处理,在 entry.S 文件中,我们可以找到,通过带有 invalid 后缀的异常向量可以调用 inv_entry 宏:

这段代码保存三个参数到 X0、X1和X2 寄存器,然后跳转到 bad_mode 函数。bad_mode 函数在 /openeuler/kernel/blob/kernel-4.19/arch/arm64/kernel/traps.c 文件中可以找到:

该函数打印了异常发生的相关信息并调用 local_daif_mask()函数设置调试掩码位D、系统错误掩码位A、中断掩码位I和快速中断掩码位F来禁止调试异常、系统错误异常、外部中断和快速中断。

  • 异常级别 EL1 生成的异常,使用当前异常级别的 SP_ELx 寄存器;

  • 64位应用程序在异常级别 EL0 生成的异常。例如64位用户态程序发生系统调用,处理器从异常级别 EL0 切换到异常级别 EL1,并且使用 aarch64 执行状态处理异常;

  • 32位应用程序在异常级别 EL0 生成的异常。例如32位用户态程序发生系统调用,处理器从异常级别 EL0 切换到异常级别 EL1,并且使用 aarch32 执行状态处理异常;

其中 kernel_ventry 的定义在同一个文件中可以找到:

该宏的输入是当前异常级别 el、跳转入口地址 label 和寄存器宽度 regsize;寄存器宽度用来标识执行状态,regsize = 64标识 aarch64 执行状态,regsize = 32标识 aarch32 执行状态。.align 7表示把下一条指令对齐到27 byte。该宏的主要作用是跳转到 label 所对应的地址处。

二、结语

本期我们介绍了 Linux 4.19 内核的异常向量表,下一期我们将介绍 Linux 4.19 内核的异常处理。



参考文献

[1]https://blog.csdn.net/rikeyone/article/details/79919019

[2]《Linux内核深度解析》,余华兵著,2019


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。