【第6章】模仿MINIX的中断处理【三】
来源:互联网 发布:java log4j 输出级别 编辑:程序博客网 时间:2024/06/05 19:42
在MINIX中,中断处理程序是用宏来定义的,那么我们就来学习一下他的做法:
extern IRQ_Table
...
%macro HW_INT_MASTER 1
call Save
mov al,20h
out 20h,al
in al,21h
or al,(1 << %1)
out 21h,al
sti
mov eax,0dh
push eax
push Int_Msg
call Disp_Color_Str
add esp,8
call [IRQ_Table + (%1 * 4)]
cli
in al,21h
and al,~(1 << %1)
out 21h,al
ret
%endmacro
%macro HW_INT_SLAVE 1
push %1;
call IRQ_Handler
add esp,4
hlt
%endmacro
HW_Int_00:
HW_INT_MASTER 0
HW_Int_01:
HW_INT_MASTER 1
HW_Int_02:
HW_INT_MASTER 2
HW_Int_03:
HW_INT_MASTER 3
HW_Int_04:
HW_INT_MASTER 4
HW_Int_05:
HW_INT_MASTER 5
HW_Int_06:
HW_INT_MASTER 6
HW_Int_07:
HW_INT_MASTER 7
HW_Int_08:
HW_INT_SLAVE 8
HW_Int_09:
HW_INT_SLAVE 9
HW_Int_10:
HW_INT_SLAVE 10
HW_Int_11:
HW_INT_SLAVE 11
HW_Int_12:
HW_INT_SLAVE 12
HW_Int_13:
HW_INT_SLAVE 13
HW_Int_14:
HW_INT_SLAVE 14
HW_Int_15:
HW_INT_SLAVE 15
我们看到,多了一个IRQ_Table,这是函数指针数组,用来放置外中断的处理函数指针,它的类型是IRQ_Handler,在type.h中声明:
- typedef void (*IRQ_Handler)(u32);
IRQ_Table分别在global.h和global.c中声明和定义:
- extern IRQ_Handler IRQ_Table[]; /* in global.h */
- IRQ_Handler IRQ_Table[IRQ_NUM]; /* in global.c */
IRQ_NUM在protect.h中定义:
- #define IRQ_NUM 16
那么接下来就来填充IRQ_Table,除了时钟中断外都填充为IRQ_Handler函数指针,哦,该死,发现重名了,那么把函数名改成Spurious_IRQ吧,此函数在i8259.c中:
- void Spurious_IRQ(u32 irq_no)
- {
- Disp_Color_Str("IRQ_NO:",0xd);
- Disp_Int(irq_no);
- Disp_Color_Str("/n",0xd);
- }
相应的,在proto.h中也得改改:
- void Spurious_IRQ(u32 irq_no);
又发现了一个BUG,即Spurious_IRQ和Clock_Handler函数的类型不同,那么就把Clock_Handler改为:
- void Clock_Handler(u32 irq_no)
- {
- if(Is_Reenter != 0)
- {
- Disp_Color_Str("!",0xe);
- return;
- }
- p_Resume_PCB++;
- if(p_Resume_PCB >= PCB_Tables + 2)
- {
- p_Resume_PCB = PCB_Tables;
- }
- }
同样别忘了在proto.h中修改一下:
- void Clock_Handler(u32 irq_no);
下面就来填充这个数组吧,在Init_8259A函数中填充吧,先都填充为Spurious_IRQ,等会再填充特定的入口函数:
- int i;
- for(i = 0 ; i < IRQ_NUM ; i++)
- {
- IRQ_Table[i] = Spurious_IRQ;
- }
需要包含一些头文件:
- #include "protect.h"
- #include "proc.h"
- #include "global.h"
别忘了在HW_INT_SLAVE宏中把IRQ_Handler改为Spurious_IRQ,同时把extern IRQ_Handler改为Spurious_IRQ。
接下来是完成在IRQ_Table中填充特定的入口函数的功能了,先在i8259.c中写成一个函数:
- void Put_IRQ_Handler(u32 irq_no,IRQ_Handler handler)
- {
- Disable_IRQ(irq_no);
- IRQ_Table[irq_no] = handler;
- }
Disable_IRQ和等会要写的Enable_IRQ是用汇编来写的,放在kliba.asm中,目的是屏蔽和激活一个指定的中断:
global Disable_IRQ
global Enable_IRQ
...
;Disable_IRQ==========================================================
Disable_IRQ:
push ebp
mov ebp,esp
push eax
push ecx
pushf
mov ecx,[ebp + 8]
cli
mov ah,1
rol ah,cl
cmp cl,8
jae disable_8
disable_0:
in al,21h
test al,ah
jnz dis_already
or al,ah
out 0a0h,al
popf
pop ecx
pop eax
pop ebp
ret
disable_8:
in al,0a1h
test al,ah
jnz dis_already
or al,ah
out 0a1h,al
popf
pop ecx
pop eax
pop ebp
ret
dis_already:
popf
pop ecx
pop eax
pop ebp
ret
;end of Disable_IRQ===================================================
;Enable_IRQ===========================================================
Enable_IRQ:
push ebp
mov ebp,esp
push eax
push ecx
pushf
mov ecx,[ebp + 8]
cli
mov ah,1
not ah
rol ah,cl
cmp cl,8
jae enable_8
enable_0:
in al,21h
and al,ah
out 21h,al
popf
pop ecx
pop eax
pop ebp
ret
enable_8:
in al,0a1h
and al,ah
out 21h,al
popf
pop ecx
pop eax
pop ebp
ret
;end of Enable_IRQ====================================================
别忘了在proto.h添加相关函数的声明:
- void Put_IRQ_Handler(u32 irq_no,IRQ_Handler handler);
- void Disable_IRQ(u32 irq_no);
- void Enable(u32 irq_no);
最后在第一个进程开始执行前用Put_IRQ_Handler初始化一下,就在Init_PCB中初始化吧:
- Put_IRQ_Handler(0,Clock_Handler);
- Enable_IRQ(0);
既然在这里已经激活了时钟中断,那么在Init_8259A函数中就应该屏蔽所有中断:
Out_Byte(0x21,0xff);
OK,到此为止所有的代码都已经修改添加完毕,编译运行,画面依然如故,但是我们的程序已经有了良好的扩展性,虽然还很幼稚,很多东西如进程优先级,进程间调度等都没有考虑到。虽然看起来很简单,但要想一口气从头写到尾,还是不太可能的。今天到此为止,休息,休息。
- 【第6章】模仿MINIX的中断处理【三】
- 【第6章】模仿MINIX的中断处理【一】
- 【第6章】模仿MINIX的中断处理【二】
- 《自己动手写操作系统第六章》引入minix中断处理方式
- 第6章 中断与中断处理
- 第6章:中断和中断处理程序--学习笔记
- 【第6章】丰富中断处理程序
- 处理不可中断的阻塞(java并发编程第7章)
- 第6天 分割编译与中断处理
- 第9章 设置ISR(中断处理函数)
- LDD3读书笔记(第7章 中断处理)
- 深入剖析Linux中断机制之三---Linux对异常和中断的处理
- 中断详解(三)——中断和异常的硬件处理
- 中断子系统(6)中断嵌套的处理
- Minix下的汇编
- Minix --Linux的起源
- Minix进程的退出
- 第12课第4.2节 字符设备驱动程序之中断方式的按键驱动_Linux中断处理结构
- 在定位中追寻成功
- 运行在浏览器上的操作系统
- 实用程序工具包(用户自制的头文件)
- 第二届C++技术大会@ 上海 - 我觉得可以去看看
- 为gridview“删除”列添加确认对话框
- 【第6章】模仿MINIX的中断处理【三】
- 提醒变成初学者注意到问题
- 几分伤感,些许惆怅
- 学习
- Java Web基础:第七讲 Servlet运行原理
- 学习Java,C等程序开发的十大诀窍
- Java Web基础:第八讲 Java Web的发展历史
- 11.9
- 线性表(2)