设置中断描述符表
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, 0 xff ) ;
io_out8(PIC1_IMR, 0 xff ) ;
io_out8(PIC0_ICW1, 0 x11 ) ;
io_out8(PIC0_ICW2, 0 x20 ) ;
io_out8(PIC0_ICW3, 1 << 2 ) ;
io_out8(PIC0_ICW4, 0 x01 ) ;
io_out8(PIC1_ICW1, 0 x11 ) ;
io_out8(PIC1_ICW2, 0 x28 ) ;
io_out8(PIC1_ICW3, 2 ) ;
io_out8(PIC1_ICW4, 0 x01 ) ;
io_out8(PIC0_IMR, 0 xfb ) ;
io_out8(PIC1_IMR, 0 xff ) ;
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, 0 xf9) ;
_io_out8:
MOV EDX,[ESP+4 ]
MOV AL,[ESP+8 ]
OUT DX,AL
RET
运行结果