您的位置:首页 > 运维架构 > Linux

linux 中断相关的几个问题

2010-08-29 14:17 225 查看
一 linux实现的几个门

intel 提供了三种类型的中断描述符:任务门,中断门,陷阱门。linux稍有不同,根据intel的定义,实现了一下几类门。

1 中断门

用户态的进程不能访问的一个intel中断门,DPL = 0。

2 系统门

用户态的进程可以访问的一个intel陷阱门,DPL = 3, 通过系统门可以激活linux下的三个异常:4,5,128(即0x80)。

3 系统中断门

用户态的进程可以访问的一个intel中断门,DPL = 3,中断异常就属于系统中断门,int 0x03。

4 陷阱门

用户态的进程不能够访问的intel陷阱门,DPL = 0.

5 任务门

不能被用户态进程访问的intel任务门, DPL = 0。

二 中断处理函数数组 interrupt[i]

在entry_32.S中的下面的汇编代码,声明和初始化了interrupt数组,有几个细节值得分析。

/*interrupt数组的声明和初始化,里面存储中断处理函数的地址*/

/*interrupt数组就像c语言的数组一样,属于数据段的东西,因此在数据段声明。但是对数组的初始化就是代码段的内容了,这里需要注意*/
.data
ENTRY(interrupt)
.text

ENTRY(irq_entries_start)
RING0_INT_FRAME
vector=0
.rept NR_IRQS
ALIGN
.if vector
CFI_ADJUST_CFA_OFFSET -4
.endif
1: pushl $~(vector)
CFI_ADJUST_CFA_OFFSET 4
jmp common_interrupt
.previous /*previous 知名下面内容上接上一个段,即data段*/
.long 1b
.text
vector=vector+1
.endr
END(irq_entries_start)

.previous
END(interrupt) /*这句是数据段的内容*/
.previous

可以总结为:

上面一段汇编首先在数据段声明了一个interrupt数组,如下面代码:

.data
ENTRY(interrupt)

.long 1b

END(interrupt)

数组中每个元素的初始值是标号1的地址。因此访问数组中的元素时,都会跳到标号1处,执行相应的指令。

还有一个细节问题:在i8259_32.c中调用函数set_intr_gate(vector, interrupt[i]);

这里引用了在entry_32.S中数据段中定义的全局的interrupt数组,但是,数据段中定义的这个intterrupt数组只能用在连接的时候,这个符号是已经定义过得,至于它的类型和大小等c编译器无法确定,因此,在hw_irq_32.h中重新声明了extern void (*interrupt[NR_IRQS])(void),这样c编译器才会确定这个数组的类型和大小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: