-- 作者:wangxinxin
-- ARM Linux外部中断处理过程
最近在学习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
|