第12章 中断嵌套问题、IOPL问题

问题:在80386中,中断是否可以嵌套?

在80386中有两种事件(可以参考我写的《中断与异常》文档):

  1. 中断事件(异步 interrupts)(一般是硬件中断)
  2. 异常事件(同步 exceptions)

在IDT中,有三种门描述符(通过设置,可以让中断向量对应不同的门描述符。比如缺页异常可以对应interrupt gate,也可以对应trap gate):

  1. Interrupt gate
  2. Trap gate
  3. Task gate

我们只是用interrupt gate和trap gate。它们之间有一个很重要的区别。

Interrupt gate ISR :

  1. 保存EFLAGS
  2. 清除EFLAGS上的IF、TF、VM、RF、NT标志位
  3. 恢复EFLAGS

Trap gate ISR:

  1. 保存EFLAGS
  2. 清除EFLAGS上的TF、VM、RF、NT标志位
  3. 恢复EFLAGS

我们为时钟中断设置的是interrupt gate,因此当发生时钟中断时,在调用时钟中断处理函数do_timer()时,IF位是置0的, 也就是被关中断的。这样,就不会发生中断嵌套。假如在do_timer中使用sti指令开中断,则可能会发生中断嵌套。因为时钟中断是PIC1上的IRQ0,因此在do_timer()函数中需要手动清除IRQ0的MASK位,使用outport(M_PIC,EIO)

问题:IOPL是什么?

在保护模式中,对I/O的控制权限也做了限制。用户进程如果不被允许是无法进行I/O操作的。这种限制有两种方法实现,它们就是IOPL和I/O许可位图。 IOPL是I/O保护机制中的关键之一,它位于EFLAGS寄存器的第12、13位。指令in、ins、out、outs、cli、sti只有在CPL<= IOPL时才能执行。这些指令被称为I/O敏感指令,如果特权级低的指令视图访问这些I/O敏感指令将会导致常规保护错误(#GP)。可以改变IOPL的指令只有popfl和iret指令,但只有运行在特权级0的程序才能将其改变。

Leave a Reply

Your email address will not be published. Required fields are marked *