8章終了時にマウスが動いている仕組みがイメージできなかったので 5〜8章で割り込みついて書いてるところを自分なりにまとめました。
- PICの設定の初期化
- IDTの設定
- IDTに割り込みハンドラを登録する
- 割り込みの発生、割り込みハンドラの呼び出し
- 割り込みハンドラ(アセンブリ)内でC言語の関数を呼ぶ
- C言語から再びアセンブリ経由でPS2のデータポートを参照する
PICの設定の初期化
int.cのinit_pic
io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15は、INT28-2fで受ける */
- IRQ0~15をINT0x20~2fで受け取るように指定。
- 0x00~0x0fはcpuが予約しているセキュリティ的な割込がすでにあるためここを回避
IDTの設定
- 初期化、マウス0x2c、キーボード0x21の登録を行なっています。
- 0x27の登録は起動バグ対策のようです。(p126)*1
struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT;//補足:ADR_IDT=0x0026f800 /* IDTの初期化 */ for (i = 0; i <= LIMIT_IDT / 8; i++) { set_gatedesc(idt + i, 0, 0, 0); } load_idtr(LIMIT_IDT, ADR_IDT); /* IDTの設定 */ set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);//キーボード set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);//バグ対策 set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);//マスク
IDTに割り込みハンドラを登録する
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);
割り込みの発生、割り込みハンドラの呼び出し
割り込みが発生する。 INT XXの命令が発生しIDTに登録している該当の割り込みハンドラが呼ばれる
- PIC 12(マウス)の割り込みはもちろん設定した通りINT 0x2Cで受け取る
- 登録した以下の割り込みハンドラが呼ばれる
_asm_inthandler2c:
PUSH ES
PUSH DS
PUSHAD
MOV EAX,ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler2c
POP EAX
POPAD
POP DS
POP ES
IRETD
割り込みハンドラ(アセンブリ)内でC言語の関数を呼ぶ
CALL _inthandler2c
によりC言語で用意したinthandler2c
が呼ばれます。
void inthandler2c(int *esp) /* PS/2マウスからの割り込み */ { unsigned char data; io_out8(PIC1_OCW2, 0x64); /* IRQ-12受付完了をPIC1に通知 */ io_out8(PIC0_OCW2, 0x62); /* IRQ-02受付完了をPIC0に通知 */ data = io_in8(PORT_KEYDAT);//補足:PORT_KEYDAT=0x0060 fifo8_put(&mousefifo, data); return; }
C言語から再びアセンブリ経由でPS2のデータポートを参照する
io_in8(PORT_KEYDAT)
で60番ポートに届いたデータを取りに行きます
_io_in8: ; int io_in8(int port); MOV EDX,[ESP+4] ; port MOV EAX,0 IN AL,DX RET
こちらの0x60がPS2のデータポートと書かれています https://wiki.osdev.org/%228042%22_PS/2_Controller
The Data Port (IO Port 0x60) is used for reading data that was received from a PS/2 device or from the PS/2 controller itself, and writing data to a PS/2 device or to the PS/2 controller itself.
データポートが使えるようになれば、こちらに0xfa
が届きます。
そちらが確認できれば0xfa
は読み捨てて以後マウスからのデータを受信します。
マウスからのデータは3バイト1セット(1:クリック、2:横移動のデータ,3:縦移動のデータ)だと思うのですが、 マウスを動かしている際になぜか1バイト目が反応しているのが気になりました。
*1:これを登録しないと起動に失敗するらしい。