Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / ARM Linux异常处理之data abort

本文简要分析了ARM Linux的data abort异常处理过程,内核版本2.6.28,s3c6410平台。

异常向量与程序跳转

data abort是ARM体系定义的异常之一。异常发生时,ARM会自动跳转到异常向量表中,通过向量表中的跳转命令跳转到相应的异常处理中去。ARM的异常处理向量表在entry-armv.S文件中:       .globl      __vectors_start__vectors_start:       swi   SYS_ERROR0       b     vector_und + stubs_offset       ldr   pc, .LCvswi + stubs_offset       b     vector_pabt + stubs_offset       b     vector_dabt + stubs_offset       b     vector_addrexcptn + stubs_offset       b     vector_irq + stubs_offset       b     vector_fiq + stubs_offset对于data abort,对应的跳转地址是vector_dabt + stubs_offset。这个地址的指令定义也在entry-armv.S:       vector_stub     dabt, ABT_MODE, 8       .long       __dabt_usr                       @  0  (USR_26 / USR_32)       .long       __dabt_invalid                     @  1  (FIQ_26 / FIQ_32)       .long       __dabt_invalid                     @  2  (IRQ_26 / IRQ_32)       .long       __dabt_svc                       @  3  (SVC_26 / SVC_32)       .long       __dabt_invalid                     @  4       .long       __dabt_invalid                     @  5       .long       __dabt_invalid                     @  6       .long       __dabt_invalid                     @  7       .long       __dabt_invalid                     @  8       .long       __dabt_invalid                     @  9       .long       __dabt_invalid                     @  a       .long       __dabt_invalid                     @  b       .long       __dabt_invalid                     @  c       .long       __dabt_invalid                     @  d       .long       __dabt_invalid                     @  e       .long       __dabt_invalid                     @  fvector_stub是一个宏定义:       .macro     vector_stub, name, mode, correction=0       .align      5vector_ ame:       .if correction       sub  lr, lr, #correction       .endif        @       @ Save r0, lr_<exception> (parent PC) and spsr_<exception>       @ (parent CPSR)       @       stmia       sp, {r0, lr}             @ save r0, lr       mrs  lr, spsr                          @ 保存跳转之前的CPSRlr寄存器       str    lr, [sp, #8]                    @ save spsr        @       @ Prepare for SVC32 mode.  IRQs remain disabled.       @       mrs  r0, cpsr       eor   r0, r0, #(mode ^ SVC_MODE)       msr  spsr_cxsf, r0                 @ 准备进入svc模式        @       @ the branch table must immediately follow this code       @       and  lr, lr, #0x0f                    @ 得到跳转前所处的模式(usrsvr等)       mov r0, sp       ldr   lr, [pc, lr, lsl #2]            @ 根据模式跳转到相应的data abort指令,并进入svc模式       movs       pc, lr                     @ branch to handler in SVC modeENDPROC(vector_ ame)       .endm由代码中红色标注部分可看出,对于同一个异常,根据进入异常之前所处的模式,会跳转到不同的指令分支,www.linuxidc.com这些指令分支紧跟在vector_stub宏定义的后面。如果进入data abort之前处于usr模式,那么跳转到__dabt_usr;如果处于svc模式,那么跳转到__dabt_svc;否则跳转到__dabt_invalid。实际上,进入异常向量前Linux只能处于usr或者svc两种模式之一。这时因为irq等异常在跳转表中都要经过vector_stub宏,而不管之前是哪种状态,这个宏都会将CPU状态改为svc模式。usr模式即Linux中的用户态模式,svc即内核模式。下面看一下在不同模式下进入data abort时的处理过程。