本文参考:中断控制器8259A(详细) ,《操作系统真相还原》《x86汇编从实模式到保护模式》
说明:本文涉及硬件知识,非重点内容,对应代码也只有几行且逻辑简单。不感兴趣的朋友可以跳过本节。

概述

中断详解一文中我们了解到,外中断是通过 INTR (interrupt) 和 NMI (Non Maskable Interrupt) 这两根信号线来通知 CPU 的:
img

CPU 通过与芯片引脚相连的 INTR 信号线来接收外部设备发送的中断。如果所有外部设备都同时直接与 INTR 信号线相连,那么,当多个设备同时发生信号,CPU 该先处理哪个信号呢?而那些本次没被选中的信号又该存放在哪呢?总不能直接丢弃吧?为了解决这些问题,8259A 可编程中断控制器粉墨登场。可编程中断控制器(Programmable Interrupt Controller,PIC),其任务相当于 CPU 的外部中断代理,负责维护中断队列仲裁中断优先级

IDT 能够存放 256 个中断,而一个 8259a 芯片只能管理 8 个中断(8个 IRQ 接口)。为了支持更多外部设备,需要将多个 8259A 芯片进行级联,最多支持 9 个芯片级联,即 64 个外部中断。为什么 9 个芯片只能支持 64 个外部中断呢?不应该是 8*9=72 个吗?这是因为级联时,其中一个芯片被设置为主片(master),其余被设置为从片(slave),来自从片的中断信号必须先传递给主片,再由主片传递给 CPU。而每级联一个从片,就需要占用主片一个 IQR 接口,从片则有专门的接口。两级级联图示如下:

工作流程

8259a内部结构

  • 中断请求寄存器IRR: 保存 8 个外界中断请求信号的请求状态( IR0~IR7 );
  • 中断服务寄存器ISR: 保存 8 个正在被 8259A 服务着的中断状态;
  • 中断屏蔽寄存器IMR: 保存 8 个对中断请求信号IR的屏蔽状态;
  • 优先级比较器PR: 用以比较正在处理的中断和刚刚进入的中断请求之间的优先级别,以决定是否产生多重中断或中断嵌套 。

以上寄存器都是 8 位,每一位代表一个接口,相当于接口的位图 。你可能会疑惑,8 位寄存器,怎么表示 IQR7 以上的接口呢?笔者是这样理解的:上图展示的是与 CPU 直接相连的主片,而从片中收到多个中断信号(IRQ8~IRQ15)后,也会进行排队和判别,优先级最高的再发往主片,因此,主片上的 IRQ2 接口就代表了 IRQ8~IRQ15 中的一个接口。

中断请求过程

  1. 外设发送信号,经过主板的信号通路后到达某个 IRQ 接口。

  2. 检查 IMR 寄存器中的位,若 IMR 中对应此 IRQ 接口的位被置 1,则表示该 IRQ 接口被屏蔽,丢弃该信号;反之则接收。

  3. 信号转入 IRR 寄存器,将对应位置 1,表示该中断信号等待被处理。IRR 相当于中断处理队列。

    优先级判断方式:IRQ 接口值越小,优先级越大

  4. 某个时刻,PR 从 IRR 中挑出优先级最高的中断,通过 INT 接口向 CPU 的 INTR 发送信号。

  5. CPU 收到信号后,立刻通过自身的 INTA 接口向主片回复一个中断响应信号,表示自己已做好准备;

  6. 主片收到响应信号后,立即在 ISR 寄存器中将相应位置 1,表示当前正在处理该中断,同时还要将 IRR 中相应位置 0。

  7. 接着,CPU 再次发送 INTA 信号给主片,目的是获取中断号。

  8. 8259A 将中断号发送给 CPU ,CPU 收到后执行相应中断程序。

  9. 如果 EOI(End Of Interrupt)被设置为手动模式,则中断处理程序末尾必须手动向 8259A 发送 EOI ;8259A 收到 EOI 后,将 ISR 中对应的位置 0 。如果 EOI(End Of Interrupt)被设置为自动模式,则主片收到 CPU 发的第二个信号后(寻求中断码),将 ISR 中对应位置 0。

值得一提的是,中断号=起始中断号+IRQ接口号 ,其中起始中断号由我们自己编程设置,因此可以将 IRQ 接口映射到不同的中断号。

8259A编程

文章作者: 极简
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 后端技术分享
自制操作系统
喜欢就支持一下吧