预览加载中,请您耐心等待几秒...
1/10
2/10
3/10
4/10
5/10
6/10
7/10
8/10
9/10
10/10

亲,该文档总共40页,到这已经超出免费预览范围,如果喜欢就直接下载吧~

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

第五章Linux内核的中断机制(By詹荣开,NUDT)Copyright©2003by詹荣开E-mail:zhanrk@sohu.comLinux-2.4.0Version1.0.0,2003-2-14摘要:本文主要从内核实现的角度分析了Linux2.4.0内核的设备中断流程。本文是为那些想要了解LinuxI/O子系统的读者和Linux驱动程序开发人员而写的。关键词:Linux、中断、设备驱动程序申明:这份文档是按照自由软件开放源代码的精神发布的,任何人可以免费获得、使用和重新发布,但是你没有限制别人重新发布你发布内容的权利。发布本文的目的是希望它能对读者有用,但没有任何担保,甚至没有适合特定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证(GPL),以及GNU自由文档协议(GFDL)。你应该已经和文档一起收到一份GNU通用公共许可证(GPL)的副本。如果还没有,写信给:TheFreeSoftwareFoundation,Inc.,675MassAve,Cambridge,MA02139,USA欢迎各位指出文档中的错误与疑问。§5.1I386的中断与异常中断通常被分为“同步中断”和异步中断两大类。同步中断是指当指令执行时由CPU控制单元产生的中断,之所以称为“同步中断”是因为只有在一条指令中止执行后CPU才会发出这类中断信号。而异步中断则是指由其他硬件设备依照CPU时钟随机产生的中断信号。在Intel80x86CPU手册中,同步中断和异步中断也被分别称为“异常(Exception)”和“中断(Interrupt)”。Intel又详细地把中断和异常细分为以下几类:(1)中断1.可屏蔽中断(MaskableInterrupt):这类中断被送到CPU的INTR引脚,通过清除eflag寄存器的IF标志可以关闭中断。2.不可屏蔽中断(NonmaskableInterrupt):被送到CPU的NMI引脚,通常只有几个危急的事件,如:硬件故障等,才产生不可屏蔽中断信号。寄存器eflag中的IF标志对这类中断不起作用。(2)异常1.处理器探测异常(Processor-detectedexception):当CPU执行一条指令时所探测到的一个反常条件所产生的异常。依据CPU控制单元产生异常时保存在内核态堆栈eip寄存器的值,这类异常又可以细分为三种:n故障(Fault):保存在eip中的值是引起故障的指令地址,因此但异常处理程序结束后,会重新执行那条指令。“缺页故障”是这类异常的一个常见例子。n陷阱(Trap):保存在eip中的值是一个指令地址,但该指令在引起陷阱的指令地址之后。只有当没有必要重新执行已执行过的指令时,才会触发trap,其主要用途是调试程序。n异常中止(Abort):当发生了一个严重的错误,致使CPU控制单元除了麻烦而不能在eip寄存器中保存有意义的值。异常中止通常是由硬件故障或系统表中无效的值引起的。由CPU控制单元发生的这个中断是一种紧急信号,用来把CPU的执行路径切换到异常中止的处理程序,而相应的ISR通常除了迫使受到影响的进程中止外,别无选择。2.编程异常(ProgrammedException):通常也称为“软中断(softwareinterrupt)”,是由编程者发出中断请求指令时发生的中断,如:int指令和int3指令。当into(检查溢出)和bound(检查地址越界)指令检查的条件不为真时,也引起编程异常。CPU控制单元把编程异常当作Trap来处理,这类异常有两个典型的用途:一、执行系统调用;二、给调试程序通报一个特定条件。5.1.1中断向量每个中断和异常都可以用一个0-255之间的无符号整数来标识,Intel称之为“中断向量(InterruptVector)”。通常,不可屏蔽中断和异常的中断向量是固定的,而可屏蔽中断的中断向量则可以对中断控制器进行编程来改变。I386CPU的256个中断向量是这样分配的:1.从0-31这一共32个向量用于异常和不可屏蔽中断。2.从32-47这一共16个向量用于可屏蔽中断,分别对应于主、从8259A中断控制器的IRQ输入线。3.剩余的48-255用于标识软中断。Linux全部使用了0-47之间的向量。但对于48-255之间的软中断向量,Linux只使用了其中的一个,即用于实现系统调用的中断向量128(0x80)。当用户态下的进程执行一条int0x80汇编指令时,CPU切换到内核态,以服务于系统调用。Linux在头文件include/asm-i386/hw_irq.h中定义了宏FIRST_EXTERNAL_VECTOR来表示第一个外设中断(即8259A的IRQ0)所对应的中断向量,此外还定义了SYSCALL_VECTOR来表示用于系统调用的中断向量。如下所示:/*