现在的位置: 首页 > 综合 > 正文

与中断有关的数据结构

2013年03月08日 ⁄ 综合 ⁄ 共 1131字 ⁄ 字号 评论关闭

1.概述

通过前文,我们已经知道了中断通常由上下两部分组成。在上部分,也就是中断处理程序,完成中断请求的响应以及完成那些对时间要求紧迫的工作;而在下部分,通常完成那些被推后的工作,因为这部分工作对时间的要求相对宽松一些。通过了解上下两部分的工作情况,可以更好的理解中断这个概念。从下半部分执行机制来看——不管是tasklet还是工作队列——这些推后的工作总是在上半部分被调用,然后交给内核在适当的时间来完成。那么,中断上部分具体是如何工作的?内核对中断是如何处理的?

在开始分析之前,需要说明的是接下来分析的属于内核对外设产生的中断的处理情况,异常的处理过程在本文的最后会有简单解释。

所有的中断的处理程序在init_IRQ函数中都被初始化为interrupt[i]。interrupt数组中每一项均指向一个代码片段:

1 pushl
$n-256
2 /*省略部分代码*/
3 jmp
common_interrupt

该代码片段除了将中断向量号压入堆栈,还会跳到一个公共处理程序common_interrup:

1 //在linux/arch/x86/kernel/entry_32.S
2  863
common_interrupt:
3  864        
addl $-0x80,(%esp)      /* Adjust vector into the [-256,-1] range *     /
4  865        
SAVE_ALL
5  866        
TRACE_IRQS_OFF
6  867        
movl %esp,%eax
7  868        
call do_IRQ
8  869        
jmp ret_from_intr

这段公共处理程序会将中断发生前的所有寄存器的值压入堆栈,也就是保存被中断任务的现场。然后调用do_IRQ函数,在do_IRQ函数中会调用(并非直接调用那么简单)到handle_IRQ_event函数,在此函数中会执行实际的中断服务例程。当中断服务例程执行完毕后,会返回到上面的那段汇编程序中,转入ret_from_intr代码段从中断返回。

在上述文字描述的基础上,可以通过下图进一步加深中断的处理过程:

从上面的概述中,我们可以很快定位我们未来要分析的函数:do_IRQ()和hand_IRQ_event();在分析上述函数之前,我们很有必要先分析一下关于中断的三个重要的数据结构。

2.struct irq_desc

在一开始我们分析中断的时候,谈及到了中断向量。在内核中,每个中断向量都有相应的有一个irq_desc结构体(稍早内核版本中为irq_desc_t)来描述一个中断向量(也就是中断源),具体代码如下:

01 31struct
irq_desc;
02  

抱歉!评论已关闭.