- 1、本文档共74页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
中断和异常 李春杰 为什么会有中断 主要内容 中断基础(ARM版) Linux内核中软件级中断处理及其数据结构 Linux的软中断、tasklet以及下半部分 中断和异常 中断(广义)会改变处理器执行指令的顺序,通常与CPU芯片内部或外部硬件电路产生的电信号相对应 中断——异步的:由硬件随机产生,在程序执行的任何时候可能出现 异常——同步的:在(特殊的或出错的)指令执行时由CPU控制单元产生(指令执行时产生,软中断SWI) 我们用“中断信号”来通称这两种类型的中断 中断信号的作用 中断信号提供了一种特殊的方式,使得CPU转去运行正常程序之外的代码 比如一个外设采集到一些数据,发出一个中断信号,CPU必须立刻响应这个信号,否则数据可能丢失 当一个中断信号到达时,CPU必须停止它当前正在做的事,并且切换到一个新的活动 为了做到这这一点, 在进程的内核态堆栈保存程序计数器的当前值(即eip和cs寄存器)以便处理完中断的时候能正确返回到中断点, 并把与中断信号相关的一个地址放入进程序计数器,从而进入中断的处理 中断信号的处理原则 快! 当内核正在做一些别的事情的时候,中断会随时到来。无辜的正在运行的代码被打断 中断处理程序在run的时候可能禁止了同级中断 中断处理程序对硬件操作,一般硬件对时间也是非常敏感的 内核的目标就是让中断尽可能快的处理完,尽其所能把更多的处理向后推迟 中断服务例程上半部分(top bottom)和下半部分(half bottom) 上半部会立即被内核执行(now主要讲) 下半部的执行可以被延迟,可以在系统不太繁忙时执行 允许不同类型中断的嵌套发生,这样能使更多的I/O设备处于忙状态 尽管内核在处理一个中断时可以接受一个新的中断,但在内核代码中还在存在一些临界区,在临界区中,中断必须被禁止 进程上下文和中断上下文 用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存器值、变量等。所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。 ? 硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。 进程上下文和中断上下文 当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下文。当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的上下文,以便在再次执行该进程时,能够必得到切换时的状态执行下去。 在LINUX中,当前进程上下文均保存在进程的任务数据结构中。在发生中断时,内核就在被中断进程的上下文中,在内核态下执行中断服务例程。但同时会保留所有需要用到的资源,以便中继服务结束时能恢复被中断进程的执行。 中断上下文 中断上下文不同于进程上下文 中断或异常处理程序执行的代码不是一个进程 它是一个内核控制路径,代表了中断发生时正在运行的进程执行 作为一个进程的内核控制路径,中断处理程序比一个进程要“轻”(中断上下文只包含了很有限的几个寄存器,建立和终止这个上下文所需要的时间很少) 中断上下文举例 分析A,B,C,D在互相抢占上的关系 假设: 2个interrupt context,记为A和B 2个process,记为C和D 1, 假设某个时刻C占用CPU运行,此时A中断发生,C被A抢占,A得以在CPU上执行。 由于Linux不为中断处理程序设置process context,A只能使用 C的kernel stack作为自己的运行栈 2 ,无论如何,Linux的interrupt context A绝对不会被某个进程C或者D抢占!! 这是由于所有已经启动的interrupt contexts,不管是interrupt contexts之间切换,还是在某个interrupt context中执行代码的过程,决不可能插入scheduler调度例程的调用。 除非interrupt context主动或者被动阻塞进入睡眠,唤起scheduler,但这是必须避免的,危险性见第3点说明。 3 ,关于第2点的解释:首先,interrupt context没有process context,A中断是“借”了C的进程上下文运行的,若允许A“阻塞”或“睡眠”,则C将被迫阻塞或睡眠,仅当A被“唤醒”C才被唤醒;而“唤醒”后,A将按照C在就绪队列中的顺序被调度。这既损害了A的利益也污染了C的kernel
文档评论(0)