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编译器才会确定这个数组的类型和大小。
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编译器才会确定这个数组的类型和大小。
相关文章推荐
- linux 中断相关的几个问题
- 使用linux的几个需要注意的问题(后续增补)
- Linux中断(interrupt)子系统之二:arch相关的硬件封装层
- MTK平台释疑android M 配置中断相关问题
- linux安装软件包相关问题
- linux_sound_alsa_Android+alsa音频系统中的几个问题
- Linux相关问题-CentOS6.5 x64版本号下Tomcat无法自启动的解决的方法
- 转:linux下svn服务器搭建以及相关问题解决方案
- 数据挖掘相关的几个问题
- linux信号处理 --和信号相关的几个系统调用
- linux下mysql出现的几个小问题
- 几个 Windows 到 Linux 的代码移植问题
- Linux启动vsftp相关问题
- Linux下Socket编程中注意的几个问题及要点总结
- Android绘制View相关的几个问题
- LINUX 系统如何配置IP 和NDS 还有相关问题解决办法
- 关于嵌入式 linux/wince几个很重要的几个问题
- linux相关问题解决方案
- FIleZilla连接linux(Ubuntu)服务器的相关问题
- linux内存相关整理--为了看swap的问题