设置中断描述符表
struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *)0x0026f800;
int i;
for(i = 0; i < 256; i++){
set_gatedesc(idt + i, 0, 0, 0);
}
load_idtr(0x7ff, 0x0026f800);
set_gatedesc(idt + 0x21, (int)asm_inthandler21, 2 * 8, AR_INTGATE32);
设置PIC
void init_pic(void)
{
io_out8(PIC0_IMR, 0xff );
io_out8(PIC1_IMR, 0xff );
io_out8(PIC0_ICW1, 0x11 );
io_out8(PIC0_ICW2, 0x20 );
io_out8(PIC0_ICW3, 1 << 2);
io_out8(PIC0_ICW4, 0x01 );
io_out8(PIC1_ICW1, 0x11 );
io_out8(PIC1_ICW2, 0x28 );
io_out8(PIC1_ICW3, 2 );
io_out8(PIC1_ICW4, 0x01 );
io_out8(PIC0_IMR, 0xfb );
io_out8(PIC1_IMR, 0xff );
return;
}
中断处理函数
void inthandler21(int *esp)
{
struct BOOTINFO *binfo = (struct BOOTINFO*) ADR_BOOTINFO;
boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15);
putfont8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT21 (IRQ-1) : PS/2 keyboard");
for(;;){
io_hlt();
}
}
_asm_inthandler21:
PUSH ES
PUSH DS
PUSHAD
MOV EAX, ESP
PUSH EAX
MOV AX, SS
MOV DS, AX
MOV ES, AX
CALL _inthandler21
POP EAX
POPAD
POP DS
POP ES
IRETD
允许CPU中断
io_sti();
_io_sti: ; void io_sti(void);
STI
RET
开启键盘中断
io_out8(PIC0_IMR, 0xf9);
_io_out8:
MOV EDX,[ESP+4]
MOV AL,[ESP+8]
OUT DX,AL
RET
运行结果