2

在我的系统编程课上,我们正在研究一个小型、简单的爱好操作系统。我个人一直在研究 ATA 硬盘驱动程序。我发现一行代码似乎会导致错误,然后立即重新启动系统。有问题的代码位于我的 IDE 中断中断服务程序的末尾。由于我使用的是 IDE 通道,因此它们是通过从 PIC(通过主 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 的功能有什么特别之处,这是一个问题?

我意识到如果没有看到代码,这可能无法回答,但感谢您的关注!

4

2 回答 2

3

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

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

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

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

于 2009-06-01T17:34:23.847 回答
1

当您重新启用 PIC 时,您是在设置 CPU 的中断标志还是清除它的情况下执行此操作(即,您是在操作码之后的某个时间CLI,还是在STI操作码之后的某个时间)?

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

因此,我希望直接导致故障的不是您的操作码:相反,故障是由于您重新启用 PIC 而发生的中断而运行的代码。

于 2009-05-20T04:11:26.110 回答