带中文注释更多信息请访问:Harmonyos技术社区https://harmonyos.51cto.com,与华为官方合建为什么会出现异常接管?例子。大人总是希望孩子能够健康成长,但在成长过程中总会遇到各种各样的问题。外部环境问题。就像最近流行的口水歌抖音一样,社会很简单,复杂的是人。每次听到都想站起来扭几下。嘿!我做错了什么?例如:如果你总是被孩子欺负怎么办?发现乱花钱怎么办?高智商的人介入帮助解决问题。那么应用程序就是孩子,内核就是守护神,拥有更高的权限和更高的智慧。而且守护者不是只有一个,而是六个,每个守护者要解决一种情况。当情况发生时,它会接手处理这件事。别管它,孩子们。先把你锁在家里,等外面安全了再放开应用玩。这六个人用自己的工具、标准的解决方案和自己独立的办公空间来处理问题。办公空间是栈空间(独立),标准方案是私有代码段,放在固定位置。这些工具是SPSR_***、SP_***、LR_***寄存器组。详情请参考该系列的工作模式。这里简要回顾一下工作模式,包括孩子本身(用户模式)。共有七种。模式。七种工作模式的图表来自ARM720T.pdf的第43页。在ARM系统中,CPU工作在以下7种模式:●用户模式(usr):属于普通用户模式,不能直接切换到其他模式。ARM处理器的正常程序执行状态。●快速中断模式(fiq):支持高速数据传输和通道处理,FIQ异常响应时进入该模式●外部中断模式(irq):用于一般中断处理,IRQ异常响应时进入该模式●管理模式(svc):操作系统保护模式,当系统复位和软件中断响应时进入该模式(由系统调用触发执行软中断SWI命令)数据访问终止模式(abt):数据或指令预取时进入该模式被终止,可以用来处理内存故障,实现虚拟内存,内存保护。●系统模式(sys):以特权运行操作系统任务,类似于用户模式,但具有直接切换到其他模式等特权●未定义指令中止模式(und):处理未定义指令陷阱,当未定义时进入该模式执行指令,可用于支持硬件协处理器的软件仿真。除用户模式外,其余6种工作模式均属于特权模式。特权模式中除系统模式外的其他5种模式称为异常模式。大多数程序运行在用户态。进入特权模式是为了处理中断、异常,或者访问受保护的系统资源●硬件特权级别:系统模式>异常模式>用户模式??●快速中断(fiq)和慢速中断(irq)的区别:快速中断期间禁止中断加工。每种模式都有自己独立的入口和独立的运行栈空间。该系列的CPU已经介绍过,只要提供入口函数和运行空间,CPU就可以工作。入口函数解决了指令来源的问题,运行空间解决了指令运行的地方问题。而在多核的情况下,每个CPU核的每个特权模式都有自己独立的栈空间。注意是特权模式下的栈空间,用户模式下的栈空间由用户(应用)程序提供。异常接管的官方概念是操作系统为处理运行过程中发生的异常情况(芯片硬件异常)而采取的一系列动作,如异常发生时打印当前函数的调用栈信息,CPUsite信息,以及任务的堆栈状态。异常接管作为一种调试手段,可以在系统发生异常时为用户提供有用的异常信息,如异常类型、异常发生时的系统状态等,方便用户定位和分析问题。鸿蒙的异常接管,当系统异常时,处理动作为:显示异常时正在运行的任务信息(包括任务名称、任务编号、堆栈大小等),以及CPUsite等信息。异常模式的进入和退出异常接管切换需要处理两件事:一是应该切换代码的??地方,即PC寄存器需要复位。各异常模式下的切换方式如图所示:各模式的状态,即CPSR(1)和SPSR(共5个)的关系,M[4:0]的修改,如图如图:下面是M[4:0]在各个模式下的具体操作方法:栈帧每个函数都有自己的栈空间,称为栈帧。当一个函数被调用时,会创建子函数的栈帧,同时将函数参数、局部变量和寄存器压入栈中。栈帧是从高地址向低地址增长的,也就是说栈底是高地址,栈顶是底地址。LR、SP、FP寄存器的历史值。堆栈分析的原理如下图所示。实际的堆栈信息根据不同的CPU架构而有所不同。这仅用于说明。图中不同颜色的寄存器代表不同的功能。您可以在函数调用期间看到寄存器的保存。通过FP寄存器,堆栈回溯到异常函数的父函数,按照规则继续分析堆栈,引入函数调用关系,方便用户定位问题。解释●LR寄存器(LinkRegister),链接寄存器,指向函数的返回地址。●R11:可作为通用寄存器使用,在特定编译选项使能时可作为帧指针寄存器FP,实现堆栈回溯功能。GNU编译器(gcc)默认使用R11作为存放变量的通用寄存器,所以默认不能使用FP的stacktraceback功能。为了支持调用栈解析功能,需要在编译参数中加入-fno-omit-frame-pointer选项,提示编译器使用R11作为FP。●FP寄存器(FramePoint),帧指针寄存器,指向当前函数的父函数的栈帧起始地址。使用该寄存器可以得到父函数的栈帧,从栈帧中获取父函数的FP,可以得到祖父函数的栈帧。以此类推,可以追溯程序调用栈,得到函数之间的调用关系。当系统发生异常时,系统打印异常函数栈帧中保存的寄存器内容,以及父函数和祖父函数栈帧中LR和FP寄存器的内容,并用户可以追踪函数之间的调用关系,定位异常。原因。六种异常模式实现代码/*DefineexceptiontypeID*///ARM处理器一共有7种工作模式,除用户模式和系统模式外,其余称为异常工作模式#defineOS_EXCEPT_RESET0x00//复位函数,例如:开机后进入CPSR_SVC_MODE模式#defineOS_EXCEPT_UNDEF_INSTR0x01//其他未定义异常#defineOS_EXCEPT_SWI0x02//软中断#defineOS_EXCEPT_PREFETCH_ABORT0x03//预取异常(异常取指),指令三步:取指,译码,执行,#defineOS_EXCEPT_DATA_ABORT0x04//数据异常#defineOS_/Quick_EXADR0CEPTADDR0x05//地址异常#defineOS_EXCEPT_IRQ0x07//普通中断异常地址异常处理(Addressabort)@Description:Addressabortexceptionhandler_osExceptAddrAbortHdl:@地址异常处理SUBLR,LR,#8@LRoffsettoreturnfromthisexception-SP,{RM0DR7}@Pushworkingregisters,butdon`tchangeSP.MOVR0,#OS_EXCEPT_ADDR_ABORT@SetexceptionIDtoOS_EXCEPT_ADDR_ABORT.B_osExceptDispatch@跳转到异常分发统一处理快速中断处理(fiq)@Description:Fastinterruptrequestexceptionhandler_osExceptFiqHdl:@fastinterrupt异常处理SUBLR@LRetn-extorp-extorm#settorm,LRofftion,4.STMFDSP,{R0-R7}@Pushworkingregisters.MOVR0,#OS_EXCEPT_FIQ@SetexceptionIDtoOS_EXCEPT_FIQ.B_osExceptDispatch@Branchtoglobalexceptionhandler.解读●快中断处理时需禁用普通中断取指异常(Prefectchabort)@Description:Prefectchabortexceptionhandler_osExceptPrefetchAbortHdl:#ifdefLOSCFG_GDB#if__LINUX_ARM_ARCH__>=7GDB_HANDLEOsPrefetchAbortExcHandleEntry#endif#elseSUBLR,LR,#4@LRoffsettoreturnfromthisexception:-4.STMFDSP,{R0-R7}@Pushworkingregisters,butdon`tchangeSP.MOVR5,LRMRSR1,SPSRMOVR0,#OS_EXCEPT_PREFETCH_ABORT@SetexceptionIDtoOS_EXCEPT_PREFETCH_ABORT.ANDR4,R1,#CPSR_MASK_MODE@InterruptedmodeCMPR4,#CPSR_USER_MODE@UsermodeBEQ_osExcPageFault@Branchifusermode_osKernelExceptPrefetchAbortHdl:MOVLR,R5B_osExceptDispatch@Branchtoglobalexceptionhandler.#endif数据访问异常(Dataabort)@Description:Dataabortexceptionhandler_osExceptDataAbortHdl:@Dataabortexceptionhandler_osExceptDataAbortHdl:@Dataabortexceptionhandling,pagemissingisadataabort#ifdefLOSCFG_GDB#if__LINUX_ARM_ARCH__>=7GDB_HANDLEOsDataAbortExcHandleEntry#endif#elseSUBLR,LR,#8@LRoffsettoreturnfromthisexception:-8,istm0regbutdon`tchangeSP.MOVR5,LRMRSR1,SPSRMOVR0,#OS_EXCEPT_DATA_ABORT@SetexceptionIDtoOS_EXCEPT_DATA_ABORT.B_osExcPageFault@跳转到缺页异常处理#endif软件中断处理(swi)@Description:Softwareinterruptexceptionhandler_osExceptSwiHdl:@Softwareinterruptexceptionhandler_osExceptSwiHdl:@Softwareinterrupt异常处理SUBSP,SP,#(4*16)@先申请16个栈空间用于本次处理软中断STMIASP,{R0-R12}@保存R0-R12寄存器值MRSR3,SPSR@本模式读取SPSR值MOVR4,LR@保存跳回寄存器LRANDR1,R3,#CPSR_MASK_MODE@Interruptedmode获取中断模式CMPR1,#CPSR_USER_MODE@Usermode是用户态BNEOsKernelSVCHandler@Branchifnotusermode在非用户态跳转@当是用户态时,获取SP和LR送出值MOVR0,SP@获取SP值,R0将作为OsArmA32SyscallHandleSTMFDSP的参数!,{R3}@SavetheCPSR入栈保存CPSR值ADDR3,SP,#(4*17)@Offsettopc/cpsrstorage跳转到PC/CPSR存储位置STMFDR3!,{R4}@SavetheCPSRandr15(pc)保存LR寄存器STMFDR3,{R13,R14}^@Saveusermoder13(sp)andr14(lr)保存用户态SP和LR寄存器SUBSP,SP,#4PUSH_FPU_REGSR1@保存中断模式(userModemode)MOVFP,#0@InitframepointerCPSIEI@开启中断,表示系统调用时可以响应中断BLXOsArmA32SyscallHandle/*交给C语言处理系统调用*/CPSIDI@执行后续指令前必须关闭中断POP_FPU_REGSR1@弹出FPvaluetoR1ADDSP,SP,#4@定位到旧的SPSR值保存的位置LDMFDSP!,{R3}@FetchthereturnSPSR弹出旧的SPSR值MSRSPSR_cxsf,R3@SetthereturnmodeSPSR在此模式下恢复SPSR值@weareleavingtousermode,我们需要恢复USERmoder13(sp)andr14(lr)的值。@ldmiawith^willreturntheusermoderegisters(providedthatr15isRinotgi2)}@RestoreregisterR0-R12LDMFDSP,{R13,R14}^@RestoreusermodeR13/R14恢复用户模式??R13/R14寄存器ADDSP,SP,#(2*4)@定位保存旧PC值LDMFDSP!,{PC}^@Returntouser切换回用户运行正常中断处理(irq)的模式OsIrqHandler:@硬中断处理,现在切换到硬中断堆栈SUBR0,SP,#(4*4)@r0=sp-16MRSR1,SPSR@获取程序状态控制寄存器MOVR2,LR@r2=lr/*disableirq,switchtosvcmode*/@superuser模式(SVC模式),主要用于SWI(软件中断)和OS(操作系统)CPSIDi,#0x13@切换到SVC模式,一旦切换到这里,后面的指令都会进入SVC的栈@CPSIDi是一个off-interrupt指令,对应CPSIE/*pushspsrandpcinsvcstack*/STMFDSP!,{R1,R2}@实际上会SPSR,LR入栈,入栈顺序为R1,R2,SP自增STMFDSP,{LR}@LR再入栈,SP不自增ANDR3,R1,#CPSR_MASK_MODE@得到CPUCMPR3的工作模式,#CPSR_USER_MODE@中断是否发生在用户模式?BNEOsIrqFromKernel@Interrupt在用户态没有发生,跳转到OsIrqFromKernel/*pushusersp,lrinsvcstack*/STMFDSP,{R13,R14}^@sp和LR入svc栈进行解释●普通中断处理可以响应快中断未定义异常处理(undef)@Description:Undefinedinstructionexceptionhandler_osExceptUndefInstrHdl:@出现未定义的指令处理#ifdefLOSCFG_GDBGDB_HANDLEOsUndefIncExcHandleEntry#else@LRoffsettoreturnfromthisexception:0.STMFDSP,{R0-R7}@Pushworkingregisters,butdon`tchangeSP.MOVR0,#OS_EXCEPT_UNDEF_INSTR@SetexceptionIDtoOS_EXCEPT_UNDEF_INSTR.B_osExceptDispatch@Branchtoglobalexceptionhandler.#endif异常分发统一处理_osExceptDispatch:@Exception模式统一分发处理MRSR2,SPSR@SaveCPSRbeforeexception.MOVR1,LR@SavePCbeforeexception.SUBR3,SP,#(8*4)@Savethestartaddressofworkingregisters.MSRCPSR_c,#(CPSR_INT_|CPSR_SVC_MODE)@SwitchtoSVCmode,and禁用所有中断MOVR5,SPEXC_SP_SET__exc_stack_top,OS_EXC_STACK_SIZE,R6,R7STMFDSP!,{R1}@PushExceptionPCSTMFDSP!,{LR}@PushSVCLRSTMFDSP!,{R5}@PushSVCSPSTMFDSP!,{R8-R12}@PushoriginalR12-R8,LDMFDRR1!,1{R4@MoveoriginalR7-R0fromexceptionsstacktooriginalstack.STMFDSP!,{R4-R11}STMFDSP!,{R2}@Pushtask`sCPSR(即exceptionSPSR).CMPR0,#OS_EXCEPT_DATA_ABORT@是数据异常吗?BNE1f@不跳转到锚点1MRCP15,0,R8,C6,C0,0@R8=C6(内存故障地址)0(访问数据故障)MRCP15,0,R9,C5,C0,0@R9=C5(内存故障状态)0(整个指令缓存无效)B3f@跳转到锚点3执行1:CMPR0,#OS_EXCEPT_PREFETCH_ABORT@是否预取异常?BNE2f@isn'tjumpingtoanchorpoint2MRCP15,0,R8,C6,C0,2@R8=C6(memoryInvalidaddress)2(invalidaccessinstruction)MRCP15,0,R9,C5,C0,1@R9=C5(内存失效状态)1(虚拟地址)B3f@跳转到锚点3执行2:MOVR8,#0MOVR9,#03:ANDR2,R2,#CPSR_MASK_MODECMPR2,#CPSR_USER_MODE@UsermodeBNE4f@notusermodeSTMFDSP,{R13,R14}^@saveusermodespandlr4:SUBSP,SP,#(4*2)@sp=sp-(4*2)非常重要的ARM37寄存器,请参考寄存器系列文章最后。以上就是异常接管对应的代码处理。每种异常发生的具体场景和代码细节。由于内容太多太复杂,本系列将分章节一一分析。敬请关注!参与贡献●访问注解仓库地址●fork本仓库>>新建一个Feat_xxx分支>>提交代码评论>>新建一个PullRequest●新建一个Issue更多信息请访问:HeHuaweiHarmonyos官方技术社区https://harmonyos.51cto.com
