|

楼主 |
发表于 2004-6-12 08:53:28
|
显示全部楼层
嗯,查阅了一些资料。我就我的三个问题说说。(后两个问题基本解决)
8086的8259A可编程中断控制芯片有8级中断源,分别为IR0~IR7,可填写初始化命令字ICW2的高五位来决定它们各自的中断类型(低三位取决于中断请求从哪个IRx输入),它的端口地址为20H和21H(众所周知,x86架构的控制芯片都具有两个奇偶端口地址,对应不同的命令控制字以供初始化)。
IBM PC的惯例为
- [color=blue]中断源[/color] [color=blue]中断类型号[/color] [color=blue]中断功能[/color]
- IR0 08H 时钟定时器
- IR1 09H 键盘
- IR2 0AH 保留
- IR3 0BH 异步通信(COM2)
- IR4 0CH 异步通信(COM1)
- IR5 0DH 磁盘
- IR6 0EH 软盘
- IR7 0FH 并行打印机
复制代码
换言之,初始化ICW2命令字的指令为
- MOV AL,00001000B
- OUT 21H,AL
复制代码
从中我们可以看出一些有趣的东西,BIOS提供的中断服务程序INT n中,n的取值功能对应关系与上表一致(从这个角度来观察BIOS,它一点都不神秘,它只是一段ROM程序罢了)。比如说,INT 9是BIOS键盘中断,恰恰对应了8259A的IR1中断源(也就是我们所熟悉的IRQ1)。
进一步说,如果要把BIOS例程替换为自己编写的中断服务程序,只要在中断向量表上的相应位置做手脚即可。中断向量表以4个字节为1个表项,保存了中断服务程序的CS:IP,共有256个表项。那么,我们把相应中断源的表项换成我们自己编写的中断服务程序的CS:IP即可。
举个实例吧。
假如现在有一台字符打印机,我们用自己的中断服务程序来驱动它。
8255A是8086的并行接口控制器,工作在方式1时,可支持CPU以中断方式与外设通信。将8255的PC3连接到8259A的IR3端,后者的中断类型号为0BH,0BH*4=002C(中断矢量表的入口地址=中断类型号*4);我们编写的服务程序入口地址为3200:0100H(使用ORG指令即可实现这点)。这样使用以下代码即可实现替换:
- MOV AX,0
- MOV ES,AX
- MOV AX,0100H
- MOV ES:[002CH],AX
- MOV AX,3200H
- MOV ES:[002EH],AX
复制代码
另外,再扩展一下话题,Linux内核中关于APIC(高级可编程中断控制器)的代码体现了这些东西,可以参考一下。
ps:至于端口地址的获取,除了查阅手册,估计别无它计。对于x86架构,估计这些也是固定值,问题不大。 |
|