zoukankan      html  css  js  c++  java
  • Linux异常处理体系结构

    arm11处理器裸机的异常与中断处理参考:

    【OK6410裸机程序】异常处理

    【OK6410裸机程序】按键中断

    另外参考一篇:Linux中断体系结构

    在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的对应关系如下:  [V=0]0x00000000~0x0000001C /[V=1]0xffff0000~0xffff001C  。Linux内核使用0xffff0000。

    异常向量的代码很简单,只是一些跳转指令。发生异常时,cpu自动执行这些指令,跳转到更复杂得代码。

    地址__vectors_start~__vectors_end间的代码就是异常向量,在arch/arm/kernel/entry-armv.S中定义,这些异常向量会被复制到0xffff0000处。

        .globl    __vectors_start
    __vectors_start:
        swi    SYS_ERROR0                   //复位时,cpu将执行这条指令
        b    vector_und + stubs_offset    //未定义异常时,cpu执行这条指令
        ldr    pc, .LCvswi + stubs_offset   //swi异常
        b    vector_pabt + stubs_offset   //指令预取终止
        b    vector_dabt + stubs_offset   //数据访问终止
        b    vector_addrexcptn + stubs_offset //没有用到
        b    vector_irq + stubs_offset    //irq异常
        b    vector_fiq + stubs_offset    //fiq异常
    
        .globl    __vectors_end
    __vectors_end:

     “更复杂得代码”在地址__stubs_start~__stubs_end之间,在arch/arm/kernel/entry-armv.S中定义,这些异常向量会被复制到0xffff0200处。

      1     .globl    __stubs_start
      2 __stubs_start:
      3 /*
      4  * Interrupt dispatcher
      5  */
      6     vector_stub    irq, IRQ_MODE, 4
      7 
      8     .long    __irq_usr            @  0  (USR_26 / USR_32)
      9     .long    __irq_invalid            @  1  (FIQ_26 / FIQ_32)
     10     .long    __irq_invalid            @  2  (IRQ_26 / IRQ_32)
     11     .long    __irq_svc            @  3  (SVC_26 / SVC_32)
     12     .long    __irq_invalid            @  4
     13     .long    __irq_invalid            @  5
     14     .long    __irq_invalid            @  6
     15     .long    __irq_invalid            @  7
     16     .long    __irq_invalid            @  8
     17     .long    __irq_invalid            @  9
     18     .long    __irq_invalid            @  a
     19     .long    __irq_invalid            @  b
     20     .long    __irq_invalid            @  c
     21     .long    __irq_invalid            @  d
     22     .long    __irq_invalid            @  e
     23     .long    __irq_invalid            @  f
     24 
     25 /*
     26  * Data abort dispatcher
     27  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
     28  */
     29     vector_stub    dabt, ABT_MODE, 8
     30 
     31     .long    __dabt_usr            @  0  (USR_26 / USR_32)
     32     .long    __dabt_invalid            @  1  (FIQ_26 / FIQ_32)
     33     .long    __dabt_invalid            @  2  (IRQ_26 / IRQ_32)
     34     .long    __dabt_svc            @  3  (SVC_26 / SVC_32)
     35     .long    __dabt_invalid            @  4
     36     .long    __dabt_invalid            @  5
     37     .long    __dabt_invalid            @  6
     38     .long    __dabt_invalid            @  7
     39     .long    __dabt_invalid            @  8
     40     .long    __dabt_invalid            @  9
     41     .long    __dabt_invalid            @  a
     42     .long    __dabt_invalid            @  b
     43     .long    __dabt_invalid            @  c
     44     .long    __dabt_invalid            @  d
     45     .long    __dabt_invalid            @  e
     46     .long    __dabt_invalid            @  f
     47 
     48 /*
     49  * Prefetch abort dispatcher
     50  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
     51  */
     52     vector_stub    pabt, ABT_MODE, 4
     53 
     54     .long    __pabt_usr            @  0 (USR_26 / USR_32)
     55     .long    __pabt_invalid            @  1 (FIQ_26 / FIQ_32)
     56     .long    __pabt_invalid            @  2 (IRQ_26 / IRQ_32)
     57     .long    __pabt_svc            @  3 (SVC_26 / SVC_32)
     58     .long    __pabt_invalid            @  4
     59     .long    __pabt_invalid            @  5
     60     .long    __pabt_invalid            @  6
     61     .long    __pabt_invalid            @  7
     62     .long    __pabt_invalid            @  8
     63     .long    __pabt_invalid            @  9
     64     .long    __pabt_invalid            @  a
     65     .long    __pabt_invalid            @  b
     66     .long    __pabt_invalid            @  c
     67     .long    __pabt_invalid            @  d
     68     .long    __pabt_invalid            @  e
     69     .long    __pabt_invalid            @  f
     70 
     71 /*
     72  * Undef instr entry dispatcher
     73  * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
     74  */
     75     vector_stub    und, UND_MODE
     76 
     77     .long    __und_usr            @  0 (USR_26 / USR_32)
     78     .long    __und_invalid            @  1 (FIQ_26 / FIQ_32)
     79     .long    __und_invalid            @  2 (IRQ_26 / IRQ_32)
     80     .long    __und_svc            @  3 (SVC_26 / SVC_32)
     81     .long    __und_invalid            @  4
     82     .long    __und_invalid            @  5
     83     .long    __und_invalid            @  6
     84     .long    __und_invalid            @  7
     85     .long    __und_invalid            @  8
     86     .long    __und_invalid            @  9
     87     .long    __und_invalid            @  a
     88     .long    __und_invalid            @  b
     89     .long    __und_invalid            @  c
     90     .long    __und_invalid            @  d
     91     .long    __und_invalid            @  e
     92     .long    __und_invalid            @  f
     93 
     94     .align    5
     95 
     96 /*=============================================================================
     97  * Undefined FIQs
     98  *-----------------------------------------------------------------------------
     99  * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
    100  * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
    101  * Basically to switch modes, we *HAVE* to clobber one register...  brain
    102  * damage alert!  I don't think that we can execute any code in here in any
    103  * other mode than FIQ...  Ok you can switch to another mode, but you can't
    104  * get out of that mode without clobbering one register.
    105  */
    106 vector_fiq:
    107     disable_fiq
    108     subs    pc, lr, #4
    109 
    110 /*=============================================================================
    111  * Address exception handler
    112  *-----------------------------------------------------------------------------
    113  * These aren't too critical.
    114  * (they're not supposed to happen, and won't happen in 32-bit data mode).
    115  */
    116 
    117 vector_addrexcptn:
    118     b    vector_addrexcptn
    119 
    120 /*
    121  * We group all the following data together to optimise
    122  * for CPUs with separate I & D caches.
    123  */
    124     .align    5
    125 
    126 .LCvswi:
    127     .word    vector_swi
    128 
    129     .globl    __stubs_end
    130 __stubs_end:
    __stubs_start

    关于stubs_offset的值及解析,参考Linux异常体系之stubs_offset

    关于__stubs_start~__stubs_end之间的代码解析,参考vector_stub宏解析 。vector_irq、 vector_dabt、vector_pabt、vector_und、vector_fiq都在它们中间。

    各种异常的C处理函数分为5类,分布在不同的函数中。

    1.中断处理C总入口函数asm_do_IRQ,在linux/arch/arm/kernel/irq.c中。它调用其它文件注册的中断处理函数。

    init_IRQ函数被用来初始化中断的处理框架,设置各种中断的默认处理函数。当中断发生时,中断总入口函数asm_do_IRQ就可以调用这些函数坐进一步的处理。

    b    vector_irq + stubs_offset
        -->vector_stub    irq, IRQ_MODE, 4
            -->__irq_usr/__irq_svc
                -->void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)

    2.未定义指令处理C总入口函数do_undefinstr,在linux/arch/arm/kernel/traps.c中。

    b    vector_und + stubs_offset
        -->vector_stub    und, UND_MODE
            -->__und_usr/__und_svc
                -->b    do_undefinstr

    3.与内存访问相关的异常处理C总入口函数do_DataAbort,do_PrefechAbort,在linux/arch/arm/kernel/fault.c中。

    4.swi异常处理函数,在在linux/arch/arm/kernel/calls.S中。swi异常的处理函数指针被组织成一个表格;swi指令机器码的为[23:0]用来作为索引,通过不同的“swi index”指令可以调用不同的swi异常处理函数,也称为系统调用,比如sys_open、sys_read、sys_write等。

    5.没有使用的异常,linux中没有使用FIQ异常。

  • 相关阅读:
    Server-Side Access Control
    MDN > Web technology for developers > HTTP
    HTML5解决跨域问题
    HTML5安全:CORS(跨域资源共享)简介
    HTML5 知识点
    android中viewPager+fragment实现的屏幕左右切换(进阶篇)
    【Android】Android 博客园客户端 (七)登录功能
    【Tools】Pro Git 一二章读书笔记
    【JavaScript】重温Javascript继承机制
    【334】Python Object-Oriented Programming
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/7629843.html
Copyright © 2011-2022 走看看