一、前言
Linux的中断宏观分为两种:软中断和硬中断。声明一下,这里的软和硬的意思是指和软件相关以及和硬件相关,而不是软件实现的中断或硬件实现的中断。
软中断就是"信号机制"。软中不是软件中断。Linux通过信号来产生对进程的各种中断操作,我们现在知道的信号共有31个,其具体内容这里略过,感兴趣读者可参看相关参考文献[1]。一般来说,软中断是由内核机制的触发事件引起的(例如进程运行超时),但是不可忽视有大量的软中断也是由于和硬件有关的中断引起的,例如当打印机端口产生一个硬件中断时,会通知和硬件相关的硬中断,硬中断就会产生一个软中断并送到操作系统内核里,这样内核就会根据这个软中断唤醒睡眠在打印机任务队列中的处理进程。
硬中断就是通常意义上的"中断处理程序",它是直接处理由硬件发过来的中断信号的。当硬中断收到它应当处理的中断信号以后,就回去自己驱动的设备上去看看设备的状态寄存器以了解发生了什么事情,并进行相应的操作。对于软中断,我们不做讨论,那是进程调度里要考虑的事情。由于我们讨论的是设备驱动程序的中断问题,所以焦点集中在硬中断里。我们这里讨论的是硬中断,即和硬件相关的中断。
二、中断产生
要中断,是因为外设需要通知操作系统她那里发生了一些事情,但是中断的功能仅仅是一个设备报警灯,当灯亮的时候中断处理程序只知道有事情发生了,但发生了什么事情还要亲自到设备那里去看才行。也就是说,当中断处理程序得知设备发生了一个中断的时候,它并不知道设备发生了什么事情,只有当它访问了设备上的一些状态寄存器以后,才能知道具体发生了什么,要怎么去处理。
设备通过中断线向中断控制器发送高电平告诉操作系统它产生了一个中断,而操作系统会从中断控制器的状态位知道是哪条中断线上产生了中断。PC机上使用的中断控制器是8259,这种控制器每一个可以管理8条中断线,当两个8259级联的时候共可以控制15条中断线。这里的中断线是实实在在的电路,他们通过硬件接口连接到CPU外的设备控制器上。
三、IRQ
并不是每个设备都可以向中断线上发中断信号的,只有对某一条确定的中断线勇有了控制权,才可以向这条中断线上发送信号。由于计算机的外部设备越来越多,所以15条中断线已经不够用了,中断线是非常宝贵的资源。要使用中断线,就得进行中断线的申请,就是IRQ(Interrupt Requirement),我们也常把申请一条中断线成为申请一个IRQ或者是申请一个中断号。
IRQ是非常宝贵的,所以我们建议只有当设备需要中断的时候才申请占用一个IRQ,或者是在申请IRQ时采用共享中断的方式,这样可以让更多的设备使用中断。
无论对IRQ的使用方式是独占还是共享,申请IRQ的过程都是一样的,分为3步:
1.将所有的中断线探测一遍,看看哪些中断还没有被占用。从这些还没有被占用的中断中选一个作为该设备的IRQ。
2.通过中断申请函数申请选定的IRQ,这是要指定申请的方式是独占还是共享。
3.根据中断申请函数的返回值决定怎么做:如果成功了万事大吉,如果没成功则或者重新申请或者放弃申请并返回错误。
申请IRQ的过程,在参考书的配的源代码里有详细的描述,读者可以通过仔细阅读源代码中的short一例对中断号申请由深刻的理解。