[自制操作系统] 第11回 认识中断

目录
一、前景回顾
二、初识中断
三、中断分类
四、中断号
五、可编程中断控制器8259A
六、中断描述符表IDT

 

一、前景回顾

  上一回我们简单地讲解了特权级的原理,这一块其实我当时也是啃的云里雾里,看了好大一会儿才明白。如果实在不怎么理解特权级检查也没关系,因为后面的代码中也不会涉及到手写特权级检查,这些都是CPU自己来完成。总之只需要对特权级检查有概念即可。本回我们来讲讲比较重要的中断。

二、初识中断

  我们知道,整个操作系统其实是处于一个死循环的,为什么这么说呢?因为CPU总是不知疲倦的取指令,译指令,执行指令。如果我们不让操作系统处于死循环的情况下,CPU就可能会将指令后面的数据给解码为某个指令来执行,这样就会导致CPU出现异常,所以为了避免这种情况出现,我们通过类似下面的代码形式:

while (1){
  操作系统代码
}

  让操作系统永远死循环在这里。在我们前面的代码中,如果仔细看的话会发现有jmp $的出现,它的目的也是让CPU执行到这里就一直死循环。那么每当有新的事件出现时,再去“通知”CPU跳转执行,执行完毕后如果没有新的事件便让CPU再次死循环。这里的“通知”就是中断所起的作用,每当有新的事件出现,便以中断的方式来通知操作系统,所以可见在操作系统中,中断的作用可以说是举足轻重的。

三、中断分类

  我们已经知道,中断便是发生了某类事件需要通知CPU处理的一种行为,所以只要有事件发生就应该让CPU知道。中断按照事件来源分类,来自CPU外部的中断就称为外部中断,来自CPU内部的中断被称为内部中断,还可以更加细分,具体看下图。

  

四、中断号

  中断机制的本质就是来了一个中断信号后,调用相应的中断处理程序,不管CPU有多少种类型的中断,为了方便管理,将来自外部设备和内部指令的各种中断类型统统归于一种管理方式,即为每一个中断信号分配一个整数,用此数来作为中断的ID,也就是所谓的中断向量,用此中断向量在中断描述符表中索引得到对应表项,再从中得到中断处理程序。中断向量表如下。

  

  表中的Error code字段中,如果值为Y,表示相应的中断处理过程会由CPU压入错误码,这个在我们后面编写中断代码时会再次提到。

五、可编程中断控制器8259A

  上一节我们说到,每一个中断信号都对应一个中断向量,CPU根据中断向量来查表执行中断函数。中断分为外部中断和内部中断,内部中断的中断信号在CPU内部即可传递。那么针对外部设备的中断,中断向量是如何传递给CPU的呢?

  为了让CPU获得每一个外部设备的中断信号,最好的方式自然是在CPU中为每一个外设准备一个引脚接收中断,但这是不现实的,因为外部设备的数量理论上是没有上限的,CPU准备再多引脚都没用,而且这种方式显得很傻。再加上我们前面说过,CPU有自己的专属任务,便是不停地取指令,译指令,执行指令。其他事不应该再去劳烦它,于是有了8259A的出现。

  8259A的作用是负责所有来自外设的中断,8259A用于管理和控制可屏蔽中断,它表现在屏蔽外设中断,对它们实行优先级判决,向CPU提供中断向量号等功能。下图是工作示意图。

  

  外部设备与8259A连接,由8259A来负责接收它们的中断请求,再将他们的中断信号传递给CPU。这里只需要有一个全局的概念即可,

六、中断描述符表IDT

  前面提到中断描述符表,中断描述符表其实是保护模式下用于存储中断处理程序入口的表。当CPU接收到一个中断后,用此中断的中断向量在IDT中索引对应的描述符,在该描述符中找到中断处理程序的入口地址,然后执行该函数。中断描述符其实就是被称为门的描述符。关于门,就是我们在上一回特权级讲解一章提到的门结构:调用门、中断门、陷阱门和任务门(忘记的朋友可以点这里)。不过我们最终只使用中断门,这里再来看一下中断门的结构。

  

  中断描述符表的地址被存放在IDTR寄存器中,IDTR寄存器的结构如下:

  

  16位的表界限,表达的最大范围是0xffff,即64KB,可容纳的描述符个数是64KB/8B=8K=8192个,但是呢处理器只支持256个中断,即0~255。

七、中断处理过程

  中断处理过程如下图所示:

  

  其中涉及到的特权级检查:DPL_GATE >= CPL > DPL_CODE。由于中断是由中断向量号通知到处理器的,中断向量号只是一个整数,并没有RPL,所以在由中断引起的特权级转移做特权级检查中,并不涉及到RPL。

  本回到此结束了,预知后事如何,请看下回分解。

posted @ 2022-07-02 16:45  李知行  阅读(333)  评论(0编辑  收藏  举报