Linux的中断和中断处理

中断

硬件在需要时候向内核发出信号。
从物理学角度看中断是一种电信号,由硬件产生,并直接送入中断控制器的输入引脚中,中断控制器是一个多路复用的控制器,当从多个引脚之一接收到信号后,会通知处理器,此时处理器会中断当前工作转而处理中断,并且通知操作系统已经产生中断,操作系统运行处理中断的程序。

中断值

中断值通常被称为中断请求(IRQ)线。
特定的中断总要和特定的设备相联系,并且内核要知道这些信息,从而设备发出信息后内核能够分辨出要处理的信息。

中断处理程序

在响应特定中断时,内核会执行一个函数,该函数叫做中断处理程序。
通常来说,一个设备有一个中断处理程序,这是他驱动程序的一部分。
在Linux中,中断处理程序就是普通的c函数,只是使用特定的声明。
中断处理程序运行在中断上下文中,该上下文执行代码不可阻塞。

中断的上半部和下半部

为了让中断运行的快,我们将不紧迫,花费时间多的工作放到下半部处理。
以网卡为例,当网卡接收到数据包存放在自己的缓存中时,通知系统发生中断处理数据包,中断开始执行,将网卡数据包拷贝到操作系统的内存,中断上半部分结束。将控制权返还给操作系统,处理和操作数据包的其他工作在下半部分进行。

中断线可以被多个设备共享,而中断处理程序也可以被多个中断线共享

注册中断处理程序

中断处理程序是设备驱动的组成部分。
驱动程序通过函数request_irq()来注册中断程序,并且激活中断请求线。
中断线是共享的,则一个中断会发生很多中断处理程序的执行。

驱动给设备分配一条给定的中断线:
	int request_irq(unsigned int irq,
							irq_handler_t handler,
							unsigned long flags,
							const char* name,
							void *dev);
	参数一:中断号
	参数二:中断处理函数指针
	参数三:中断处理标志(IRQF_DISABLED:内核在处理这个中断时,要终止其他所有中断;IRQF_SHARD:多个中断处理程序之间共享中断线)
	参数四:中断设备的名字(eg.“keyboard")
	参数五:共享中断线,用来区分不同的设备,如果无需共享为NULL

编写中断处理程序

irqreturn_t intr_handler(int irq,void *dev);dev用来区分处理中断线的设备(多设备处理一中断的情况下)

Linux的中断处理程序是不可重入的,即如果中断处理程序正在执行中断a时发生了中断a,系统会忽略。
但是除了中断a的中断都是可以处理的。

中断上下文

在进程上下文中可以通过current宏获得正在执行的进程的pcb,所以可以睡眠。
而中断上下文不能重新找到上下文,所以不能睡眠。
中断上下文的栈是一页。同时内核栈也是一页。

中断处理机制的实现

设备硬件产生一个中断,发送给中断控制器,中断控制器发送给处理器,处理器跳到do_IRQ()函数的位置执行,判断该线上是否有中断处理程序,如果有则运行所有的中断处理程序,返回内核中断的代码。

你可能感兴趣的:(Linux,linux,运维,服务器)