- 论坛徽章:
- 0
|
第二部分 软件行为
在ARM完成硬件逻辑之后,跳转到0018H处开始执行。这部分代码由Linux开始接管,因为不同平台间的差异,Linux试图提供一个general的中断处理框架,对于平台相关的部分留有接口(这部分的代码由BSP的伙计们去完成)。总之,演出开始了。。。
在中断发生时,Linux可能正运行内核态的代码,也可能是用户态的代码。这两种少许有些区别,海豚就用第一种情况(被中断的处理器正处于内核态)来说明。
在arch/arm/kernel/entry-armV.S中,__irq_svc是这种情况的入口点。首先自然是建立中断的上下文环境,尤其是堆栈的建立,然后将那些需要入栈的全给它入栈了,这个帖子不打算讨论太多的细节,否则主线(mainstream)就不清楚了!
接下来很重要的一点是调用一个名为irq_handler的宏,因为在这个宏里会跳转到我们driver安装的中断处理例程里,所以这里仔细看看这段代码:- /*
- * Interrupt handling. Preserves r7, r8, r9
- */
- .macro irq_handler
- get_irqnr_preamble r5, lr
- 1: get_irqnr_and_base r0, r6, r5, lr
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- adrne lr, 1b
- bne asm_do_IRQ
- #ifdef CONFIG_SMP
- /*
- * XXX
- *
- * this macro assumes that irqstat (r6) and base (r5) are
- * preserved from get_irqnr_and_base above
- */
- test_for_ipi r0, r6, r5, lr
- movne r0, sp
- adrne lr, 1b
- bne do_IPI
- #ifdef CONFIG_LOCAL_TIMERS
- test_for_ltirq r0, r6, r5, lr
- movne r0, sp
- adrne lr, 1b
- bne do_local_timer
- #endif
- #endif
- .endm
复制代码 其中get_irqnr_and_base用来获得本次中断的硬件中断号,显然是个平台相关的函数,所以BSP的伙计们必须针对特定的平台来实现这个函数。这个函数的定义一般是放在include/asm-arm/arch-imx/entry-macro.S, arch-imx便是一个特定的ARM平台。这段代码会和平台上的中断控制器打交道,用来获得硬件中断号,放在r0中, r1放的是struct pt_regs *,然后跳转到asm_do_IRQ(). Yes, asm_do_IRQ!多么熟悉的身影啊, 经常使C的程序员们就象看到了失散多年的亲人一样,眼泪哗哗的啊。。。。。。。。。。。。 |
|