HarmonyOS内核源码分析,鸿蒙内核源码分析(异常接管篇) | | 中文注解HarmonyOS源码...

news/2024/7/4 8:33:27

为何要有异常接管?

拿小孩成长打比方,大人总希望孩子能健康成长,但在成长过程中总会遇到各种各样的问题,树欲静而风不止,成长路上有危险,有时是自己的问题有时是外在环境问题.就像抖音最近的流行口水歌一样,社会很单纯,复杂的是人啊,每次听到都想站起来扭几下.哎!

老衲到底做错什么了?

比如:老被小朋友欺负怎么弄? 发现乱花钱怎么搞? 青春期发育怎么应对? 失恋要跳楼又怎么办? 意思超过他的认知范围,就是靠它自己解决不了了,就需要有更高权限,更高智慧的人介入进来,帮着解决,干擦屁股的事.

那么应用程序就是那个小孩,内核就是监护人,有更高的权限,更高的智慧.而且监护人还不止一个,而是六个,每个监护人对应解决一种情况,情况发生了就由它来接管这件事的处理,小朋友你就别管了,先把你关家里,处理好了外面安全了再把应用程序放出来玩去.

这六个人处理问题都自带工具,有标准的解决方案,有自己独立的办公场所,办公场所就是栈空间(独立的),标准解决方案就是私有代码段,放在固定的位置.而自带的工具就是

SPSR_***,SP_***,LR_***寄存器组.详见 系列篇之工作模式篇

,这里再简单回顾下有哪些工作模式,包括小孩自己(用户模式)一共是七种模式.

七种工作模式

图来源于ARM720T.pdf第43页,在ARM体系中,CPU工作在以下七种模式中:

df003c206eb51e795e584d5848152e91.png

● 用户模式(usr):属于正常的用户模式,不能直接切换到其他模式,ARM处理器正常的程序执行状态。

● 快速中断模式(fiq):支持高速数据传输及通道处理,FIQ异常响应时进入此模式

● 外部中断模式(irq):用于通用中断处理,IRQ异常响应时进入此模式

● 管理模式(svc):操作系统保护模式,系统复位和软件中断响应时进入此模式(由系统调用执行软中断SWI命令触发)

● 数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于处理存储器故障、实现虚拟存储器和存储器保护。

● 系统模式(sys):运行具有特权的操作系统任务,与用户模式类似,但具有可以直接切换到其他模式等特权

● 未定义指令中止模式(und):处理未定义的指令陷阱,当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。

除用户模式外,其余6种工作模式都属于特权模式

● 特权模式中除了系统模式以外的其余5种模式称为异常模式

● 大多数程序运行于用户模式

● 进入特权模式是为了处理中断、异常、或者访问被保护的系统资源

● 硬件权限级别:系统模式 > 异常模式 > 用户模式

● 快中断(fiq)与慢中断(irq)区别:快中断处理时禁止中断

每种模式都有自己独立的入口和独立的运行栈空间. 系列篇之CPU篇

已介绍过只要提供了入口函数和运行空间,CPU就可以干活了.入口函数解决了指令来源问题,运行空间解决了指令的运行场地问题.

而且在多核情况下,每个CPU核的每种特权模式都有自己独立的栈空间.注意是特权模式下的栈空间,用户模式的栈空间是由用户(应用)程序提供的.

官方概念

异常接管是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作,例如打印异常发生时当前函数的调用栈信息、CPU现场信息、任务的堆栈情况等。

异常接管作为一种调测手段,可以在系统发生异常时给用户提供有用的异常信息,譬如异常类型、发生异常时的系统状态等,方便用户定位分析问题。

鸿蒙的异常接管,在系统发生异常时的处理动作为:显示异常发生时正在运行的任务信息(包括任务名、任务号、堆栈大小等),以及CPU现场等信息。

进入和退出异常方式

异常接管切换需要处理好两件事:

● 一个是代码要切到哪个位置,也就是要重置PC寄存器,每种异常模式下的切换方式如图:

57338897bc6d9dbb91ceacdaaa5e1cf7.png

● 另一个是要恢复每种模式的状态,即 CPSR(1个) 和 SPSR(共5个) 的关系,对M[4:0]的修改,如图:

119c1eb01d25a7089f7f42ba5182f52f.png

以下是M[4:0]在每种模式下具体操作方式:

dac5f0422fd4a0b0d95c1ed8109c9cdb.png

e36d148fe122f29c9b60307c26c8c089.png

栈帧

每个函数都有自己的栈空间,称为栈帧。调用函数时,会创建子函数的栈帧,同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长,也就是说栈底是高地址,栈顶是底地址. 详见 系列篇之用栈方式篇

以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。

堆栈分析原理如下图所示,实际堆栈信息根据不同CPU架构有所差异,此处仅做示意。

图中不同颜色的寄存器表示不同的函数。可以看到函数调用过程中,寄存器的保存。通过FP寄存器,栈回溯到异常函数的父函数,继续按照规律对栈进行解析,推出函数调用关系,方便用户定位问题。

2d8645490672935dd99017c21c0f2091.png

解读

● LR寄存器(Link Register),链接寄存器,指向函数的返回地址。

● R11:可以用作通用寄存器,在开启特定编译选项时可以用作帧指针寄存器FP,用来实现栈回溯功能。

GNU编译器(gcc)默认将R11作为存储变量的通用寄存器,因而默认情况下无法使用FP的栈回溯功能。为支持调用栈解析功能,需要在编译参数中添加-fno-omit-frame-pointer选项,提示编译器将R11作为FP使用。

● FP寄存器(Frame

Point),帧指针寄存器,指向当前函数的父函数的栈帧起始地址。利用该寄存器可以得到父函数的栈帧,从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。

当系统发生异常时,系统打印异常函数的栈帧中保存的寄存器内容,以及父函数、祖父函数的栈帧中的LR、FP寄存器内容,用户就可以据此追溯函数间的调用关系,定位异常原因。

六种异常模式实现代码/* Define exception type ID *///ARM处理器一共有7种工作模式,除了用户和系统模式其余都叫异常工作模式

#define OS_EXCEPT_RESET          0x00//重置功能,例如:开机就进入CPSR_SVC_MODE模式

#define OS_EXCEPT_UNDEF_INSTR    0x01//未定义的异常,就是others

#define OS_EXCEPT_SWI            0x02//软中断

#define OS_EXCEPT_PREFETCH_ABORT 0x03//预取异常(取指异常), 指令三步骤: 取指,译码,执行,

#define OS_EXCEPT_DATA_ABORT     0x04//数据异常

#define OS_EXCEPT_FIQ            0x05//快中断异常

#define OS_EXCEPT_ADDR_ABORT     0x06//地址异常

#define OS_EXCEPT_IRQ            0x07//普通中断异常

地址异常处理(Address abort)@ Description: Address abort exception handler

_osExceptAddrAbortHdl: @地址异常处理

SUB     LR, LR, #8                                       @ LR offset to return from this exception: -8.

STMFD   SP, {R0-R7}                                      @ Push working registers, but don`t change SP.

MOV     R0, #OS_EXCEPT_ADDR_ABORT                        @ Set exception ID to OS_EXCEPT_ADDR_ABORT.

B       _osExceptDispatch                                @跳到异常分发统一处理

快中断处理(fiq)@ Description: Fast interrupt request exception handler

_osExceptFiqHdl: @快中断异常处理

SUB     LR, LR, #4                                       @ LR offset to return from this exception: -4.

STMFD   SP, {R0-R7}                                      @ Push working registers.

MOV     R0, #OS_EXCEPT_FIQ                               @ Set exception ID to OS_EXCEPT_FIQ.

B       _osExceptDispatch                                @ Branch to global exception handler.

解读

● 快中断处理时需禁用普通中断

取指异常(Prefectch abort)

文章后续内容和相关附件可以点击下面的原文链接前往学习


http://www.niftyadmin.cn/n/3575469.html

相关文章

【听】另一种选择,面对不辛与现实如何脱困

人生不如意,事常八九,而某些重大变故或者事件可能会伴随人的一生,永远走不出的阴影,那么这种情况,我们需要如何脱困,如何才能走出阴影,回归正常的生活,另一种选择,这本书…

vs发布项目webconfig替换语法

关于vs发布项目时webconfig替换语法也是最近才学到的东西,写这篇文章就当是作个备忘录吧,如果能帮助别人能够学习到webconfig如何替换那就再好不过了。 1.认识一下web项目下的web.Debug.config和web.release.config的作用 刚开始学习的时候就没听说过这两…

VS2010读取txt文件在控制台输出中文时出现乱码解决办法

有时我们直接创建的txt文件是以UTF-8的格式存储的, 但是我们的控制台exe程序默认的是ANSI编码模式,于是不适配出现中文乱码的问题 这个时候我们就得该txt的编码方式为ANIS: 在运行在控制台就没出现读取txt中的中文乱码问题了:…

用户登录之后查询id android,Android客户端和服务端如何使用Token和Session

对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不知道为什么要用他?更不知道其原理,今天我就带大家一起分析分析这东西。一、我们先解释一下他的含义:1、Token的引入…

【听】离经叛道,如何激发创新能力

离经叛道,找正如书名一样,一些观点看似不合理,又在情理之中,尤其是在作者的阐述之下,教你如何激发创新能力。毫无疑问,规规矩矩,一层不变,这是完全没有创新的可能的,而关…

linux硬盘修复

badblocks -s -v /位置转载于:https://www.cnblogs.com/xiaonange/p/4065961.html

关于Java中的静态代码块

2019独角兽企业重金招聘Python工程师标准>>> 一.静态代码块 ①特点:随着类的加载而执行,且只执行一次,不管创建了多少次对象实例,这个类中的静态代码块只会在第一次创建类实例或者直接使用类名调用静态方法时执行一次&…