最近在学习arm linux的整套外部中断的处理过程,在网上汇总了一些资料,整个过程差不多都了解到了。如果没有这些资料我真是没信心从汇编开始读代码,感谢 奔腾年代的jimmy.lee和 linux论坛的bx_bird。 
在下面的的注释中有一些我读代码时遇到的问题,要是大家知道是怎么回事,希望多多回复。 
一.ARM linux的中断向量表初始化分析 
ARM linux内核启动时,通过start_kernel()->trap_init()的调用关系,初始化内核的中断异常向量表. 
/* arch/arm/kernel/traps.c */ 
void __init trap_init(void) 
{ 
extern void __trap_init(unsigned long); 
unsigned long base = vectors_base(); 
__trap_init(base); 
if (base != 0) 
oopsprintk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n", base); 
#ifdef CONFIG_CPU_32 
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 
#endif 
} 
vectors_base是一个宏,它的作用是获取ARM异常向量的地址,该宏在include/arch/asm-arm/proc-armv/system.h中定义: 
extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ 
extern unsigned long cr_alignment; /* defined in entry-armv.S */ 
#if __LINUX_ARM_ARCH__ >= 4 
#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0) 
#else 
#define vectors_base() (0) 
#endif 
  对于ARMv4以下的版本,这个地址固定为0;ARMv4及其以上的版本,ARM异常向量表的地址受协处理器CP15的c1寄存器(control register)中V位(bit[13])的控制,如果V=1,则异常向量表的地址为0x00000000~0x0000001C;如果V=0,则为:0xffff0000~0xffff001C。(详情请参考ARM Architecture Reference Manual) 
  下面分析一下cr_alginment的值是在哪确定的,我们在arch/arm/kernel/entry-armv.S找到cr_alignment的定义: 
.globl SYMBOL_NAME(cr_alignment) 
.globl SYMBOL_NAME(cr_no_alignment) 
SYMBOL_NAME(cr_alignment): 
.space 4 
SYMBOL_NAME(cr_no_alignment): 
.space 4 
  分析过head-armv.S文件的朋友都会知道,head-armv.S是非压缩内核的入口: 
1 .section ".text.init",#alloc,#execinstr 
2 .type stext, #function 
3ENTRY(stext) 
4 mov r12, r0 
5 
6 mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode 
7 msr cpsr_c, r0 @ and all irqs disabled 
8 bl __lookup_processor_type 
9 teq r10, #0 @ invalid processor? 
10 moveq r0, #'p' @ yes, error 'p' 
11 beq __error 
12 bl __lookup_architecture_type 
13 teq r7, #0 @ invalid architecture? 
14 moveq r0, #'a' @ yes, error 'a' 
15 beq __error 
16 bl __create_page_tables 
17 adr lr, __ret @ return address 
18 add pc, r10, #12 @ initialise processor 
19 @ (return control reg) 
20 
21 .type __switch_data, %object 
22__switch_data: .long __mmap_switched 
23 .long SYMBOL_NAME(__bss_start) 
24 .long SYMBOL_NAME(_end) 
25 .long SYMBOL_NAME(processor_id) 
26 .long SYMBOL_NAME(__machine_arch_type) 
27 .long SYMBOL_NAME(cr_alignment) 
28 .long SYMBOL_NAME(init_task_union)+8192 
29 
30 .type __ret, %function 
31__ret: ldr lr, __switch_data 
32 mcr p15, 0, r0, c1, c0 
33 mrc p15, 0, r0, c1, c0, 0 @ read it back. 
34 mov r0, r0 
35 mov r0, r0 
36 mov pc, lr 
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/6_system/linux/Linuxjs/2008827/137989.html