从实模式切换到保护模式时,为什么需要禁用中断?

6
我在许多操作系统(以及某些引导程序)中看到它们在从实模式切换到保护模式之前都会禁用中断(cli)。为什么我们需要这样做?
1个回答

8
BIOS使用PIT中断(IRQ0)来跟踪时间。一旦进入保护模式,实模式的中断处理就不再有效;处于保护模式的CPU需要保护模式IDT(中断描述符表)。进入保护模式时,IDTR(IDT寄存器)中的IDT限制被设置为0(任何中断号都会使CPU生成异常),因此只要PIT(或其他任何东西)产生中断,CPU就会生成一个异常,并触发另一个异常,从而引发#DF(双重错误),因此也会引发#TF(三重错误)。
同样,在保护模式下发生的IRQ0将触发#DE(除法异常)ISR(中断服务例程),因为在保护模式下,中断向量从0到31都保留给异常使用。
因此,发生的事情(最有可能的,因为除了PIT之外,还可能发生其他中断)的顺序如下(注意:这假定PIT中断将首先触发,但正如我之前所说,它实质上可以是任何中断,每个中断都会导致#DF和三重错误):
  1. 在CR0中设置PE位。
  2. PIT中断发生,PIC(可编程中断控制器)在其引脚#0上接收信号。
  3. PIC重新映射未设置,因此它在CPU上触发IRQ0。
  4. IRQ0(=#DE)尝试执行中断处理程序,但IDT的限制为0,因此生成(IIRC)#GP(通用保护错误)。
  5. IDT的限制为0,因此会生成#DF。
  6. IDT的限制为0,因此会生成#TF。
  7. CPU要么停止,要么重新启动。

IRQ0不会触发#DE - 它将触发#DF,因为默认情况下PIC的IRQ0被BIOS映射到INT 8。 - Ruslan
@Ruslan 听起来完全是武断的。任何BIOS都可以按自己想要的方式重新映射它。而且这在这里并不是完全相关的 - 除了#DF或#TF之外的任何向量都会触发#DF,#DF将触发#TF,而#TF,嗯...将直接跳到7。顺便问一下,哪个BIOS重新映射到那个特定的向量?有任何参考资料吗,还是只是通过实验找到的值? - Griwes
1
这在最初的IBM PC上是如此,并且为了兼容所有PC兼容系统而保持不变。例如,请参见此参考资料。您找到的任何其他参考资料,例如Ralf Brown的中断列表或其他任何内容,都会告诉您同样的事情。如果IDT正确设置,#DF将与向量8相同。 - Ruslan
@Ruslan:好的,看起来不错,尽管我相信有一些BIOS实际上确实会将IRQ重新映射到其他中断向量 - 就像许多BIOS供应商从未特别担心那些愚蠢的兼容性问题一样:P - Griwes
这就解释了为什么需要禁用中断,但并不解释为什么需要使用“cli”指令。《80386程序员参考手册》(https://archive.org/details/bitsavers_intel80386ammersReferenceManual1986_27457025)说:“80386的初始状态会禁用中断;[...]”,这也是我在Bochs中观察EFLAGS寄存器时所能观察到的。(该手册还解释了为什么需要禁用中断。) - user247702

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接