概述
管理系统中存在的各种设备是内核的主要职责,内核一般可以通过两种方式来履行这个职责:
轮询:内核以一定的周期访问设备,查询设备的状态并进行处理。
中断:设备在需要时通知内核,内核收到设备的请求后再做出相应处理。
使用轮询方式时,内核对设备的访问按照一定频率周期地进行,因而常常会出现设备的请求不能得到及时的处理,或者在内核一次又一次的访问中没有
发现设备的任何请求,进而消费了大量的CPU资源的情况。
而使用中断方式则不同,内核成为被动的一方,只有在收到设备的中断请求时,才中断当前正在进行的工作去进行中断处理。
中断分类
中断可分为同步中断和异步中断。
同步中断由CPU本身产生,又称为内部中断。这里的同步是指中断请求信号与代码指令之间的同步执行,即只有在一条指令执行完毕后,而不是执行期
间,CPU才会发出中断。
异步中断有其他硬件设备产生,又称为外部中断。与同步中断相反,异步中断可于任何时间产生,包括指令执行期间。
通常将同步中断称为异常,将异步中断称为中断,我们也将采用这种说法。
异常产生于CPU在指令执行期间检测到异常或非法的条件时,与当前正在执行的指令有直接的联系。而中断通常用于指示设备的特定操作已经完成,与
当前正执行的指令之间并没有直接联系。
异常包括故障、陷阱和中止。故障是指在引起异常的指令之前,把该异常情况通知给系统的一种异常。故障处理结束后,返回到引起故障的指令并执行。
陷阱是指在引起异常的指令之后,把该异常情况通知给系统的一种异常。在转入相应的处理程序进行陷阱处理时,引起陷阱的指令应该已经正常完成,
因此陷阱处理结束后,将返回到引起陷阱的指令的下一条指令并执行。
中止是在系统出现严重情况时,通知系统的一种异常。引起中止的指令是无法确定的,产生中止时,正执行的程序不能被恢复执行。
中断包括可屏蔽中断和不可屏蔽中断。CPU提供了两条外接引脚用于中断,即NMI和INTR。其中,NMI用于不可屏蔽中断,比如电源掉电,一旦产生,CPU
必须立即无条件响应,否则进行其他工作毫无意义,INTR用于可屏蔽中断,主要是外部I/O设备的中断信号,比如打印机中断,这些中断信号需要通过中断
控制器传递给CPU。可屏蔽中断有屏蔽和非屏蔽两种状态,处于屏蔽状态的中断将被忽略。
可屏蔽中断受EFLAGES寄存器的中断允许标志位IF控制。
PIC vs APIC
中断控制器有可编程中断控制器和高级可编程中断控制器两种。
前者只能用于单处理器平台,而后者则可以用于多处理器平台。目前,无论UP平台还是MP,多数使用的都是APIC。
1.可编程中断控制器8259A
单个8259A芯片只能管理8个中断源,若是需要管理更多的中断源,则必须将多个芯片级联。虽然最多可以级联成64级,但传统的PIC都是采用两个8259A
级联的方式,支持15个中断源(第一个8259A芯片的IR2引脚用于串联第二个8259A芯片)。
中断控制器与其他硬件设备相连接的各条线被称做中断线。由于数目有限,所以中断线是非常宝贵的资源,使用之前,必须首先在设备的驱动程序中进行
中断线的申请,获得该中断线的控制权,才能发送中断信号。
中断线又被称为IRQ(Interrupt ReQuest)线,只有当设备确实需要使用中断的时候才能申请占用,或者在申请时采用与其他设备共享中断线的方式。
中断线按照一定的顺序进行编号,这个编号即是中断号。
8259A的输出连接到CPU的INTR引脚上。外设发出中断信号时,若对应的中断没有被屏蔽,则拉高INTR引脚通知CPU有中断发生,CPU可以通过INTA
引脚应答,表示收到中断请求。
2.高级可编程中断控制器APIC
与8259A相比,APIC最大的优势是可适用于MP平台,以及可支持更多的中断源。
APIC由两部分组成:本地高级中断控制器(Local APIC,LAPIC),位于CPU中,主要负责传递中断信号到指定的处理器,在MP平台,每个CPU都具有一个
自己的LAPIC;I/O高级中断控制器(I/O APCI,IOAPIC)负责收集来自I/O设备的中断信号并分发给LAPIC,系统中最多可以拥有8个I/O APIC。
在一个典型的MP平台上,通常有一个IOAPIC和多个LAPIC,所有的LAPIC都连接到I/O APIC,形成一个多级的APIC中断分发网络。
中断号 vs 中断向量
无论是中断还是异常,CPU的响应过程基本一致,即根据中断源所提供的中断向量,从中断描述符表中获取相应处理程序的地址,然后执行。
Intel X86能够支持256种不同的中断,并将它们从0~255进行编号,用于区分不同的中断源。这个8位的编号通常被称为中断向量。
与中断号不同,中断向量是从CPU角度看到的中断信号划分。当I/O设备把中断信号发送给中断控制器时,与之关联的是一个中断号;而当中断控制器将
该信号传递给CPU时,与之关联的则是一个中断向量。
中断号与中断向量之间存在一对一的映射关系。对于8259A,缺省是中断号加上32等于对应的中断向量。
中断服务程序
中断服务程序必须在设备驱动程序中定义,并在使用request_irq函数申请IRQ线时,关联到所申请到的IRQ线上。它们都具有如下相同的原型。
中断服务程序的返回值是一个特殊类型——irqreturn_t,它在include/linux/irqreturn.h文件中定义。
irqreturn_t只能取两个值:IRQ_NONE表示不处理所收到的中断请求,比如当中断服务程序发现该中断请求并不由自己负责时:IRQ_HANDLED表示
接收到了有效的中断请求,并且做出了正确的处理。另外,也可以使用宏IRQ_RETVAL(x),若x为非0值,返回IRQ_HANDLED,否则返回IRQ_NONE.
中断服务程序是无需重入的。当一个给定的中断服务程序正在执行时,相应的中断线在所有服务器上都会被屏蔽,以避免在同一中断线上接收另一个新
的中断。因此,同一个中断服务程序绝对不会被同时调用。
————————————————
版权声明:本文为CSDN博主「马冬冬」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mdd18703649811/article/details/48241415