【一文讲透计算机的“中断”】

author: 程序员小灰 (link

中断,英文名为Interrupt,计算机的世界里处处都有中断,任何工作都离不开中断,可以说整个计算机系统就是由中断来驱动的。那么什么是中断?简单来说就是CPU停下当前的工作任务,去处理其他事情,处理完后回来继续执行刚才的任务,这一过程便是中断。

本文旨在进一步揭开中断机制的面纱,理清中断的过程,就中断做出以下几个方面的介绍:中断分类,中断描述符表,中断控制器,和中断过程。详细的思维导图如下:

v2-65b73ec2d05152b79d83056c76294f53_1440w.webp


一、中断分类

v2-4b720a6f3f3027430d9417770d52e8aa_1440w.webp

1 外部中断

1、可屏蔽中断通过INTR线向CPU请求的中断,主要来自外部设备如硬盘,打印机,网卡等。此类中断并不会影响系统运行,可随时处理,甚至不处理,所以名为可屏蔽中断。

2、不可屏蔽中断: 通过NMI线向CPU请求的中断,如电源掉电,硬件线路故障等。这里不可屏蔽的意思不是不可以屏蔽,不建议屏蔽,而是问题太大,屏蔽不了,不能屏蔽的意思。

注:INTR和NMI都是CPU的引脚

2 内部中断(软中断,异常)

1、陷阱:是一种有意的,预先安排的异常事件,一般是在编写程序时故意设下的陷阱指令,而后执行到陷阱指令后,CPU将会调用特定程序进行相应的处理,处理结束后返回到陷阱指令的下一条指令。如系统调用,程序调试功能等。

尽管我们平时写程序时似乎并没有设下陷阱,那是因为平常所用的高级语言对底层的指令进行了太多层的抽象封装,已看不到底层的实现,但其实是存在的。例如printf函数,最底层的实现中会有一条int 0x80指令,这就是一条陷阱指令,使用0x80号中断进行系统调用。

2、故障:故障是在引起故障的指令被执行,但还没有执行结束时,CPU检测到的一类的意外事件。 出错时交由故障处理程序处理,如果能处理修正这个错误,就将控制返回到引起故障的指令即CPU重新执这条指令。如果不能处理就报错

常见的故障为缺页,当CPU引用的虚拟地址对应的物理页不存在时就会发生故障。缺页异常是能够修正的,有着专门的缺页处理程序,它会将缺失的物理页从磁盘中重新调进主存。而后再次执行引起故障的指令时便能够顺利执行了。

3、终止:执行指令的过程中发生了致命错误,不可修复,程序无法继续运行,只能终止,通常会是一些硬件的错误。 终止处理程序不会将控制返回给原程序,而是直接终止原程序

二、中断描述符表

中断描述符表类似全局描述附表,表内存放的描述符,与GDT不同的是IDT内可以存放4种描述符:任务门描述符,陷阱门描述符,调用门描述符,中断门描述符。

咱们在此只介绍中断门描述符,4种描述符除了任务门其他都类似,中断门也是最常用的,如Linux的系统调用就是使用中断门实现的。

1 中断描述符

v2-8320cc71d06242d72d90e3041a9bf14e_1440w.webp

中断描述符的结构如上,重要字段和属性为已标出,有个了解就好,不必深究各个位的具体含义。

2 中断向量号

在介绍中断向量号之前,我们先引入一个段选择子(segment selector)的概念。所谓段选择子,就是段寄存器的值,段选择子的高13位为全局描述符表的索引号,其他的位置是属性位,这就好比是数组下标索引数组元素。

至于中断向量号,作用等同于段选择子的高13位,用来在IDT中索引相对的中断描述符,但没有相应的类似段选择子的结构。

部分中断向量表,需要了解的部分如下图所示:

v2-6c9bd4b2b147362d09f2d0fd8eb24611_1440w.webp

3 中断描述符表寄存器IDTR

v2-c10c493b368eca0ad716b282f531ca96_1440w.webp

IDTR也类似于GDTR,存放的是48位数据信息,高32位是IDT的地址,低16位表示IDT的界限。

同GDTR,IDTR也有相应的加载指令:lidt m16&32,m是那48位数据信息,lidt指令将其加载到IDTR寄存器,使得CPU知道IDT在哪。

三、中断控制器

每个独立运行的外设都可以是一个中断源,能够向CPU发送中断请求,为了方便管理和减少引脚数目,设立了中断控制器,让所有的可屏蔽中断都通过INTR信号线与CPU进行交流。

中断控制器中较为流行的是Intel 8259A芯片,下面对8259A作简单介绍:

1 级联

单个8259A芯片只有8根中断请求信号线(IRQ0, IRQ1, … , IRQ7),这是不够用的,所以采用多个8259A芯片。将它们如下图一样像串联的方式组合起来,这种组合方式就叫做级联。

v2-c3b1a818575615e96187543ecd0784ec_1440w.webp

级联时只能有一个主片,其余的均为从片,最多可级联9个,即最多支持64个中断。为什么不是8 * 9 = 72个呢?从上图可以看出级联时后面的芯片会占用前面芯片的一个IRQ接口,而最后一个8259A没有其他人占用,所以8259A的个数和支持的中断数关系为7n + 1。

2 8259A的一些功寄存器和功能部件

1、IMR:Interrupt Mask Register,中断屏蔽寄存器,其中的每个位标志着一个外设,1表示屏蔽该外设,0表示中断允许。

2、IRR:Interrrupt Request Register,中断请求寄存器,请求中断的外设在IRR对应的位 值为1。当有多个中断请求时,IRR寄存器中多位将会置1,相当于维持了一个请求中断的队列。

3、ISR:In_Service Register,中断服务寄存器,正在进行处理的中断在ISR对应的位值为1。

4、PR:Priority Resolver,优先级裁决器,用于从IRR中挑选一个优先级最大的中断。(IRQ接口号小的优先级大)。

四、中断过程

v2-944b83143c579c2c1482e97ac4dde721_720w.webp

1 中断请求

1、 当外设发出中断信号后,信号被送入8259A;

2、 8259A检查IMR寄存器中是否屏蔽了来自该IRQ的信号,若IMR寄存器中对应的位为1,表示屏蔽了IRQ代表的中断,则丢掉此中断信号,若IMR寄存器中对应的位为0,表示未屏蔽此中断,则将IRR寄存器中与此中断对应的位 置1。

3、 PR优先级裁决器从IRR寄存器中挑选一个优先级最大的中断,然后8259A向CPU发送INTR信号。

2 中断响应

1、 CPU收到INTR信号后便知道有新的中断了,在执行完当前指令后,向8259A发送一个中断回复信号。

2、 8259A收到回复信号后,将选出来的优先级最大的中断在ISR寄存器中相应的位 置1,表示该中断正在处理,同时将此中断在IRR寄存器中相应的位 置0,相当于将此中断从中断请求队列中去掉。

3、 CPU再次向8259A发送INTR信号,表示想要获取中断向量号。

4、 8259A通过数据总线向CPU发送中断向量号,中断向量号 = 起始向量号 + IRQ接口号,一般起始向量号为32,从中断向量表可看出0—31已经被占用,后面的32—127是分配给可屏蔽中断的,所以此处外设的中断设置的起始向量号便为32。

3 保护现场——压栈

1、 CPU据中断向量号去IDT中获取中断描述符,取出选择子中的DPL与当前特权级CPL进行比较,若特权级发生变化,则需要切换栈。(不同特权级有着不同的栈,如Linux使用了0, 3特权级,则有两个栈,一个内核栈,一个用户栈)

2、 于是处理器临时保存当前的旧栈SS和ESP的值,从TSS(每一个任务有一个TSS结构,其中保存着不同特权级栈的SS和ESP值)中获取与DPL特权级同的栈信息加载到SS和ESP寄存器。再将旧栈SS和ESP的值压入新栈中。若没有特权级变化,则跳过此步骤。

v2-98c0f34fd64651a1af41c87a5ff67a95_720w.webp

3、 压入程序状态信息,即EFLAGS寄存器

v

4、压入断点,即返回地址,即当前任务的CS,EIP值。

v2-84cd4a71f5464fe132cfe38e60212a43_720w.webp

5、若该中断有错误码,压入错误码

v2-8e7a25061cfe2ad4132ec466154c7524_720w.webp

4 定位中断服务程序

直接先上流程图:

v2-7b31b68a276045a69e4b92e2be89e5b0_720w.webp

具体步骤如下:

1、 据中断向量号去IDT中索引中断描述符,具体操作:取出IDTR中的IDT地址,加上中断向量号 * 8,得到的地址指向所要的中断描述符。

2、 据中断描述符中的段选择子去GDT中索引段描述符,具体操作:取出GDTR中的GDT地址。加上段选择子高13位 * 8, 得到的地址为中断处理程序所在段的段基址。

3、 上一步得到的段基址加上段描述符中的段内偏移量得到的地址变为中断服务程序的地址。

5 中断处理过程

中断的实际处理过程就是执行中断处理程序,Linux将中断处理程序分为上下两部分,需要紧急处理立即执行的归为上半部,不那么紧急的归为下半部。

这便涉及到了开关中断的问题。开中断,即EFLAGS的IF位置1,表示允许响应中断;关中断,即EFLAGS的IF位置0,表示不允许响应中断。

1、 上半部分是刻不容缓的,需要立即执行的部分,所以要在关中断的状态下执行。

2、 而下半部分不那么紧急,在开中断的情况下进行,如果此时有新的中断发生,当前中断处理程序便会换下CPU,CPU会另寻时间重新调度,完成整个中断处理程序。

6 中断返回——出栈

中断返回就是出栈的过程,将第三步保护现场压入栈中的信息弹出。

1、 有错误码弹出错误码。

2、 此时的栈顶指针ESP应指向EIP_old,剩余栈中的信息使用iret指令弹出,CPU执行到iret指令时再次检查和比较特权级是否变化。

3、 弹出EIP_old, CS_old

4、 若特权级变化,将ESP_old, SS_old, 加载到ESP,SS寄存器。

至此,中断已返回,中断也已处理。

上述的中断过程是我根据资料照着自己的理解分为了6步,每步又有许多微操作,可能跟某些书籍资料等所划分的步骤不同,甚至一些微操作的顺序也不太一样,比如说中断处理时什么时候关中断,我查阅了许多资料和书籍,讲述得都有区别。

不同操作系统在中断方面的实现有所不同,但总体来说都会经历上述的步骤,可能细微之处略有差别,却也不影响我们了解中断的过程。

END

中断是操作系统重要的机制,没有中断,操作系统什么也干不了,没法输入没法输出,不能管理硬件资源,也不能向上层应用提供服务。而且操作系统本身就像是一个死循环,等待事件发生需求来临,然后为其提供服务解决问题。而这事件的发生与处理就是靠中断机制来控制的,所以说中断对于操作系统来说有着举足轻重的作用,而我们也有必要了解中断,理清中断的过程。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ESD(Electrostatic Discharge,静电放电)是一种瞬时放电现象,通常是由人体或设备上积累的静电电荷引起的。一般来说,ESD会导致电子设备损坏或误操作,因此必须采取措施来避免ESD。 在设计中,ESD保护应该开始于PCB的物理设计。一个好的物理设计将使ESD泄放的能量尽可能地均匀地分散到整个电路板上。这种物理设计包括有效的接地,涂覆和排列PCB层。同时,这也需要考虑到整个系统的电缆结构、机箱接地和隔离等因素,从而最大限度地提高整个系统的耐ESD能力。 此外,在设计电路时,还需要考虑到ESD保护措施。主要的保护措施包括使用可靠的ESD保护器件,如TVS器件、瞬变压抑器和热释电器件,以保护线路免受ESD的影响。此外,在设计输入、输出和供电接口时,还应该采用合适的线路过滤器和电容器,以进一步提高系统的ESD耐受性。 最后,测试是ESD保护设计的重要环节。ESD测试可以验证保护设计的有效性,并排除措施上的缺陷。通常,测试人员会使用标准ESD模拟器来模拟真实的ESD事件。在测试过程中,应注意对设备进行预处理,如去静电和适当的人体模拟。此外,还应该制定合适的检验标准以确保测试的准确性和可重复性。 总之,ESD保护设计至关重要,因为它能够保护电子设备免受静电放电的损害。为了实现可靠的ESD保护,这需要考虑物理设计和电路设计,以及有效的测试工具。最后,只有将所有这些因素合理结合,才能实现有效的ESD保护设计。 ### 回答2: ESD(Electrostatic Discharge,静电放电)指的是在两个带有不同电荷的物体接触或者靠近时,电荷之间发生放电的现象。这种放电可以对各种电子元器件和电路造成损害,从而影响设备的性能和寿命。 ESD的原理可以通过三种方式传递:空气中的放电、直接接触和电感耦合。在实际应用中,ESD对硅芯片、存储器、晶体管等电子元件的损害是非常严重的,这些元件的特性和结构容易受到ESD的影响。 为了防止ESD对电子元件和电路的损坏,需要在设计中采用一些专门的技术,比如在元器件和电路板上增加ESD保护电路、在设备外壳上增加处理工艺等。对于集成电路芯片而言,可以采用对基底和指的进行控制,以及在芯片电路设计过程中合理选择元器件和适当布局等。 总之,ESD保护是电子元器件和电路设计中非常重要的一环,需要采用针对性的技术来减缓和防止ESD对设备的影响,从而保证设备的长期稳定性和可靠性。 ### 回答3: ESD全程为静电放电,是由于静电在两者之间产生的高电压放电引起的电感和电容的相互作用。在现代电子系统中,由于设备的电路越来越小,因此更容易受到静电干扰,人们不得不在设计中考虑如何避免或降低这种静电干扰。本文将从ESD的原理出发,简要介绍如何在电路设计中考虑防止ESD干扰。 ESD的产生是由于静电的积累导致的高电压放电,因此防止ESD干扰的基本原则是减小静电的积累。在电路设计中,静电主要通过两个方面来进行干扰:一是直接放电干扰,即静电直接放电到电路中,导致电路损坏;二是间接放电干扰,即静电放电到设备的金属外壳等部位,导致电磁场干扰影响电路的正常工作。因此,在设计中,需要采用一些措施来减小这些干扰。 1. 选择合适的元器件:在元器件的选择上,要选择一些抗ESD干扰的元器件,如采用ESD保护二极管等,能够减小ESD对电路的影响。 2. 优化电路结构:在电路设计中,要优化电路结构,减少电路间的交叉干扰,避免电路产生高电位差,这样能够减少静电的积累和ESD的辐射。 3. 采用ESD保护电路:在设计电路时,引入一些ESD保护电路,能够有效地减小ESD对电路的影响。例如采用Zener二极管、TVS二极管等保护电路。 在总体设计中,需要综合以上措施,采用一些适合的方案来消除ESD对电路的干扰。同时,在实际使用中,也需要对电路进行定期维护和检测,保证电路的正常运行。在电子技术的快速发展中,ESD防护的问题只会越来越重要,只有对其进行深入的研究和应用,才能更好地保证电子设备的稳定运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值