Operating system 为什么在从实模式切换到保护模式之前需要禁用中断?

Operating system 为什么在从实模式切换到保护模式之前需要禁用中断?,operating-system,x86,bootloader,osdev,real-mode,Operating System,X86,Bootloader,Osdev,Real Mode,我在许多操作系统(和一些引导加载程序)中看到,它们都在从实模式切换到保护模式之前禁用中断(cli)。为什么我们需要这样做?Bios使用PIT中断(IRQ0)来跟踪时间。一旦进入保护模式,实模式中断处理将不再有效;处于保护模式的CPU需要保护模式IDT(中断描述符表)。进入保护模式后,IDTR(IDT寄存器)中的IDT limit设置为0(任何中断号都会使CPU产生异常),因此一旦PIT(或任何其他)产生中断,CPU就会产生异常,从而产生另一个异常,触发#DF(双故障)和#TF(三故障) 此外,在

我在许多操作系统(和一些引导加载程序)中看到,它们都在从实模式切换到保护模式之前禁用中断(
cli
)。为什么我们需要这样做?

Bios使用PIT中断(IRQ0)来跟踪时间。一旦进入保护模式,实模式中断处理将不再有效;处于保护模式的CPU需要保护模式IDT(中断描述符表)。进入保护模式后,IDTR(IDT寄存器)中的IDT limit设置为0(任何中断号都会使CPU产生异常),因此一旦PIT(或任何其他)产生中断,CPU就会产生异常,从而产生另一个异常,触发#DF(双故障)和#TF(三故障)

此外,在保护模式下发生的IRQ0将触发#DE(除异常)ISR(中断服务例程),因为0到31之间的中断向量是为保护模式下的异常保留的

因此,事件发生的顺序(最有可能的情况是,PIT以外的其他中断也可能发生)如下所示(注意:这假设PIT中断将首先触发,但正如我前面所说,它基本上可以是任何中断,每个中断都将导致#DF和三重故障):

  • PE位设置在CR0中
  • PIT中断发生时,PIC(可编程中断控制器)在其引脚0上获取信号
  • PIC重新映射未设置,因此会在CPU上触发IRQ0
  • IRQ0(#DE)尝试执行中断处理程序,但IDT的限制为0,因此生成(IIRC)#GP(一般保护故障)
  • IDT的限制为0,因此生成#DF
  • IDT的限制为0,因此生成#TF
  • CPU停止或重新启动

  • IRQ0不会触发#DE-它会触发#DF,因为默认情况下PIC的IRQ0被BIOS映射到INT 8。@听起来完全是任意的。任何BIOS都可以以任何方式重新映射它。此外,它在这里也不是完全相关的-除了#DF或#TF之外的任何向量都将触发#DF,#DF将触发#TF,以及#TF,嗯。。。直接跳到7。顺便说一句,什么BIOS重新映射到那个特定的向量?有没有任何参考资料,或者只是通过实验发现的一个值?在最初的IBM PC中是这样的,在所有兼容PC的系统中仍然是这样。见例。您找到的任何其他参考资料,例如拉尔夫·布朗的中断列表或任何东西,都会告诉您同样的情况。而#DF将在IDT设置正确的情况下保持平衡-因为向量8表示#DF。@Ruslan:好的,看起来不错,虽然我很确定有一些BIOS确实将IRQ重新映射到其他中断向量,但并不是很多BIOS供应商都特别担心这种愚蠢的兼容性问题:p这解释了为什么需要禁用中断,而不是为什么需要
    cli
    指令。表示“80386的初始状态使中断处于禁用状态;[…]”,这就是我可以在使用Bochs的EFLAGS寄存器中观察到的。(手册还解释了为什么需要禁用中断。)