LINUX 操作系统 第6章 中断和中断处理程序.ppt_第1页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第2页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第3页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第4页
LINUX 操作系统 第6章 中断和中断处理程序.ppt_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章中断和中断处理程序 2 6 1中断 陷阱和异常 中断 interrupt 设备发出的中断 此类中断的发生是无法预测的 它是被动的 用户空间和系统空间都可能发生中断 陷阱 trap 由软件产生的中断 它是由专设的指令 如X86的 intn 在程序中有意设置的 他是主动的 陷阱只发生在用户空间 异常 exception 由于违规操作产生的 如除法操作DIV的除数为0 多半是不小心 而不是故意的 也是被动的 系统调用 通过int0 x80实现 同 陷阱 3 中断 陷阱和异常 共同点 CPU对它们的响应过程基本一致 即 在执行完当前指令后 或者在执行当前指令的中途 就根据中断源所提供的 中断向量 在内存中找到相应的服务程序的入口地址 并调用该服务程序 中断 的向量是由软件或硬件设置好了的 陷阱的向量是在 自陷 指令中发出的 intn中的n 而各种异常的向量则是CPU的硬件结构中预先规定好的 因此 在实践中常常将它们作为统一的模式加以考虑和实现 而且常常统称为 中断 4 中断 中断使硬件得以与处理器进行通信 中断随时可能发生 因此内核随时可能因为新到来的中断而被打断 不同的设备对应的中断不同 每个中断都通过一个唯一的数字标识 从而使得操作系统能够对中断进行区分 这些中断值通常被称为中断请求 IRQ 线 通常IRQ都是一些数值量 5 6 2中断处理程序 在响应一个特定中断的时候 内核会执行一个函数 中断处理程序 或叫中断服务例程 一个设备的中断处理程序是它的设备驱动程序的一部分 中断处理程序与其他内核函数的真正区别 中断处理程序是被内核调用来响应中断的 它们运行于中断上下文中 6 中断随时可能发生 因此中断处理程序也就随时可能执行 所以必须保证中断处理程序能够快速执行 这样才能保证尽可能快地恢复中断代码的执行 因此 尽管对硬件而言 迅速对其中断进行服务非常重要 但对系统的其它部分而言 让中断处理程序在尽可能短的时间内完成运行也同样重要 7 上半部与下半部 对中断处理程序而言 既想它运行得快 又想它完成的工作量多 鉴于这两个目的之间的矛盾 一般把中断处理分为两个部分 上半部 中断处理程序 接收到一个中断 它就立即开始执行 但只做有严格时限的工作 这些工作都是在所有中断被禁止的情况下完成的 下半部 能够被允许稍后执行的工作推迟到下半部执行 下半部在开中断的情况下执行 8 上半部和下半部分开的例子 例 网卡接收数据包应在上半部完成的工作 应答硬件 拷贝最新的网络数据包到内存 读取网卡上更多的数据包 可以在下半部完成的工作 处理和操作数据包 9 6 3注册中断处理程序 中断处理程序是驱动程序的组成部分 驱动程序通过以下函数注册并激活一个中断处理程序 intrequest irq unsignedintirq irqreturn t handler int void structpt regs unsignedlongirqflags constchar devname void dev id 10 request irq 的参数 第1个参数irq 要分配的中断号 第2个参数handler 一个指针 指向处理这个中断的实际中断处理程序 第3个参数irqflags 可以为0 也可以是SA INTERRUPT SA SAMPLE RANDOM SA SHIRQ其中的一个或多个标志的位掩码 第4个参数devname 与中断相关的设备的ASCII文本表示法 第5个参数dev id 主要用于共享中断线 11 request irq 的返回值 若成功执行 返回0 如果返回非0值 表示有错误发生 在这种情况下 指定的中断处理程序不会被注册 注意 request irq 函数可能会睡眠 因此 不能在中断上下文或其它不允许阻塞的代码中调用该函数 12 使用request irq 函数 if request irq irqn my interrupt SA SHIRQ my device dev printk KERN ERR my device cannotregisterIRQ d n irqn return EIO 13 释放中断处理程序 卸载驱动程序时 需要注销相应的中断处理程序 并释放中断线 可以调用voidfree irq unsignedintirq void dev id 来释放中断线 如果指定的中断线不是共享的 那么 该函数删除处理程序的同时将禁用这条中断线 如果中断线是共享的 则仅删除dev id所对应的处理程序 而这条中断线本身只有在删除了最后一个处理程序时才会被禁用 14 6 4编写中断处理程序 典型的中断处理程序声明 staticirqreturn tintr handler intirq void dev id structpt regs regs 其返回值为irqreturn t型 实际上是int型 中断处理程序可能返回两个特殊的值 IRQ NONE 当中断处理程序检测到一个中断 但该中断对应的设备并不是在注册处理函数期间指定的产生源时 返回该值 IRQ HANDLED 当中断处理程序被正确调用 且确实是它所对应的设备产生了中断时 返回该值 15 在include linux interrupt h中有如下几行 定义了中断处理程序的返回值 typedefintirqreturn t defineIRQ NONE 0 defineIRQ HANDLED 1 defineIRQ RETVAL x x 0 16 典型中断处理程序的参数说明 irq 是这个处理程序要响应的中断的中断线号 现在 该参数已没有太大用处 dev id 一个通用指针 它与传递给request irq 的参数dev id必须一致 如果该值有唯一确定性 那么它就相当于一个cookie 可以用来区分共享同一中断处理程序的多个设备 regs 一个指向结构的指针 该结构包含处理中断之前处理器的寄存器和状态 除了调试 很少用到它 17 中断处理程序和重入 当一个给定的中断处理程序正在执行时 相应的中断线在所有处理器上都会被屏蔽掉 以防止在同一中断线上接收到另一个新的中断 因此 同一个中断处理程序绝对不会被同时调用以处理嵌套的中断 所以 Linux的中断处理程序是无需重入的 这极大地简化了中断处理程序的编写 18 6 4 1共享的中断处理程序 共享的处理程序与非共享的处理程序在注册和运行方式上比较相似 但差异主要有三点 request irq 的参数irqflags必须设置SA SHIRQ标志 对每个注册的中断处理程序来说 dev id参数必须唯一 指向任一设备结构的指针就可以满足这一要求 中断处理程序必须能够区分它的设备是否真的产生了中断 19 6 4 2中断处理程序实例 例 来自RTC real timeclock 驱动程序的一个实际的中断处理程序 它在drivers char rtc c中定义 在RTC驱动程序装载时 会调用rtc init 函数 进行初始化 在rtc init 函数中 将注册中断处理程序 代码见下页 20 其中的第2个参数是中断处理程序rtc interrupt 其代码见下页 if request irq rtc irq rtc interrupt SA INTERRUPT rtc void 21 中断处理程序rtc interrupt staticunsignedlongrtc irq data 0 irqreturn trtc interrupt intirq void dev id structpt regs regs spin lock 22 rtc interrupt 续 spin unlock 23 6 5中断上下文 当执行一个中断处理程序或下半部时 内核处于中断上下文中 中断上下文不能睡眠 因此不能从中断上下文中调用某些会睡眠的函数 24 6 6中断处理机制的实现 中断处理系统的实现依赖于体系结构 依赖于处理器 所使用的中断控制器的类型 体系结构的设计及机器本身 中断从硬件到内核的路由见下页图 25 中断从硬件到内核的路由 26 在内核中 中断的旅程开始于预定义入口点 对于每条中断线 处理器都会跳到对应的一个唯一位置 这样 内核就可以知道所接收中断的IRQ号了 然后 内核调用do IRQ 函数 27 do IRQ 函数 通过orig eax读出堆栈中的值 并将高位屏蔽掉 得到IRQ号 unsignedintdo IRQ structpt regs regs intirq regs orig eax 28 补充 pt regs结构 structpt regs longebx longecx longedx longesi longedi longebp longeax intxds intxes longorig eax longeip intxcs longeflags longesp intxss 29 do IRQ handle IRQ event inthandle IRQ event unsignedintirq structpt regs regs structirqaction action intstatus 1 intretval 0 if action flags 30 补充 irqaction数据结构 structirqaction irqreturn t handler int void structpt regs unsignedlongflags cpumask tmask constchar name void dev id structirqaction next intirq structproc dir entry dir 31 proc interrupts procfs是一个虚拟文件系统 它只存在于内核内存 一般安装于 proc目录下 proc interrupts文件 存放系统中与中断相关的统计信息 见下页 32 proc interrupts文件的内容 33 6 7中断控制 Linux内核提供了一组接口用于操作机器上的中断状态 这些接口为我们提供了能够禁止当前处理器的中断系统 或屏蔽掉整个机器的一条中断线的能力 34 6 7 1禁止和激活中断 用于禁止当前处理器上的本地中断 随后又激活它们的语句为 local irq disable 禁止中断 local irq enable 这两个函数通常以单个汇编指令实现 其代码在include asm i386 system h中 见下页 35 如果在调用local irq disable 之前已经禁止了中断 那么该例程往往会带来潜在的危险 同样local irq enable 也存在潜在危险 因此需要一种机制把中断恢复到以前的状态而不是简单地禁止或激活 definelocal irq disable asm volatile cli memory definelocal irq enable asm volatile sti memory 36 在禁止中断之前应该保存中断系统的状态 而在准备激活中断时 只需要把中断恢复到它们原来的状态 如下所示 unsignedlongflags local irq save flags local irq restore flags 对local irq save 的调用和对local irq restore 的调用必须在同一个函数中进行 37 6 7 2禁止指定中断线 在某些情况下 只禁止整个系统中一条特定的中断线就够了 这就是所谓的屏蔽掉一条中断线 Linux提供了四个接口 voiddisable irq unsignedintirq voiddisable irq nosync unsignedintirq voidenable irq unsignedintirq voidsynchronize irq unsignedintirq 38 6 7 3中断系统的状态 宏irqs disabled 如果本地处理器上的中断系统被禁止 则它返回非0 否则返回0 宏in interrupt 如果内核处于中断上下文中 返回非0 说明内核此时正在执行中断处理程序 或者正在执行下半部处理程序 宏in irq 只有在内核确实正在执行中断处理程序时才返回非0 39 6 8下半部简介 中断处理程序是内核中必不可少的 但本身存在一些局限 它以异步方式执行并且有可能会打断其他重要代码的执行 因此 应执行得

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论