装配OUTB功能如何导致三重故障?

时间:2009-05-20 03:24:29

标签: operating-system x86 interrupt hobby-os

在我的系统编程课程中,我们正在开发一个简单的小型操作系统。我个人一直在研究ATA硬盘驱动器。我发现一行代码似乎导致了一个错误,然后立即重新启动系统。有问题的代码是我的中断服务程序结束时的IDE中断。由于我使用的是IDE通道,它们通过从属PIC(通过主控级联)发送。最初我的代码只是将中断结束字节发送给从机,但后来我的教授告诉我,我也应该将它发送给主PIC。

这就是我的问题,当我取消注释将EOI字节发送到主PIC的线路时,系统会发生三重故障,然后重新启动。同样,如果我留下它评论系统仍在运行。

_outb( PIC_MASTER_CMD_PORT, PIC_EOI );  // this causes (or at least sets off) a triple fault reboot
_outb( PIC_SLAVE_CMD_PORT, PIC_EOI );

如果没有看到系统的其他部分,是否有人可以解释这里可能发生的事情?

注意:就像在黑暗中一样,我用另一个_outb()调用替换了_outb()调用,这只是确保为IDE控制器启用了中断,但是,生成的程序集几乎是相同的。这不会导致错误。

* _ outb()是x86 OUTB指令的包装器。

将EOI发送给主PIC的功能有什么特别之处?

我意识到没有看到代码这可能无法回答,但感谢您的期待!

2 个答案:

答案 0 :(得分:3)

三重故障通常指向堆栈溢出或奇数堆栈指针。当发生故障或中断时,系统会立即尝试将更多垃圾压入堆栈(在调用故障处理程序之前)。如果堆栈被冲洗,这将导致另一个故障,然后尝试在堆栈上推送更多东西,这会导致另一个故障。此时,系统会放弃并重新启动。

我知道这一点,因为我实际上有一个愚蠢的专利(大约20年前在戴尔工作),在没有外部硬件的情况下导致CPU复位(过去通过键盘控制器完成):

   MOV ESP,1
   PUSH EAX    ; triple fault and reset!

OUTB指令本身不会导致故障。我的猜测是你正在重新启用一个中断,当你的堆栈出现问题时会触发中断。

答案 1 :(得分:1)

当你重新启用PIC时,你是在设置CPU的中断标志还是清除它(即你是在CLI操作码之后的某个时间执行它,还是在{{1}之后的某个时间执行它操作码)?

假设CPU的中断标志被使能,您重新启用PIC的行为允许任何挂起的中断到达CPU:这将中断您的代码,分派到IDT指定的向量等。

所以我希望不是你的操作码会直接导致错误:相反,错误是由于重新启用PIC而导致的中断运行的代码。