1.中断的概念:

   中断是指CPU在正常运行程序时,由于程序的预先安排或内外部事件,引起CPU中断正在运行的程序,而转到发生中断事件程序中。引起中断的事件称为中断源。中断源向CPU提出处理的请求称为中断请求。发生中断时被打断程序的暂停点称为断点。CPU暂停现行程序而转为响应中断请求的过程称为中断响应。处理中断源的程序称为中断处理程序。CPU执行有关的中断处理程序称为中断处理。而返回断点的过程称为中断返回。中断的实现实行软件和硬件综合完成,硬件部分叫做硬件装置,软件部分称为软件处理程序。

   从物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,处理器会通知OS已经产生中断。这样,OS就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。


2. ARM中断:

   不同的处理器的体系结构是不同的,中断系统也是不相同的,下面以arm为例讲述。

Linux 中断(一)_中断

   以上是arm的异常模式和类型,以IRQ为例:

   在IRQ中断发生时arm处理器的硬件会自动执行以下工作

   (1)将被中断任务模式的PC值保存到IRQ模式中的LR寄存器中;

   (2)将被中断任务模式的CPSR值保存到IRQ模式中的SPSR寄存器中;

   (3)将模式自动切换到IRQ模式并将CPSR中的bit7位置禁止后继IRQ中断的发生;

   (4)PC被赋予0x00000018或0xFFFF0018,将从该地址开始执行,得到中断源,然后执行相应中断服务程序;

   (5)清除中断标志,返回

   上述过程用伪代码可以描述如下:

   (1) R14_irq = address of next instruction to be executed + 4

   (2) SPSR_irq = CPSR

   (3) CPSR[4:0] = 0b10010

       CPSR[5] = 0    //Execute in ARM state

       CPSR[7] = 1

   (4) if VE == 0 then

           if high vectors configured then

               PC = 0xFFFF0018

           else

               PC = 0x00000018

       else

           PC = IMPLEMENTATION

   (5) SUBS PC,R14, #4

3. linux arm异常向量表处理:

   在start_kernel中,调用trap_init处理异常向量表;

arch/arm/kernel/traps.c
void __init trap_init(void)
{
    unsigned long vectors = CONFIG_VECTORS_BASE;
        ......
    memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
    memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
    memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
        ......
}

   在arch/arm/kernel/entry-armv.S中,定义了__vectors_start跟__vectors_end,这个范围就是异常向量表,另CONFIG_VECTORS_BASE在autoconf.h定义,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。

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:

4. 中断响应:

   当有外部中断产生时,跳到中断向量表执行b vector_irq + stubs_offset,最后到asm_do_IRQ执行。

asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
    struct irqdesc *desc = irq_desc + irq;
    /*
     * Some hardware gives randomly wrong interrupts.  Rather
     * than crashing, do something sensible.
     */
    if (irq >= NR_IRQS)
        desc = &bad_irq_desc;
    irq_enter();
    desc_handle_irq(irq, desc, regs);
    /* AT91 specific workaround */
    irq_finish(irq);
    irq_exit();
}