rust-os.08 硬件中断(Hardware Interrupts)
Contents
在本文中,我们将设置可编程中断控制器,以将硬件中断正确转发到CPU。 为了处理这些中断,我们将新条目添加到中断描述符表中,就像我们对异常处理程序所做的一样。 我们将学习如何获取定期的计时器中断以及如何从键盘获取输入。
总览
中断提供了一种从连接的硬件设备通知CPU的方法。
因此,键盘不必通知内核定期检查键盘上是否有新字符(称为轮询的过程),而是可以将每次按键通知内核。
因为内核仅在发生某些事情时才采取行动,所以效率更高。
它还可以缩短响应时间,因为内核不仅可以在下一次轮询时立即做出反应。
无法将所有硬件设备直接连接到CPU。
而是由一个单独的中断控制器汇总来自所有设备的中断,然后通知CPU:
大多数中断控制器是可编程的,这意味着它们支持不同的中断优先级。
例如,这可以使计时器中断比键盘中断具有更高的优先级,以确保准确计时。
与异常不同,硬件中断是异步发生的。
这意味着它们与执行的代码完全独立,并且可以随时发生。
因此,我们的内核突然有了一种并发形式,其中包含所有潜在的与并发相关的错误。
Rust严格的所有权模型在这里为我们提供了帮助,因为它禁止了可变的全局状态。
但是,仍然有可能出现死锁,正如我们将在本文后面看到的那样。
The 8259 PIC
英特尔8259是1976年推出的可编程中断控制器(PIC)。长期以来,它已被较新的APIC取代,但由于向后兼容的原因,当前系统仍支持其接口。
8259 PIC的建立比APIC容易得多,因此在以后的文章中切换到APIC之前,我们将使用它来引入中断。
8259有8条中断线和几条用于与CPU通讯的线。
当时的典型系统配备了8259 PIC的两个实例,一个实例与一个实例PIC连接到实例之一的中断线:
该图显示了中断线的典型分配。
我们看到15条线中的大多数都有固定的映射,例如
辅助PIC的第4行分配给了鼠标。
每个控制器可以通过两个I / O端口,一个“命令”端口和一个“数据”端口进行配置。
对于主控制器,这些端口是0x20(命令)和0x21(数据)。
对于辅助控制器,它们是0xa0(命令)和0xa1(数据)。
有关如何配置PIC的更多信息,请参见osdev.org上的文章。
ip:instruction pointer 指令指针
sp:stack pointer 栈指针
ss:stack segment 栈段寄存器
cs:code segment 代码段寄存器
硬件中断处理理解
notify_end_of_interrupt方法只向中断控制器(interrupt controller)发出信号,表明我们已经处理完中断,以便它在可能发送的下一次请求。但是,中断在CPU上默认保持禁用状态,直到中断处理程序返回。因此,即使中断控制器在中断调用的notify_end_of_interrupt之后立即引发中断,在处理程序返回之前CPU也不会开始处理它。 在自定义的idt上添加一个键盘中断的中断处理函数:
|
|
Author sorvik
LastMod 2020-03-03