您好、欢迎来到现金彩票网!
当前位置:2019跑狗图高清彩图 > 向量屏蔽 >

linux中断源码分析34--中断发生

发布时间:2019-08-09 21:18 来源:未知 编辑:admin

  上篇文章已经描述了中断描述符表和中断描述符数组的初始化,由于在初始化期间系统关闭了中断(通过设置CPU的EFLAGS寄存器的IF标志位为0),当整个中断和异常的初始化完成后,系统会开启中断(设置CPU的EFLAGS寄存器的IF标志位为1),此时整个系统的中断已经开始可以使用了。本篇文章我们具体研究一次典型中断发生时的运行流程。

  当进入到中断时,中断处理程序会调用irq_enter()函数禁止抢占和调度。当中断退出时,会通过irq_exit()减少其硬件计数器。我们需要清楚的就是,无论系统处于硬中断还是软中断,调度和抢占都是被禁止的。

  边沿触发方式。当一个外部设备产生中断,中断信号会沿着中断线到达中断控制器。中断控制器接收到该外部设备的中断信号后首先会检测自己的中断屏蔽寄存器是否屏蔽该中断。如果没有,则设置中断请求寄存器中中断向量号对应的位,并将INTR拉高用于通知CPU,CPU每当执行完一条指令时都会去检查INTR引脚是否有信号(这是CPU自动进行的),如果有信号,CPU还会检查EFLAGS寄存器的IF标志位是否禁止了中断(IF = 0),如果CPU未禁止中断,CPU会自动通过INTA信号线应答中断控制器。CPU再次通过INTA信号线通知中断控制器,此时中断控制器会把中断向量号送到数据线上,CPU读取数据线获取中断向量号。到这里实际上中断向量号已经发送给CPU了,如果中断控制器是AEIO模式,则会自动清除中断向量号对应的中断请求寄存器的位,如果是EIO模式,则等待CPU发送的EIO信号后在清除中断向量号对应的中断请求寄存器的位。用步骤描述就是:

  动态分发。区别就是静态分发设置了指定中断送往指定的一个或多个CPU上。动态分发则是由中断控制器控制中断应该发往哪个CPU或CPU组。CPU已经接收到了中断信号以及中断向量号。此时CPU会自动跳转到中断描述符表地址,以中断向量号作为一个偏移量,直接访问中断向量号对应的门描述符。在门描述符中,有个特权级(DPL),系统会先检查这个位,然后清除EFLAGS的IF标志位(这也说明了发发生中断时实际上CPU是禁止其他可屏蔽中断的),之后转到描述符中的中断处理程序中。在上一篇文章我们知道,所有的中断门描述符的中断处理程序都被初始化成了interrupt[i],它是一段汇编代码。

  被中断上下文(进程上下文或者中断上下文)保存到栈中,最后调用do_IRQ函数。

  好的,最后执行中断描述符中的handle_irq指针所指函数,我们回忆一下,在初始化阶段,所有的中断描述符的handle_irq指针指向了handle_level_irq()函数,文章开头我们也说过,中断产生方式有两种:一种电平触发、一种是边沿触发。handle_level_irq()函数就是用于处理电平触发的情况,系统内建了一些handle_irq函数,具体定义在include/linux/irq.h文件中,我们罗列几种常用的:

  CPU禁止中断,当CPU进入到中断处理时自动会清除EFLAGS的IF标志,也就是进入中断处理时会自动禁止中断。在SMP系统中,就是单个CPU禁止中断。

  在中断控制器处就屏蔽中断,这样该中断产生后并不会发到CPU上。在SMP系统中,效果相当于所有CPU屏蔽了此中断。系统在执行此中断的中断处理函数才会要求中断控制器屏蔽该中断,所以没必要在此中断的处理过程中中断控制器再发一次中断信号给CPU。

  在SMP系统中,同一个中断信号有可能发往多个CPU,但是中断处理只应该处理一次,所以设置状态为IRQD_IRQ_INPROGRESS,其他CPU执行此中断时都会先检查此状态(可看handle_level_irq()函数)。

  所以在SMP系统下,对于handle_level_irq而言,一次典型的情况是:中断控制器接收到中断信号,发送给一个或多个CPU,收到的CPU会自动禁止中断,并执行中断处理函数,在中断处理函数中CPU会通知中断控制器屏蔽该中断,之后当执行中断服务例程时会设置该中断描述符的状态为IRQD_IRQ_INPROGRESS,表明其他CPU如果执行该中断就直接退出,因为本CPU已经在处理了。

  上篇文章已经描述了中断描述符表和中断描述符数组的初始化,由于在初始化期间系统关闭了中断(通过设置CPU的EFLAGS寄存器的IF标志位为0),当整个中断和异常的初始化完成后,系统会开启中断(设置CPU的EFLAGS寄存器的IF标志位为1),此时整个系统的中断已经开始可以使用了。本篇文章我们具体研究一次典型中断发生时的运行流程。

  当进入到中断时,中断处理程序会调用irq_enter()函数禁止抢占和调度。当中断退出时,会通过irq_exit()减少其硬件计数器。我们需要清楚的就是,无论系统处于硬中断还是软中断,调度和抢占都是被禁止的。

  边沿触发方式。当一个外部设备产生中断,中断信号会沿着中断线到达中断控制器。中断控制器接收到该外部设备的中断信号后首先会检测自己的中断屏蔽寄存器是否屏蔽该中断。如果没有,则设置中断请求寄存器中中断向量号对应的位,并将INTR拉高用于通知CPU,CPU每当执行完一条指令时都会去检查INTR引脚是否有信号(这是CPU自动进行的),如果有信号,CPU还会检查EFLAGS寄存器的IF标志位是否禁止了中断(IF = 0),如果CPU未禁止中断,CPU会自动通过INTA信号线应答中断控制器。CPU再次通过INTA信号线通知中断控制器,此时中断控制器会把中断向量号送到数据线上,CPU读取数据线获取中断向量号。到这里实际上中断向量号已经发送给CPU了,如果中断控制器是AEIO模式,则会自动清除中断向量号对应的中断请求寄存器的位,如果是EIO模式,则等待CPU发送的EIO信号后在清除中断向量号对应的中断请求寄存器的位。用步骤描述就是:

  动态分发。区别就是静态分发设置了指定中断送往指定的一个或多个CPU上。动态分发则是由中断控制器控制中断应该发往哪个CPU或CPU组。CPU已经接收到了中断信号以及中断向量号。此时CPU会自动跳转到中断描述符表地址,以中断向量号作为一个偏移量,直接访问中断向量号对应的门描述符。在门描述符中,有个特权级(DPL),系统会先检查这个位,然后清除EFLAGS的IF标志位(这也说明了发发生中断时实际上CPU是禁止其他可屏蔽中断的),之后转到描述符中的中断处理程序中。在上一篇文章我们知道,所有的中断门描述符的中断处理程序都被初始化成了interrupt[i],它是一段汇编代码。

  被中断上下文(进程上下文或者中断上下文)保存到栈中,最后调用do_IRQ函数。

  好的,最后执行中断描述符中的handle_irq指针所指函数,我们回忆一下,在初始化阶段,所有的中断描述符的handle_irq指针指向了handle_level_irq()函数,文章开头我们也说过,中断产生方式有两种:一种电平触发、一种是边沿触发。handle_level_irq()函数就是用于处理电平触发的情况,系统内建了一些handle_irq函数,具体定义在include/linux/irq.h文件中,我们罗列几种常用的:

  CPU禁止中断,当CPU进入到中断处理时自动会清除EFLAGS的IF标志,也就是进入中断处理时会自动禁止中断。在SMP系统中,就是单个CPU禁止中断。

  在中断控制器处就屏蔽中断,这样该中断产生后并不会发到CPU上。在SMP系统中,效果相当于所有CPU屏蔽了此中断。系统在执行此中断的中断处理函数才会要求中断控制器屏蔽该中断,所以没必要在此中断的处理过程中中断控制器再发一次中断信号给CPU。

  在SMP系统中,同一个中断信号有可能发往多个CPU,但是中断处理只应该处理一次,所以设置状态为IRQD_IRQ_INPROGRESS,其他CPU执行此中断时都会先检查此状态(可看handle_level_irq()函数)。

  所以在SMP系统下,对于handle_level_irq而言,一次典型的情况是:中断控制器接收到中断信号,发送给一个或多个CPU,收到的CPU会自动禁止中断,并执行中断处理函数,在中断处理函数中CPU会通知中断控制器屏蔽该中断,之后当执行中断服务例程时会设置该中断描述符的状态为IRQD_IRQ_INPROGRESS,表明其他CPU如果执行该中断就直接退出,因为本CPU已经在处理了。

http://bluecaleel.com/xiangliangpingbi/329.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有