Hongmeng kernel source code analysis (abnormal takeover) | The society is very simple, the complex is people | Chinese annotation HarmonyOS source code | v39.02

Millions of Chinese character annotations >> Intensive reading of the kernel source code, Chinese annotation analysis, deep excavation of foundation engineering, permanent brain memory, four major code warehouses are updated daily <gitee | github | csdn | coding>

Hundreds of blog analysis >> Storytelling core, Q&A guide, life-style metaphor, tabular description, graphical display, multi-site daily synchronization update <oschina | csdn | weharmony>


The description of the ARM part of the series is based on the ARM720T.pdf document.

Why is there an abnormal takeover?

Take the growth of a child as an analogy. Adults always hope that children can grow up healthily, but they will always encounter various problems in the process of growth. The tree desires to be quiet and windy, and there is danger on the growth path. Sometimes it is their own problems and sometimes they are foreign. Regarding environmental issues. Just like Douyin’s recent popular saliva songs, the society is very simple, and the complicated ones are people. Every time I hear it, I want to stand up and twist a few times. Hey! What did Lao Na do wrong?

For example: What do you do when you are bullied by children? What do you do when you find that you spend money? How do you deal with puberty? What should you do if you lose love and jump off the building? It means more than his cognition, but it can’t solve it by himself, so he needs a higher authority , A more intelligent person stepped in to help solve the problem of wiping the ass.

Then the application is the kid, and the kernel is the guardian, with higher authority and higher wisdom. And there are more than one guardian, but six. Each guardian solves a situation, and it takes over when a situation occurs. For the handling of this matter, don't worry about it, kids, shut you off at home first, and handle the outside safety before releasing the app to play.

These six people have their own tools to deal with problems, have standard solutions, have their own independent office space, the office space is the stack space (independent), and the standard solution is the private code segment, placed in a fixed location. the tool is SPSR_***, SP_***, LR_***the register set. see the series of articles published work mode , then briefly reviewed here what work mode there, including children themselves (user mode) a total of seven modes.

Seven working modes

The picture is from page 43 of ARM720T.pdf . In the ARM system, the CPU works in the following seven modes:
Insert picture description here

  • User mode (usr): It is a normal user mode and cannot be directly switched to other modes. The ARM processor is in the normal program execution state.
  • Fast interrupt mode (fiq): support high-speed data transmission and channel processing, enter this mode when FIQ responds abnormally
  • External interrupt mode (irq): used for general interrupt processing, enter this mode when IRQ responds abnormally
  • Management mode (svc): operating system protection mode, enter this mode when the system is reset and software interrupt response (triggered by the system call to execute the soft interrupt SWI command)
  • Data access termination mode (abt): Enter this mode when data or instruction prefetching is terminated, which can be used to handle memory failures and implement virtual memory and memory protection.
  • System mode (sys): Run privileged operating system tasks, similar to user mode, but with privileges such as being able to switch directly to other modes
  • Undefined instruction abort mode (und): handles undefined instruction traps, enters this mode when undefined instructions are executed, and can be used to support software emulation of hardware coprocessors.

Except for user mode, the other 6 working modes belong to privileged mode

  • The other five modes in the privileged mode except the system mode are called exception modes
  • Most programs run in user mode
  • Entering privileged mode is to handle interrupts, exceptions, or access protected system resources
  • Hardware permission level: System mode> Abnormal mode> User mode
  • The difference between fast interrupt (fiq) and slow interrupt (irq): interrupt is prohibited during fast interrupt processing

Each mode has its own independent entry point and independent running stack space. The CPU part of the series has already introduced that as long as the entry function and running space are provided, the CPU can work. The entry function solves the problem of the source of instructions and the running space. It solves the problem of the running site of instructions.
And in the case of multi-core, each privileged mode of each CPU core has its own independent stack space. Note that the stack space in the privileged mode, the stack space in the user mode is determined by the user (application ) Provided by the program.

Official concept

Exception takeover is a series of actions taken by the operating system to handle exceptions (chip hardware exceptions) that occur during operation, such as printing the call stack information of the current function when the exception occurs, CPU site information, and the stack of tasks.
Exception takeover, as a debugging method, can provide users with useful exception information when an exception occurs in the system, such as exception type, system status when the exception occurs, etc., so that users can locate and analyze the problem.

Hongmeng's exception takeover, the processing action when an exception occurs in the system is: display the task information (including task name, task number, stack size, etc.) that is running when the exception occurs, and information such as the CPU site.

Entry and Exit Abnormal Way

Two things need to be handled for abnormal takeover switching:

  • One is where the code should be cut, that is, to reset the PC register. The switching method under each abnormal mode is as shown in the figure:

Insert picture description here

  • Another is to restore the state of each mode, i.e., CPSR(1个)and SPSR(共5个)the relationship of M[4:0]the modification, as shown:
    Insert picture description here

The following is M[4:0]the specific operation method in each mode:

Insert picture description here
Insert picture description here

Stack frame

Each function has its own stack space, called a stack frame. When a function is called, a stack frame of the sub-function is created, and the function is put into the stack at the same time as parameters, local variables, and registers. Stack frame to address the low growth from the high address, that address bottom of the stack is high, top of the stack is the end of the address. See series with a stack of papers published way

To ARM32 CPUarchitecture, for example, each stack frame are saved PC, LR, SPand FPthe historical value of the register.
The principle of stack analysis is shown in the figure below. The actual stack information differs according to different CPU architectures. This is only for illustration.
The registers of different colors in the figure represent different functions. You can see the preservation of registers during the function call. Through the FP register, the stack traces back to the parent function of the abnormal function, continues to analyze the stack according to the law, and introduces the function call relationship, which is convenient for users to locate the problem.
Insert picture description here

Interpretation

  • LR register (Link Register), link register, points to the return address of the function.

  • R11: It can be used as a general-purpose register. It can be used as a frame pointer register FP when certain coding options are turned on to realize the stack traceback function.
    The GNU compiler (gcc) defaults to R11 as a general-purpose register for storing variables, so the stack traceback function of FP cannot be used by default. To support the call stack parsing function, you need to add the -fno-omit-frame-pointer option to the compilation parameters to prompt the compiler to use R11 as FP.

  • FP register (Frame Point), frame pointer register, points to the start address of the stack frame of the parent function of the current function. The stack frame of the parent function can be obtained by using this register, and the FP of the parent function can be obtained from the stack frame, and the stack frame of the grandfather function can be obtained. By analogy, the program call stack can be traced to obtain the calling relationship between functions.
    When an exception occurs in the system, the system prints the contents of the registers saved in the stack frame of the exception function, as well as the contents of the LR and FP registers in the stack frame of the parent function and grandfather function, and the user can trace the calling relationship between the functions based on this, and locate the exception the reason.

Six kinds of exception mode implementation code

/* 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                                @跳到异常分发统一处理

Fast interrupt processing (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.

Interpretation

  • Normal interrupts need to be disabled for fast interrupt processing

Prefectch abort

@ Description: Prefectch abort exception handler
_osExceptPrefetchAbortHdl:
#ifdef LOSCFG_GDB
#if __LINUX_ARM_ARCH__ >= 7
    GDB_HANDLE OsPrefetchAbortExcHandleEntry
#endif
#else
    SUB     LR, LR, #4                                       @ LR offset to return from this exception: -4.
    STMFD   SP, {
    
    R0-R7}                                      @ Push working registers, but don`t change SP.
    MOV     R5, LR
    MRS     R1, SPSR

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

    AND     R4, R1, #CPSR_MASK_MODE                          @ Interrupted mode
    CMP     R4, #CPSR_USER_MODE                              @ User mode
    BEQ     _osExcPageFault                                   @ Branch if user mode

_osKernelExceptPrefetchAbortHdl:
    MOV     LR, R5
    B       _osExceptDispatch                                @ Branch to global exception handler.
#endif

Data access exception (Data abort)

@ Description: Data abort exception handler
_osExceptDataAbortHdl: @数据异常处理,缺页就属于数据异常
#ifdef LOSCFG_GDB
#if __LINUX_ARM_ARCH__ >= 7
    GDB_HANDLE OsDataAbortExcHandleEntry
#endif
#else
    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     R5, LR
    MRS     R1, SPSR

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

    B     _osExcPageFault   @跳到缺页异常处理
#endif

Soft interrupt processing (swi)

@ Description: Software interrupt exception handler
_osExceptSwiHdl: @软中断异常处理
    SUB     SP, SP, #(4 * 16)	@先申请16个栈空间用于处理本次软中断
    STMIA   SP, {
    
    R0-R12}		@保存R0-R12寄存器值
    MRS     R3, SPSR			@读取本模式下的SPSR值
    MOV     R4, LR				@保存回跳寄存器LR

    AND     R1, R3, #CPSR_MASK_MODE                          @ Interrupted mode 获取中断模式
    CMP     R1, #CPSR_USER_MODE                              @ User mode	是否为用户模式
    BNE     OsKernelSVCHandler                               @ Branch if not user mode 非用户模式下跳转
	@ 当为用户模式时,获取SP和LR寄出去值
    @ we enter from user mode, we need get the values of  USER mode r13(sp) and r14(lr).
    @ stmia with ^ will return the user mode registers (provided that r15 is not in the register list).
    MOV     R0, SP											 @获取SP值,R0将作为OsArmA32SyscallHandle的参数
    STMFD   SP!, {
    
    R3}                                        @ Save the CPSR 入栈保存CPSR值
    ADD     R3, SP, #(4 * 17)                                @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置
    STMFD   R3!, {
    
    R4}                                        @ Save the CPSR and r15(pc) 保存LR寄存器
    STMFD   R3, {
    
    R13, R14}^                                  @ Save user mode r13(sp) and r14(lr) 保存用户模式下的SP和LR寄存器
    SUB     SP, SP, #4
    PUSH_FPU_REGS R1	@保存中断模式(用户模式模式)											

    MOV     FP, #0                                           @ Init frame pointer
    CPSIE   I	@开中断,表明在系统调用期间可响应中断
    BLX     OsArmA32SyscallHandle	/*交给C语言处理系统调用*/
    CPSID   I	@执行后续指令前必须先关中断

    POP_FPU_REGS R1											 @弹出FP值给R1
    ADD     SP, SP,#4										 @ 定位到保存旧SPSR值的位置
    LDMFD   SP!, {
    
    R3}                                        @ Fetch the return SPSR 弹出旧SPSR值
    MSR     SPSR_cxsf, R3                                    @ Set the return mode SPSR 恢复该模式下的SPSR值

    @ we are leaving to user mode, we need to restore the values of USER mode r13(sp) and r14(lr).
    @ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list)

    LDMFD   SP!, {
    
    R0-R12}									 @恢复R0-R12寄存器
    LDMFD   SP, {
    
    R13, R14}^                                  @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器
    ADD     SP, SP, #(2 * 4)								 @定位到保存旧PC值的位置
    LDMFD   SP!, {
    
    PC}^                                       @ Return to user 切回用户模式运行

Ordinary interrupt processing (irq)

OsIrqHandler:	@硬中断处理,此时已切换到硬中断栈
    SUB     LR, LR, #4
    /* push r0-r3 to irq stack */
    STMFD   SP, {
    
    R0-R3}		@r0-r3寄存器入 irq 栈
    SUB     R0, SP, #(4 * 4)@r0 = sp - 16
    MRS     R1, SPSR		@获取程序状态控制寄存器
    MOV     R2, LR			@r2=lr

    /* disable irq, switch to svc mode */@超级用户模式(SVC 模式),主要用于 SWI(软件中断)OS(操作系统)
    CPSID   i, #0x13				@切换到SVC模式,此处一切换,后续指令将入SVC的栈
									@CPSID i为关中断指令,对应的是CPSIE
    /* push spsr and pc in svc stack */
    STMFD   SP!, {
    
    R1, R2} @实际是将 SPSR,和LR入栈,入栈顺序为 R1,R2,SP自增
    STMFD   SP, {
    
    LR}	  @LR再入栈,SP不自增

    AND     R3, R1, #CPSR_MASK_MODE	@获取CPU的运行模式
    CMP     R3, #CPSR_USER_MODE		@中断是否发生在用户模式
    BNE     OsIrqFromKernel			@中断不发生在用户模式下则跳转到OsIrqFromKernel

    /* push user sp, lr in svc stack */
    STMFD   SP, {
    
    R13, R14}^ 		@sp和LR入svc栈

Interpretation

  • Can respond to fast interrupts during normal interrupt processing

Undefined exception handling (undef)

@ Description: Undefined instruction exception handler
_osExceptUndefInstrHdl:@出现未定义的指令处理
#ifdef LOSCFG_GDB
    GDB_HANDLE OsUndefIncExcHandleEntry
#else
                                                              @ LR offset to return from this exception:  0.
    STMFD   SP, {
    
    R0-R7}                                       @ Push working registers, but don`t change SP.

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

    B       _osExceptDispatch                                 @ Branch to global exception handler.

#endif

Unified handling of abnormal distribution

_osExceptDispatch: @异常模式统一分发处理
    MRS     R2, SPSR                                         @ Save CPSR before exception.
    MOV     R1, LR                                           @ Save PC before exception.
    SUB     R3, SP, #(8 * 4)                                 @ Save the start address of working registers.

    MSR     CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE)      @ Switch to SVC mode, and disable all interrupts
    MOV     R5, SP
    EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7

    STMFD   SP!, {
    
    R1}                                        @ Push Exception PC
    STMFD   SP!, {
    
    LR}                                        @ Push SVC LR
    STMFD   SP!, {
    
    R5}                                        @ Push SVC SP
    STMFD   SP!, {
    
    R8-R12}                                    @ Push original R12-R8,
    LDMFD   R3!, {
    
    R4-R11}                                    @ Move original R7-R0 from exception stack to original stack.
    STMFD   SP!, {
    
    R4-R11}
    STMFD   SP!, {
    
    R2}                                        @ Push task`s CPSR (i.e. exception SPSR).

    CMP     R0, #OS_EXCEPT_DATA_ABORT 		@是数据异常吗?
    BNE     1f 								@不是跳到 锚点1
    MRC     P15, 0, R8, C6, C0, 0 			@R8=C6(内存失效的地址) 0(访问数据失效)
    MRC     P15, 0, R9, C5, C0, 0 			@R9=C5(内存失效的状态) 0(无效整个指令cache)
    B       3f 								@跳到锚点3处执行
1:  CMP     R0, #OS_EXCEPT_PREFETCH_ABORT 	@是预取异常吗?
    BNE     2f 								@不是跳到 锚点2
    MRC     P15, 0, R8, C6, C0, 2 			@R8=C6(内存失效的地址) 2(访问指令失效)
    MRC     P15, 0, R9, C5, C0, 1 			@R9=C5(内存失效的状态) 1(虚拟地址)
    B       3f 								@跳到锚点3处执行
2:  MOV     R8, #0
    MOV     R9, #0

3:  AND     R2, R2, #CPSR_MASK_MODE 
    CMP     R2, #CPSR_USER_MODE                              @ User mode
    BNE     4f @不是用户模式
    STMFD   SP, {
    
    R13, R14}^                                  @ save user mode sp and lr
4:
    SUB     SP, SP, #(4 * 2) @sp=sp-(4*2)

Very important ARM37 registers

Insert picture description here

See the series of articles published register

end

The above is the code processing corresponding to the exception takeover. The specific scenarios where each exception occurs and the code details are handled. Because the content is too much and too complicated, the series will be analyzed one by one in the follow-up. Stay tuned!

Participate in contribution

Like, please generously like + follow + favorite

Search "Hongmeng Kernel Source Code Analysis" on major sites to quickly find the organization.

Public number: Hongmeng kernel source code analysis

Welcome to reprint, please indicate the source, the official account reprint application method: just reply to your official account name after paying attention.


Millions of Chinese character annotations >> Intensive reading of the kernel source code, Chinese annotation analysis, deep excavation of foundation engineering, permanent brain memory, four major code warehouses are updated daily <gitee | github | csdn | coding>

Hundreds of blog analysis >> Storytelling core, Q&A guide, life-style metaphor, tabular description, graphical display, multi-site daily synchronization update <oschina | csdn | weharmony>

Guess you like

Origin blog.csdn.net/kuangyufei/article/details/114438285