linux中断向量的初始化
中断异常向量表的地址有两种:
异常向量表的加载地址: 就是在向量表加载到内存,但在运行之前的地址
异常向量表的运行地址: 实际运行时的中断向量表地址
中断异常向量表的基地址的确定:
在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0x00000000,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的地址的对应关系如下:
V=0 ~ 0x00000000~0x0000001C
V=1 ~ 0xffff0000~0xffff001C
linux内核目前都是将0xffff0000设置为中断向量表的开始地址
中断异常向量表的内容(arch/arm/kernel/entry-armv.S)
/*
* We group all the following data together to optimise
* for CPUs with separate I & D caches.
*/
.align 5
.LCvswi:
.word vector_swi
.globl __stubs_end
__stubs_end:
.equ stubs_offset, __vectors_start + 0x200 - __stubs_start
/*
*interruption ventor entry table
*rubbitxiao
*/
.globl __vectors_start
__vectors_start:
ARM( swi SYS_ERROR0 )
THUMB( svc #0 )
THUMB( nop )
W(b) vector_und + stubs_offset
W(ldr) pc, .LCvswi + stubs_offset
W(b) vector_pabt + stubs_offset
W(b) vector_dabt + stubs_offset
W(b) vector_addrexcptn + stubs_offset
W(b) vector_irq + stubs_offset
W(b) vector_fiq + stubs_offset
.globl __vectors_end
__vectors_end:
以上向量表的反汇编代码如下:
000002c4 <__stubs_end>:
2c4: ef9f0000 svc 0x009f0000
2c8: ea0000dd b 644 <__switch_to+0x19c>
2cc: e59ff410 ldr pc, [pc, #1040] ; 6e4 <__switch_to+0x23c>
2d0: ea0000bb b 5c4 <__switch_to+0x11c>
2d4: ea00009a b 544 <__switch_to+0x9c>
2d8: ea0000fa b 6c8 <__switch_to+0x220>
2dc: ea000078 b 4c4 <__switch_to+0x1c>
2e0: ea0000f7 b 6c4 <__switch_to+0x21c>
由以上可知中断向量表是一个跳转表,对应8个中断向量,每个异常向量都有固定的pc地址相对应,并且都对应个特定的处理器模式,而每种处理器模式又有各自特有的备份寄存器。他们的对应关系如下:
偏移量
中断类型
处理器的模式
0x00
复位