"interrupt hooking" 是什么意思?
What does "interrupt hooking" mean?
我在阅读 PnP BIOS specification 时偶然发现了以下段落:
Actively monitor the INT 19h bootstrap vector
The current System BIOS
Architecture allows option ROMs to hook INT 19h indiscriminately. By
actively monitoring control of INT 19h, the System BIOS may regain
control of the Bootstrap process to ensure that the Operating System
is loaded from the proper device and in the proper manner.
第 3 行提到了 "hook" 中断的可能性。据我所知,这意味着监视中断的发出,例如在每个 ISR 中调用一个特殊的通知函数,让 OS 跟踪触发的中断。对吗?
这是什么意思?
当在实模式下触发中断时,CPU 将执行转移到该中断的处理程序,该处理程序在 Interrupt Vector Table 中指定。
在此上下文中挂钩中断意味着更改中断向量 Table 中条目 19h
处的地址以指向他们选择的另一个地址。然后,当触发中断 19h
时,它将从该地址开始执行自己的例程,这也可能在返回之前将控制权转移回原始 19h
中断处理程序。
假设中断处理程序位于 RAM 中,另一种挂钩方法是在中断处理程序中放置一个内联挂钩 19h
。也就是说,可以单独保留中断处理程序的地址,但用 jmp
(或 call
)替换处理程序中的指令之一到他们自己的例程。在这种情况下,尚不清楚他们是否也监视这种类型的挂钩。
编辑:浏览文档后,第一种挂钩方式似乎就是他们所说的。
... If the IPL device is known to the system BIOS, then
ensure that interrupt 19h is still controlled by the system BIOS. If not, recapture interrupt 19h and save the vector ...
... If the operating system fails to load and a previous ISA option ROM
had control of the interrupt 19h vector, then restore the interrupt 19h vector to the ISA option ROM and re-execute the Interrupt 19h bootstrap loader ...
因此,基本上在启动过程的特定部分,他们检查选项 ROM 是否修改了中断处理程序 19h
。如果它被修改,他们保存新处理程序的地址(他们可能会选择 运行 稍后)并将原始处理程序放回 IVT。
是的,"hooking" 意味着当中断触发时让您的代码 运行,然后在您的函数完成时跳转到您替换的处理程序。因此,您没有完全接管中断,而是将您的函数添加到处理程序链的头部。
将 IDT 想象成一个函数指针的全局数组。在 C 中,它会像:
extern void (*IDT[256])(void );
static void (*old_handler)(void);
void my_handler(void) {
// do stuff ..., then:
old_handler();
} // tail-call optimized to a jmp
void install_handler(int irq) {
old_handler = IDT[irq];
IDT[irq] = my_handler;
}
void uninstall_handler(int irq) { // Don't forget this part when you unload your code
IDT[irq] = old_handler;
}
这 compiles to 正是您用来挂接真实 IDT 的代码类型。
我在阅读 PnP BIOS specification 时偶然发现了以下段落:
Actively monitor the INT 19h bootstrap vector
The current System BIOS Architecture allows option ROMs to hook INT 19h indiscriminately. By actively monitoring control of INT 19h, the System BIOS may regain control of the Bootstrap process to ensure that the Operating System is loaded from the proper device and in the proper manner.
第 3 行提到了 "hook" 中断的可能性。据我所知,这意味着监视中断的发出,例如在每个 ISR 中调用一个特殊的通知函数,让 OS 跟踪触发的中断。对吗?
这是什么意思?
当在实模式下触发中断时,CPU 将执行转移到该中断的处理程序,该处理程序在 Interrupt Vector Table 中指定。
在此上下文中挂钩中断意味着更改中断向量 Table 中条目 19h
处的地址以指向他们选择的另一个地址。然后,当触发中断 19h
时,它将从该地址开始执行自己的例程,这也可能在返回之前将控制权转移回原始 19h
中断处理程序。
假设中断处理程序位于 RAM 中,另一种挂钩方法是在中断处理程序中放置一个内联挂钩 19h
。也就是说,可以单独保留中断处理程序的地址,但用 jmp
(或 call
)替换处理程序中的指令之一到他们自己的例程。在这种情况下,尚不清楚他们是否也监视这种类型的挂钩。
编辑:浏览文档后,第一种挂钩方式似乎就是他们所说的。
... If the IPL device is known to the system BIOS, then ensure that interrupt 19h is still controlled by the system BIOS. If not, recapture interrupt 19h and save the vector ...
... If the operating system fails to load and a previous ISA option ROM had control of the interrupt 19h vector, then restore the interrupt 19h vector to the ISA option ROM and re-execute the Interrupt 19h bootstrap loader ...
因此,基本上在启动过程的特定部分,他们检查选项 ROM 是否修改了中断处理程序 19h
。如果它被修改,他们保存新处理程序的地址(他们可能会选择 运行 稍后)并将原始处理程序放回 IVT。
是的,"hooking" 意味着当中断触发时让您的代码 运行,然后在您的函数完成时跳转到您替换的处理程序。因此,您没有完全接管中断,而是将您的函数添加到处理程序链的头部。
将 IDT 想象成一个函数指针的全局数组。在 C 中,它会像:
extern void (*IDT[256])(void );
static void (*old_handler)(void);
void my_handler(void) {
// do stuff ..., then:
old_handler();
} // tail-call optimized to a jmp
void install_handler(int irq) {
old_handler = IDT[irq];
IDT[irq] = my_handler;
}
void uninstall_handler(int irq) { // Don't forget this part when you unload your code
IDT[irq] = old_handler;
}
这 compiles to 正是您用来挂接真实 IDT 的代码类型。