`
woodding2008
  • 浏览: 289617 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Linux中断和中断处理

 
阅读更多

            众所周知,处理器的速度跟外围的硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器发送一个请求,然后专门等待回应的办法,显然差强人意。既然硬件处理的这么慢,那么内核就应该在这期间去处理其他事务,等待硬件真正完成了请求的操作后,再回过头来对它进行处理。

            轮询(polling)可能会是一种解决办法。它可以让内核定期对设备的状态进行查询,然后做出相应的处理。不过这种方法可能会让内核做不少不用功。更好的办法是提供一种机制,让硬件在需要的时候想内核发出信号,这就是中断机制。

 

中断

       中断使得硬件得以发出通知给处理器。在你敲击键盘的时候,键盘控制器会发送一个中断,通知操作系统有键按下。中断本质上是一种特殊的电信号,有硬件设备向处理器发出。处理器收到中断后,会马上向操作系统反应此信号的到来,然后就由操作系统负责处理这些新到来的数据。硬件设备生成中断的时候并不考虑处理器的时钟同步---换句话说就是中断随时产生,因此,内核随时可能因为新到来的中断而被打断。

 

中断处理程序

    在相应一个特定中断的时候,内核会执行一个函数,该函数叫作中断处理程序或中断服务例程(interrupt service routine,ISR)。产生中断的每个设备都有一个相应的中断处理程序。例如:由一个函数专门处理来自系统时钟的中断,而另外一个函数专门处理键盘产生的中断。一个设备的中断程序时它设备驱动程序的一部分---设备驱动程序是用于对设备进行管理的内核代码。中断处理程序负责通知硬件设备中断已经被接收。同时中断程序还要处理其他工作,比如要把来自硬件的网络数据包拷贝到内存,对其进行处理后再交给合适的协议栈或应用程序。

 

上半部与下半部的对比

        又想中断处理程序运行的快,又想中断程序完成的工作多,这两个目的显然有所抵触。鉴于两个目的之间存在的此消彼长的矛盾关系,所以我们一般把处理切为两半部分执行。中断时上半部分(top half)---接收到一个中断,它就立即执行,但是做有严格时限的工作,例如对接收的中断进行应答或者复位硬件,这些工作都是所有中断被禁止的情况下完成的。能够被允许稍后完成的工作会推迟到下半部(bottom half)去。此后,在合适的时机,下半部会被中断执行。

 

中断上下文

     当执行一个中断处理程序时,内核处于中断上下文(interrput context)中。进程上下文是一种内核所处的操作模式,此时内核代表进程执行---例如,执行系统调用或运行内核线程。在进程上下文中,可以通过current宏关联当前进程。此外,因为进程是以进程上下文的形势连接到内核中的,因此,进程上下文可以睡眠,也可以调用调度程序。

      与之相反,中断上下文和进程并没有什么瓜葛。与current宏也是不相干的。因为没有后备进程,所以中断上下文不可以休眠,否则又怎能再对它重新调度呢?,因此,不能从中断上下文中调用某些函数。如果一个函数睡眠,就不能在你的中断处理程序中使用它---这是对什么样的函数可以在中断成立程序中使用的限制。

      中断上下文具有较为严格的时间限制。因为它打断了其他代码。中断上下文的代码应当迅速,简洁,尽量不要使用循环去处理繁重的工作。尽量把工作从中断处理程序中分离出来,放在下半部来执行,因为下半部可以在更合适的时间运行。

      中断处理程序之前并不具有自己的栈,他们共享所有进程的内核栈,内核栈的大小是两页,在32位的体系结构上是8KB,在64位体系结构上是16KB。因为在这种设置中,中断处理共享别人的堆栈。2.6早期版本的内核中,增加了一个选项,把栈的大小从两页减小到一页。也就是32位系统只提供4KB的栈。这就减轻了内存的压力,因为系统中每个进程原先都需要两页连续,且不可换出的内核内存。为了应对栈大小的压力,中断处理程序拥有了自己的栈。

中断处理机制的实现

       中断处理系统在Linux中的实现是非常依赖体系结构的,实现依赖于处理器、所使用的中断控制器的类型、体系结构的设计以及机器本身。

       下图是中断从硬件到内核的路由,设备产生中断,通过总线把电信号发送给中断控制器,如果中断线是激活的(他们是允许被屏蔽的),那么中断控制器就会把中断发往处理器。在大多数体系结构中,这个工作就是通过电信号给处理器的特定管脚发送一个信号。除非在处理器上禁止该中断,否则,处理器会立即停止它正在做的事情,关闭中断系统,然后调到内存中预定义的位置开始执行那里的代码。这个预定义的位置是由内核设置的,是中断处理程序的入口点。

 

      

中断控制

      Linux内核提供了一组接口用于操作机器上的中断状态。这些接口为我们提供了能够禁止当前处理器的中断系统,或屏蔽掉整个机器的一条中断线的能力,这些例子都是与体系结构相关的。

      控制中断系统的原因归根结底是需要提供同步。通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码。此外,禁止中断还可以禁止内核抢占。然而,不管是禁止中断还是禁止内核抢占,都没有提供任何的保护机制来防止来自其他处理器的并发访问。Linux支持多处理器,因此,内核代码一般需要获取某种锁,防止来自其他处理器对共享数据的并发访问。获取这些锁的同时也伴随着禁止本地中断。锁提供保护机制,防止来自其他处理器的并发访问,而禁止中断提供提供保护机制,则是防止来自其他中断程序并发访问。

 

 

下半部和退后执行的工作

        中断处理程序时内核中很有用的部分,但是由于本身存在的一些局限,所以它只能完成整个中断处理流程的上半部分,这些局限包括:

  • 中断处理程序以一部方式执行,并且它有可能会打断其他重要代码(设置包括其他中断处理程序)的执行,因此为了避免被打断的代码停止时间过长,中断处理程序应该执行的越快越好。
  • 如果当前有一个中断处理程序正在执行,在最好的情况下,与该中断同级的其他中断会被屏蔽,在最坏情况下,当前处理器上所有其他中断都会被屏蔽。因此禁止中断后硬件与操作系统无法通信,因此中断处理程序执行的愉快越好。
  • 由于中断处理程序往往需要对硬件进行操作,所以他们通常有很高的时限要求。
  • 中断处理程序不在进程上下文中运行,所以他们不能阻塞,这限制了他们所做的事情。

      现在,为什么中断处理程序只能作为整个硬件处理流程一部分的原因就很明显了,操作系统必须有一个快速、异步、简单的机制对硬件作出迅速响应并完成那些时间要求严格的操作。中断处理程序很适合于实现这些功能,可是对于那些其他的、对时间要求相对宽松的任务,就应该推后到中断被激活以后再去运行。

      这样,整个中断处理流程就被分为两个部分,或叫两半。第一部分是中断处理程序(上半部),内核通过对它的异步执行完成对硬件中断的即时相应。

 

下半部

      下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作。在理想情况下,最好是中断处理程序将所有工作都交给下半部执行,因为我们希望给在中断处理程序中完成的工作越少越好,我们期望中断处理程序能够尽快地返回。

       但是,中断处理程序注定要完成一部分工作。例如:中断处理程序机会都需要通过操作硬件对中断的到达进行确认,有时它还会从硬件拷贝数据。因为这些工作对时间非常敏感,所以只能靠中断处理程序自己去完成。

       剩下的几乎所有其他工作都是下半部执行的目标。例如:如果你在上半部中把数据从硬件拷贝到了内容,那么当然应该在下半部中处理他们。遗憾的是,并不存在严格明确的规定来说明到底什么任务应该在哪个部分中完成--如何做决定完全取决于驱动程序开发者自己的判断。尽管在理论上不存在什么错误,但轻率的实现效果往往不很理想。中断处理程序会异步执行,并且在最好的情况下它也会锁定当前的中断线程。因此将中断处理程序持续执行的时间缩短到最小程度显然非常重要。对于上半部和下半部之间划分工作,尽管不存在某种严格的规则,但还是有一些提示可以借鉴:

  • 如果一个任务对时间非常敏感,将其放在中断处理程序中执行。
  • 如果一个任务和硬件相关,将其放在中断处理程序中执行。
  • 如果一个任务要保证不被其他中断(特别是相同的中断)打断,将其放在中断处理程序中执行。
  • 其他所有任务,考虑放置在下半部执行。

       和上半部只能通过中断程序实现不同,下半部可以通过多种机制实现:工作队列、软中断、tasklet。

 

软中断

        软中断是执行中断指令产生的,而硬中断是由外设引发的。软中断使用的比较少,而tasklet是下半部更常用的一种形式,tasklet是通过软中断实现的。软中断是在编译期间静态分配的,他不能向tasklet那样能被动态的注册或注销。

       目前只有两个子系统直接使用软中断网络和SCSI.

 

tasklet

        tasklet是利用软中断实现的一种下半部机制。选择到底用软中断还是tasklet其实很简单:通常应该用tasklet,它与软中断本质上很相似,行为表现也相近,但是接口更简单,锁保护也要求低。

 

工作队列

       工作队列(work queue)是另外一种将工作退后执行的形式,它和我们前面讨论的形式不同。工作队列把工作推后,交给一个内核线程去执行---这个下半部分总是会在进程上下文中执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的是工作队列允许重新调度和睡眠。

       通常在工作队列和软中断/tasklet中做出选择很容易,如果要推后执行的任务需要睡眠,那么就选择工作队列。如果推后执行的任务不需要睡眠,那么就选择软中断或tasklet。

        如果需要用一个可以重新调度的实体来执行下半部处理,应该选择使用工作队列,他是唯一能在进程上下文中运行的下半部机制,也只有它可以睡眠,这意味着需要获得大量内存是、需要获取信号量时、需要执行阻塞I/O操作时,它会非常有用。

 

下半部机制的选择

      各种不同的下半部实现机制之间做出选择是很重要的。一般的驱动程序开发者需要做出两个选择,首先是你虚部一个可调度的实体来执行推后的工作或者说需要休眠吗?要是有,工作队列就是唯一选择,否则就是用tasklet。如果专注性能提高就考虑软中断。

 

 

 

 

 

 

  • 大小: 307.5 KB
  • 大小: 261.5 KB
  • 大小: 187.6 KB
  • 大小: 138.9 KB
分享到:
评论

相关推荐

    Linux中断处理.ppt

    在Linux中,中断处理分为两种类型:快中断和慢中断。快中断通常处理简单的、时间短暂的事件,它们在关闭中断的状态下迅速执行,以减少系统开销。而慢中断则涉及更复杂的任务,可能需要较长时间,因此在处理过程中会...

    linux下中断处理程序示例,含驱动和应用程序

    总的来说,这个示例涵盖了从驱动开发到应用程序的完整中断处理流程,是学习Linux中断系统和驱动开发的宝贵资源。通过分析和实践这些代码,开发者可以深入理解中断处理的原理,提高在Linux环境下的系统级编程能力。

    Linux中断响应机制

    Linux中断响应机制是操作系统核心的重要组成部分,它负责处理硬件设备发送的中断请求,确保系统能够及时、有效地响应外部事件。本文将深入解析Linux中断响应机制的原理和流程。 早期的中断响应机制简单直接,CPU...

    ARM Linux中断源码分析(2)——中断处理流程

    ### ARM Linux中断源码分析(2)——中断处理流程 #### 一、中断与异常概述 在ARM架构的Linux系统中,对中断处理的理解是非常重要的。本文将详细解析ARM Linux中断处理流程,从异常向量表出发,深入探讨中断处理的...

    linux中断.rar

    本文将详细讲解Linux中断的基本概念、类型、处理流程以及在ARM架构中的实现。 首先,中断是硬件向CPU发送的一个信号,表明发生了需要操作系统介入的事件,比如设备数据传输完成或外部事件发生。中断分为硬件中断和...

    Linux中断处理体系结构分析1

    中断控制器是Linux中断处理机制中的一个关键组件,负责接收和处理来自硬件的中断请求。中断控制器可以是专门的硬件设备,也可以是软件模拟的。常见的中断控制器有8259A芯片、APIC(Advanced Programmable Interrupt ...

    linux中断子系统

    Linux中断子系统是Linux操作系统中负责处理中断请求的核心部分。在嵌入式系统中,中断被用来响应外部或内部事件,例如硬件设备需要CPU的注意时发出的信号。中断系统需要高效地管理这些中断请求,确保系统能够快速...

    Linux中断介绍

    本知识点将围绕Linux中断系统中的中断控制器PIC和APIC以及Linux中断实现进行深入解析。 ### PIC(Programmable Interrupt Controller)可编程中断控制器 PIC是较早出现的中断控制器设计,它支持在8086/88和286微...

    Linux中断处理说明

    ### Linux中断处理详解 #### 基本概念与分类 中断是计算机系统中一个关键的概念,它是由硬件信号触发的事件,能够在程序执行的任意时刻发生。根据其特性,中断可以分为可屏蔽中断和不可屏蔽中断。可屏蔽中断可以...

    linux中断学习小结

    通过以上分析,我们可以看到Linux中断处理机制的核心在于高效地响应和处理外部事件。了解这些基础概念和技术细节对于深入理解Linux内核的工作原理至关重要。此外,编写实际的中断处理程序还需要考虑更多的细节,如...

    中断详细介绍(linux中断)

    在计算机系统中,中断分为硬件中断和软件中断。硬件中断是由外部设备(如键盘、鼠标、网络接口卡等)产生的,用于通知CPU设备状态的变化或需要服务。例如,当键盘被按下,键盘控制器会产生一个中断,CPU接收到后停止...

    arm linux中断处理过程分析

    这一系列流程确保了ARM Linux系统能够有效地响应和处理外部中断,维持系统的稳定性和实时响应能力。对于嵌入式开发者和系统工程师而言,深入理解这一过程对于优化系统性能和调试中断相关的软件问题至关重要。

    ARM LINUX中断机制分析

    通过对 `irq_desc` 和 `irq_chip` 数据结构的分析,我们可以深入了解ARM Linux中断机制的工作原理。这些数据结构不仅提供了对中断线的描述和管理,还定义了对硬件的具体操作方式。了解这些基础概念对于理解和调试...

    基于ARM Linux的中断、异常的处理分析

    本文通过详细探讨ARM架构下Linux 2.6内核中的中断和异常处理机制,不仅介绍了中断的基本概念、硬件机制,还深入分析了Linux 2.6内核如何初始化中断向量表并处理中断和异常的过程。这对于理解ARM平台上的嵌入式系统...

    linux内核中断处理流程

    把内核中断的流程说的很清楚,学习Linux的必备资料

    Linux中断与异常编程技术 - 副本.doc

    Linux简单中断与异常编程技术

    Linux中断解析,Linux中断解析

    本章将向读者依次解释中断概念,解析Linux中的中断实现机理以及Linux下中断如何被使用。作为实例我们第一将向《i386体系结构》一章中打造的系统加入一个时钟中断;第二将为大家注解RTC中断,希望通过这两个实例可以...

    Linux中断处理驱动程序编写

    `irqflags`可以指定中断的触发方式和处理方式;`dev_id`用于标识设备,在共享中断时有用。 - **释放中断**:使用`free_irq()`函数。 ```c void free_irq(unsigned int irq, void *dev_id); ``` 2. **中断的使...

Global site tag (gtag.js) - Google Analytics