linux外部中断过程

内核在linux-2.6.22.6\init\main.c:start_kernel函数中调用trap_init、init_IRQ 两个函数来设置异常的处理函数。

asmlinkage void __init start_kernel(void)
{
    ...
    trap_init();
    ...
    init_IRQ();
    ...
}

1.linux-2.6.22.6\arch\arm\kernel\traps.c\:trap_init函数分析
trap_init函数被用来设置各种异常的处理向量,所谓向量,就是一些被安放在固定位置的代码,当发生异常时,CPU会自动执行这些固定位置上相应代码段,arm架构linux内核异常向量基址地0xffff0000,trap_init函数将异常向量复制到0ffff0000处:

void __init trap_init(void)
{
    ...
    unsigned long vectors = CONFIG_VECTORS_BASE;     //CONFIG_VECTORS_BASE=0xffff0000
    extern char __stubs_start[], __stubs_end[];
    extern char __vectors_start[], __vectors_end[];
    ...

    /*
     * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
     * into the vector page, mapped at 0xffff0000, and ensure these
     * are visible to the instruction stream.
     */
    memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
    memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
    ...
}

vectors等于0xffff0000是异常向量的基址,memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);将从__vectors_start地址开始的,大小为__vectors_end - __vectors_start的代码复制到0xffff0000地址上,__vectors_start~-_vectors_end之间的代码就是异常向量,在arch/arm/kernel/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
    .globl  __vectors_end
__vectors_end:

    .data

    .globl  cr_alignment
    .globl  cr_no_alignment

其中的vector_und、vector_pabt、vector_irq等表示要跳转去执行的代码,以vector_irq为例,它在arch/arm/kernel/entry-armv.S中,通过宏指令来定义:

vector_stub irq, IRQ_MODE, 4

.long   __irq_usr           @  0  (USR_26 / USR_32)
.long   __irq_invalid           @  1  (FIQ_26 / FIQ_32)
.long   __irq_invalid           @  2  (IRQ_26 / IRQ_32)
.long   __irq_svc           @  3  (SVC_26 / SVC_32)
.long   __irq_invalid           @  4
.long   __irq_invalid           @  5
.long   __irq_invalid           @  6
.long   __irq_invalid           @  7
.long   __irq_invalid           @  8
.long   __irq_invalid           @  9
.long   __irq_invalid           @  a
.long   __irq_invalid           @  b
.long   __irq_invalid           @  c
.long   __irq_invalid           @  d
.long   __irq_invalid           @  e
.long   __irq_invalid           @  f

vector_stub是一个带参宏指令,它根据后面的参数定义了以“vector_irq”为标号的一段代码,具体是:

.macro  vector_stub, name, mode, correction=0
.align  5

    vector_\name:
        .if \correction
        sub lr, lr, #\correction
        .endif

        @
        @ Save r0, lr_<exception> (parent PC) 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值