[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

枕上诗书闲处好,门前风景雨来佳。这篇文章主要讲述[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2相关的知识,希望能为你提供帮助。
“  一个行者问老和尚:“您得道前,做什么?”老和尚:“砍柴担水做饭。”行者问:“那得道后呢?”老和尚:“砍柴担水做饭。”行者又问:“那何谓得道?”老和尚:“得道前,砍柴时惦记着挑水,挑水时惦记着做饭;得道后,砍柴即砍柴,担水即担水,做饭即做饭。”



很多时候平凡的日子不平凡。


??上一次我们??讲到ARM v8的异常向量表(??上一期节目点击这里??)。我们以data abort这个异常为例子。假设data abort发生在EL1这个异常级别里。它会从异常向量表里跳转到el1_sync这个汇编函数里。


[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



第270行的kernel_entry是一个汇编的宏,用来保存发生异常现场,把相关CPU寄存器保存到EL1的栈里,这里和ARM32的代码类似,会有一个栈框,这栈框的大小是S_FRAME_SIZE,该栈框大小是一个软件定义的,而非硬件定义,也就是说你可以实现一个和Linux实现不一样的栈框。


接下来读取esr_el1j寄存器的值。ESR_EL1寄存器全称exception syndrome register,可以参考ARM v8手册第D10.2.36章内容。这个寄存器有点类似ARM v7中的DFSR寄存器。这个寄存器的具体定义在D10.2.39章。
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



在这个寄存器里,EC域保存了异常的类型(exception class)。对于current EL的data abort,可以看手册的定义,当EC== 100101的时候就是表示当前EL发生了data abort异常。


[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



这个值和代码里273行的ESR_ELx_EC_DABT_CUR的定义是吻合的,它定义在arch/arm64/include/asm/esr.h文件中。
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



所以根据274行代码会跳转到el1_da汇编函数里。这个函数也是在entry.S文件里。
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



首先去读取far_el1寄存器。这个寄存器是在第D10.2.40章里。这寄存器保存了导致异常发生的虚拟地址,那我们操作系统就可以读取这个寄存器来继续后续的异常处理,它很类似ARM V7中的DFAR寄存器。
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



第二步是开启中断。
第三步跳转到do_mem_abort函数里。


[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



【[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2】这个函数有三个参数,其中第一个和第二参数需要注意,第一个参数是异常发生时候那个错误的虚拟地址,即读取的FAR_EL1寄存器,第二参数是ESR_EL1寄存器。不过第二个参数有不少花头。


ESR_EL1寄存器的bit  26~31比特位是Exception class,bit 0 ~24是ISS域,它会根据 exception class的不同 而有不同的解读,也就是说,Exception class不同,ISS域的编码是 不一样的。对应Data abort这个类型来说,ISS的编码是在ARM v8手册的2460页里。见下面这个图。


[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片


其中bit 0~5是指示具体发生了那种类型的data abort。我们以level 3的页表转换错误为例(translation fault level 3),我们看到在DFSC域里,它是000111,也就是7号。
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



我们看一下Linux内核代码,在arch/arm64/mm/fault.c文件中有一个fault_info[ ]的数组,我们看看7号是对应是神马?
[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片



我们惊奇发现fault_info[ ]数组里7号就是level 3的translation fault,对应的处理函数是do_page_fault函数,见第386行代码。大家可以从0开始来数这个数组。


我们通过两期的笨叔点滴来go through了一遍ARM V8上发生异常的台前幕后,希望对大家有所帮助。更多精彩内容敬请关注笨叔的第二季《奔跑吧Linux内核》配套视频。




[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片

第二季来啦




大家期待的第二季视频来了,我们这次是进程管理、锁机制以及中断管理三合一,加量不加价。旗舰篇还是原价1199,现在特价999。


初级篇: 笨叔和大家彻底理清进程管理、锁机制以及中断管理相关的概念。比如说:
  1. 进程的生命周期
  2. 进程控制块
  3. 进程调度的本质
  4. CFS调度器
  5. 进程切换是怎么玩
  6. SMP负载均衡
  7. 大小核调度是怎么回事
  8. 为啥需要中断
  9. 中断发生了ARMv7和ARMv8处理器做了啥
  10. 中断底层汇编处理
  11. 中断上下半部
  12. 如何写好一个中断处理函数
  13. 软中断是怎么回事
  14. tasklet和workqueue怎么玩
  15. 什么是中断上下文
  16. 为啥需要锁
  17. 什么是原子操作
  18. ARMv7和ARMv8处理器怎么进行原子操作的
  19. 内存屏障是什么
  20. spinlock怎么用
  21. 信号量和mutex该选谁
  22. RCU怎么用
  23. 为啥这里要添加一个锁
  24. ...


旗舰篇包含初级篇内容,还包含如下特色:
  1. 额外增加核心代码的导读,真正做到自主可控。
  2. 综合创新实验,笨叔带领大家在树莓派上玩一个小OS。
  3. 面试宝典,那些年我们被虐过的面试题目。


[笨叔点滴15]ARMv8里异常处理哪些蛇神牛鬼 2

文章图片

 



    推荐阅读