我想通过IDT处理内核中断。 我在Linux下使用Intel x86。x86:中断处理程序循环
我已经设置了我的IDT和我的中断条目,并且我启动了一些测试来查看我的中断处理程序。
当我尝试int $0x0
时,它完美地工作:我的处理程序被调用,但是当我尝试一些错误代码推入的异常时,我输入了一个无限循环。
架构如下:
当异常到达时,我的处理程序的第一部分是ASM和调用一个常见的C部分。
my_handler.c
void handler(int i)
{
printf("Exception %d caught\n", i);
}
my_handlers.S
common:
pushal
pushl %ds
pushl %es
pushl %fs
pushl %gs
addl $48, %esp // 4 4-bytes segments pushed
// + 8 4-bytes registers (pushal)
` // esp points on exception code
call handler // call the C handler with exception code
subl $48, %esp
popl %gs
popl %fs
popl %es
popl %ds
popal
addl $8, %esp // 4-byte error code + 4-byte exception number
iret
exception_de_handler:
pushl $0 // Fake error code
pushl $0 // interrupt number
jmp common
exception_gp_handler:
// error code is pushed by µproc.
pushl $13 // interrupt number
jmp common
exception_pf_handler:
// error code is pushed by µproc.
pushl $14 // interrupt number
jmp common
如果我尝试运行followig代码:
int* a = 0x0;
*a = 42;
它的工作原理,在exceution的*a = 42;
但如果我尝试:
int* a = 0x0;
*a = 42;
*a = 1337;
它进入无限循环:
Exception 14 caught
Exception 13 caught
Exception 13 caught
Exception 13 caught
Exception 13 caught
.....
Exception 13 caught
Exception 13 caught
Exception 13 caught
.....
为什么第一个例外页面错误(14)对一般保护(13)来处理,然后循环?
谢谢你的回答。
为什么在Linux下手动操作IDT?那不可能很好地结束。您应该使用Linux的设备驱动程序API来处理中断。 (另外我不确定你如何从内核模式调用'printf' - 我们可能需要更多解释你实际做了什么。) – zwol 2012-02-14 23:06:03
@Zack - 好点 – Stewart 2012-02-15 00:28:12