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
@Zack - 良い点 – Stewart