割り込みゲートディスクリプタの設置がうまくいっていないようです。
どこに誤りがあるのかわからないので教えてください。
プロテクトモードです。
参考:
0から作るos
How to use LIDT from inline assembly to load an interrupt vector table?
手順として
"割り込み"ゲートディスクリプタテーブルを0x00000000に設置。
ベクタ0x00だけ初期化します。
int 0x00にてソフトウエア割り込みを起こして
登録した割り込みハンドラが呼び出されるか見て
適切に設置されているかを確認する。
以下が作成したコードです。
ソフトウエア割り込み(0x00)を呼び出したとたんにVMがエラーで落ちるので
適切に割り込みゲートを設置できていないと思われます。
///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 1 // // typedef struct { unsigned short size; void * base; } __attribute__ ((packed)) IDTR; IDTR idtr; idtr.size = 128 * 8; idtr.base = 0x00000000; __asm__ ("lidt %0" :: "m"(*(&idtr))); // // // ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 2 // // int IDT_LOW; int IDT_HIGH; void (*p)() = Display_Rotation; int *GateAddress_Low = 0x00 * 8 + 0; int *GateAddress_High = 0x00 * 8 + 4; __asm__ __volatile__( "MOV %%DX,%%AX\n\t" "MOV %%EAX,%0\n\t" "MOV %2,%%DX\n\t" "MOV %%EDX,%1\n\t" :"=b" (IDT_LOW),"=c" (IDT_HIGH) :"i" ((short)(0x8000 + (0 << 13) + (0b110 << 8))),"a" ((0x08)<<16),"d" (p) ); *GateAddress_Low = IDT_LOW; *GateAddress_High = IDT_HIGH; // // // ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ __asm__("int $0x00\n\t");
1
LIDT命令でIDTRレジスタに読み込ませています。
[フォーマット](http://softwaretechnique.jp/OS_Development/Image/Kernel_Development02/IDTR.png
割り込みゲートディスクリプタのサイズは8バイト
それを128個配置するので 128 * 8。
IDT設置アドレスは0x00000000にしています。
2
割り込みテーブル ベクタ0x00のゲートディスクリプタをセットしています。
割り込みハンドラには Display_Rotation関数を登録します。
IDT_LOWに割り込みディスクリプタに格納する値の下位32bitを。
IDT_HIGHに割り込みディスクリプタに格納する値の上位32bitを
__asm__の処理で入れるようにしています(のつもり・・・)。
その後、
*GateAddress_Low = IDT_LOW;
*GateAddress_High = IDT_HIGH;
にて IDT ベクタ0x00の割り込みディスクリプタに対応するアドレスに
IDT_LOW IDT_HIGHを格納しています。
もしかしたら初歩的なミスをしているかもしれませんが・・・
どこのコードに誤りがあるのか分からないのでお願いします
アセンブリ出力結果(こっちでは都合上 LOOP関数を割り込みハンドラとして登録します。)
void loop(); void main_kernel(){ ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 1 // // typedef struct { unsigned short size; void * base; } __attribute__ ((packed)) IDTR; IDTR idtr; idtr.size = 128 * 8; idtr.base = 0x00000000; __asm__ ("lidt %0" :: "m"(*(&idtr))); // // // ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // 2 // // int IDT_LOW; int IDT_HIGH; void (*p)() = loop; int *GateAddress_Low = 0x00 * 8 + 0; int *GateAddress_High = 0x00 * 8 + 4; __asm__ __volatile__( "MOV %%DX,%%AX\n\t" "MOV %%EAX,%0\n\t" "MOV %2,%%DX\n\t" "MOV %%EDX,%1\n\t" :"=b" (IDT_LOW),"=c" (IDT_HIGH) :"c" ((short)(0x8000 + (0 << 13) + (0b110 << 8))),"a" ((0x08)<<16),"d" (p) ); *GateAddress_Low = IDT_LOW; *GateAddress_High = IDT_HIGH; // // // ///_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ __asm__("int $0x00\n\t"); } void loop(void){ for(;;){} }
pushl %ebx subl $32, %esp //スタック32バイト確保 movw $1024, -30(%ebp) //-30(ebp)に 構造体変数idtr.size = 128 * 8 movl $0, -28(%ebp) //-30(ebp)に 構造体変数idtr.base = 0 lidt -30(%ebp)
こちらがLIDT命令付近と思われる処理です。
/NO_APP movl $_loop, -8(%ebp) //-8(ebp) LOOP関数開始アドレス movl $0, -12(%ebp) //-12 = IDT_Address下位 0x0000000 (つまりセグメントディスクリプタ下位32bit) movl $4, -16(%ebp) // -16 = IDT_Address 上位 0x00000004 (つまりセグメントディスクリプタ上位32bit) movl $-31232, %ecx // ECX == ((short)(0x8000 + (0 << 13) + (0b110 << 8))) たぶん16BIT movl $524288, %eax // EAX == (0x08)<<16 movl -8(%ebp), %edx //EDX == LOOP関数開始アドレス /APP # 52 "project1.c" 1 MOV %DX,%AX //EAXの下位16BITにloop関数開始アドレス EAXの上位16BITにセグメントセレクタ MOV %EAX,%ebx //さきほどのEAXをEBXにコピー MOV %cx,%DX //EDX上位にlooP関数開始アドレス EDX下位に ((short)(0x8000 + (0 << 13) + (0b110 << 8)))←サイズ16bit MOV %EDX,%ecx //先ほどのEDXをECXにコピー # 0 "" 2 /NO_APP movl %ecx, %eax //さきほどEAXからEBXにコピーしたものをまたEAXにコピー movl %ebx, %edx //さきほどEDXからECXにコピーしたものをまたEDXにコピー movl %edx, -20(%ebp) //-20(EBP)に 合計32BIT [下位16BITにloop関数開始アドレス 上位16BITにセグメントセレクタ] を保存 movl %eax, -24(%ebp) //-24(EBP)に 合計32BIT [上位にlooP関数開始アドレス 下位に((short)(0x8000 + (0 << 13) + (0b110 << 8)))]を保存 movl -12(%ebp), %eax //35行目 IDT_Address下位 0x0000000 (つまりセグメントディスクリプタ下位32bit)をEAXにコピー movl -20(%ebp), %edx //[下位16BITにloop関数開始アドレス 上位16BITにセグメントセレクタ] をEDXに movl %edx, (%eax) movl -16(%ebp), %eax // 36行目 IDT_Address 上位 0x00000004 (つまりセグメントディスクリプタ上位32bit)をEAXにコピー movl -24(%ebp), %edx //[上位にlooP関数開始アドレス 下位に((short)(0x8000 + (0 << 13) + (0b110 << 8)))]をEDXにコピー movl %edx, (%eax)
こちらがゲート設置処理です。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。