现在我们要添加外中断咯,首先要写各外中断的处理程序,我们想在外中断发生时显示相应的外中断号,那么在处理程序中要把相应的中断号压入栈中,这里像内中断一样统一进入一个函数把中断号显示出来,这个函数用C来写吧,这个函数调用了Disp_Color_Str和Disp_Int。接下来我们想开启键盘中断,在Init_8259A进行相应的设置,然后在IDT中填充相应的门描述符,最后在kernel中开中断sti,整个过程就完成了。
各外中断处理程序:
HW_Int_00:
push 0;
call IRQ_Handler
add esp,4
hlt
HW_Int_01:
push 1;
call IRQ_Handler
add esp,4
hlt
HW_Int_02:
push 2;
call IRQ_Handler
add esp,4
hlt
HW_Int_03:
push 3;
call IRQ_Handler
add esp,4
hlt
HW_Int_04:
push 4;
call IRQ_Handler
add esp,4
hlt
HW_Int_05:
push 5;
call IRQ_Handler
add esp,4
hlt
HW_Int_06:
push 6;
call IRQ_Handler
add esp,4
hlt
HW_Int_07:
push 7;
call IRQ_Handler
add esp,4
hlt
HW_Int_08:
push 8;
call IRQ_Handler
add esp,4
hlt
HW_Int_09:
push 9;
call IRQ_Handler
add esp,4
hlt
HW_Int_10:
push 10;
call IRQ_Handler
add esp,4
hlt
HW_Int_11:
push 11;
call IRQ_Handler
add esp,4
hlt
HW_Int_12:
push 12;
call IRQ_Handler
add esp,4
hlt
HW_Int_13:
push 13;
call IRQ_Handler
add esp,4
hlt
HW_Int_14:
push 14;
call IRQ_Handler
add esp,4
hlt
HW_Int_15:
push 15;
call IRQ_Handler
add esp,4
hlt
统一的处理程序IRQ_Handler:
- void IRQ_Handler(u32 irq_no)
- {
- Disp_Color_Str("IRQ_NO:",0xd);
- Disp_Int(irq_no);
- Disp_Color_Str("/n",0xd);
- }
在8259A中不要屏蔽键盘中断:
- Out_Byte(0x21,0xfd);
在Init_IDT中填充外中断的门描述符:
- Fill_Gate(0x20,HW_Int_00,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x21,HW_Int_01,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x22,HW_Int_02,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x23,HW_Int_03,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x24,HW_Int_04,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x25,HW_Int_05,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x26,HW_Int_06,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x27,HW_Int_07,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x28,HW_Int_08,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x29,HW_Int_09,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2a,HW_Int_10,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2b,HW_Int_11,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2c,HW_Int_12,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2d,HW_Int_13,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2e,HW_Int_14,DA_386IGate,PRIVILEGE_KRNL);
- Fill_Gate(0x2f,HW_Int_15,DA_386IGate,PRIVILEGE_KRNL);
相应的函数的声明之类的略去了,整个源代码也懒得贴了。
我们可以看到,汇编全都写在一个源文件里,C也全部写在一个源文件里,而且一写常量都硬编码,这样有诸多的不便。下次就开始整理这堆代码,按照功能分成不同的文件和不同的目录,这样看上去会清爽很多,便于管理。
最后附上敲入任意一个键的图: