第二十九期-Linux内核的异常(1)

作者:罗宇哲,中国科学院软件研究所智能软件研究中心

上一章中我们介绍了与ARM64体系中的异常与中断。这一期我们将介绍Linux 4.19内核中的异常向量表。

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

上一期中我们提到,异常向量被保存在异常向量表中。在 /openeuler/kernel/blob/kernel-4.19/arch/arm64/kernel/entry.S 文件中我们可以找到定义异常向量表的汇编代码:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1cCKIR8-1588845472503)(media/68c504496e61df9d816b55137780a4ea.png)]
以上异常向量表共16项并被分为四组,每组包含四项并对应不同的异常处理情形。这四组表项从上到下对应的四种情形分别是[1][2]:

  • 异常级别EL1生成的异常,使用SP_EL0寄存器;内核不支持带有invalid后缀的异常处理,在entry.S文件中,我们可以找到,通过带有invalid后缀的异常向量可以调用inv_entry宏:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7XJyJHdp-1588845472520)(media/84bce66dd3a8dff9100fb6fd037995c7.png)]
    这段代码保存三个参数到X0、X1和X2寄存器,然后跳转到bad_mode函数。bad_mode函数在/openeuler/kernel/blob/kernel-4.19/arch/arm64/kernel/traps.c文件中可以找到:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jzNLP6fq-1588845472531)(media/c153f43186f45743c884dbe438af2d16.png)]
    该函数打印了异常发生的相关信息并调用local_daif_mask()函数设置调试掩码位D、系统错误掩码位A、中断掩码位I和快速中断掩码位F来禁止调试异常、系统错误异常、外部中断和快速中断。

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

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

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

其中kernel_ventry的定义在同一个文件中可以找到:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a0u4e9ou-1588845472538)(media/ab35bf253702e52a6094c430c1942d63.png)]
该宏的输入是当前异常级别el、跳转入口地址label和寄存器宽度regsize;寄存器宽度用来标识执行状态,regsize = 64标识aarch64执行状态,regsize = 32标识aarch32执行状态。.align 7表示把下一条指令对齐到27byte。该宏的主要作用是跳转到label所对应的地址处。

二、结语

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

参考文献
[1] https://blog.csdn.net/rikeyone/article/details/79919019
[2] 《Linux内核深度解析》,余华兵著,2019

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值