上文提到data abort的正常处理过程中,最终会调用do_DataAbort函数,下面分析一下该函数的处理过程。 do_DataAbort asmlinkage void __exception do_DataAbort( unsigned long addr, // 导致异常的内存地址 unsigned int fsr, //异常发生时CP15中的寄存器值,见前文 struct pt_regs *regs) // 异常发生前的寄存器...
1 # define CPU_DABORT_HANDLER v6_early_abort v6_early_abort: 首先读取DFSR和DFAR两个协处理寄存器,保存在R1和R0中,然后调用do_DataAbort进入C语言环境: 1 2 3 4 5 ENTRY(v6_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR b do_DataAbor...
上文提到data abort的正常处理过程中,最终会调用do_DataAbort函数,下面分析一下该函数的处理过程。 do_DataAbort asmlinkage void __exception do_DataAbort( unsigned long addr, // 导致异常的内存地址 unsigned int fsr, // 异常发生时CP15中的寄存器值,见前文 struct pt_regs *regs) // 异常发生前的寄存...
ARM有7种类型的异常,按优先级从高到低的排列如下:复位异常(Reset)、数据异常(Data Abort)、快速中断异常(FIQ)、外部中断异常(IRQ)、预取异常(Prefetch Abort)、软件中断(SWI)和未定义指令异常(Undefined instruction)。 注意 在ARM文档中,使用术语Exception来描述异常。Exception主要是从处理器被动接受异常的角度出发,...
比如当前代码运行在内核空间,发生了data abort,异常向量表的入口地址就是0x200。 2.kernel_ventry 异常发生后,处理器从对应的异常向量表入口地址开始执行,第一条指令是kernel_ventry。kernel_ventry是一个宏定义,先检查栈空间是否有溢出,然后跳转到指定的异常处理标签。
el1_da 跳转到异常处理程序do_mem_abort之前,为其设置好了三个入参: x0:产生DataAbort的故障虚拟地址。 x1:esr_el1,异常综合表征寄存器值,在el1_sync第二条指令已经保存。 x2:stack frame 地址,即pt_regs结构体的首地址,在kernel_entry已对其填充。
比如当前代码运行在内核空间,发生了data abort,异常向量表的入口地址就是0x200。 2.kernel_ventry 异常发生后,处理器从对应的异常向量表入口地址开始执行,第一条指令是kernel_ventry。kernel_ventry是一个宏定义,先检查栈空间是否有溢出,然后跳转到指定的异常处理标签。
代码片段1:__dabt_svc代码块处理了数据异常中断,核心函数是C语言函数do_DataAbort()。 .align 5 __dabt_svc: svc_entry @ irq/dabt/pabt/und异常发生后,在SVC模式下的现场保存 mrs r9, cpsr @ r9=当前SVC模式下的cpsr的值(IRQ使能位为:禁止) ...
_prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq //word伪操作用于分配一段字内存单元(分配的单元都是字对齐的),并用伪操作中的expr初始化 _pad: .word 0x12345678 /* now 16*4=64 */ ...
el1_da 跳转到异常处理程序do_mem_abort之前,为其设置好了三个入参: x0:产生DataAbort的故障虚拟地址。 x1:esr_el1,异常综合表征寄存器值,在el1_sync第二条指令已经保存。 x2:stack frame 地址,即pt_regs结构体的首地址,在kernel_entry已对其填充。