ARMLinux中断处理过程分析
ARM Linux中断处理过程分析(1) [原创 2007-06-09 21:43:26 ] 发表者: jimmy_lee ??
Date:??????2007-06-09
?
在我的上一篇文章(ARM linux的中断向量表初始化分析ARM Linux中断向量表是如何建立的,在这篇文章中,我将分析一下Linux内核的ARM体系下,中断处理是如何响应的一个过程。
在ARM体系架构下,定义了7种异常,每一种异常都有自己的入口地址,即异常向量表,当异常发生时,处理器会自动跳转到相应的入口处执行。对于ARMv4及其以上的版本,异常向量表的起始位置由协处理器15(cp15)的控制寄存器(c1)里的V位(bit13)有关,当V=0时,异常向量表的起始位置在0而当V=1时,异常向量表就起始于0xffff0000位置。在上一篇文章中,我们已经分析知道异常向量表放置于0xffff0000起始位置,而IRQ中断处理入口地址为:0xffff0018,所以当发生一IRQ中断异常时,处理器会自动跳转到0xffff0018这个虚拟地址上。
0xffff0018这个虚拟地址上是一条跳转指令:
b__real_stubs_start + (vector_IRQ - __stubs_start)
???所以对于IRQ的处理就是从vector_IRQ标号处开始的。在linux2.4.19内核中相应代码如下:
1 vector_IRQ:@
2@ save mode specific registers
3@
4ldrr13, .LCsirq
5sublr, lr, #4
6strlr, [r13]@ save lr_IRQ
7mrslr, spsr
8strlr, [r13, #4]@ save spsr_IRQ
9@
10@ now branch to the relevent MODE handling routine
11@
12mrsr13, cpsr
13bicr13, r13, #MODE_MASK
14orrr13, r13, #I_BIT | MODE_SVC
15msrspsr_c, r13@ switch to SVC_32 mode
16
17andlr, lr, #15
18ldrlr, [pc, lr, lsl #2]
19movspc, lr@ Changes mode and branches
20
21.LCtab_irq:.word__irq_usr@ 0 (USR_26 / USR_32)
22.word__irq_invalid@ 1 (FIQ_26 / FIQ_32)
23.word__irq_invalid@ 2 (IRQ_26 / IRQ_32)
24.word__irq_svc@ 3 (SVC_26 / SVC_32)
25.word__irq_invalid@ 4
26.word__irq_invalid@ 5
27.word__irq_invalid@ 6
28.word__irq_invalid@ 7
29.word__irq_invalid@ 8
30.word__irq_invalid@ 9
31.word__irq_invalid@ a
32.word__irq_invalid@ b
33.word__irq_invalid@ c
34.word__irq_invalid@ d
35.word__irq_invalid@ e
36.word__irq_invalid@ f
首先,行4~8是保存进入IRQ模式之前的pc指针(在lr_IRQ)和CPSR(在SPSR_IRQ)到.LCsirq所指向的地址中。.LCsirq相关代码也是位于entry-armv.S中:
.LCsirq:.word__temp_irq
…
__temp_irq:.word0@ saved lr_irq
.word0@ saved spsr_irq
.word-1@ old_r0
在这里补充一下ARM对于异常的处理过程,可以用下面的一段伪码来表示:
r14_ = return link
SPSR_ = CPSR
CPSR[4:0] = 异常模式编码
CPSR[5] = 0;运行于ARM状态