我想通過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