在linux1.0中的目录boot/setup.S中有一段初始化8259中断控制器的代码,代码如下:
! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
! we put them right after the intel-reserved hardware interrupts, at
! int 0x20-0x 2F . There they won't mess up anything. Sadly IBM really
! messed this up with the original PC, and they haven't been able to
! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x 0f ,
! which is used for the internal hardware interrupts as well. We just
! have to reprogram the 8259's, and it isn't fun.
需要说明的是主 8259A 的地址为0x20和0x21,从 8259A 的地址为0xa0和0xa1,只要向某一个 8259A 的第一个端口(0x20,0xa0)写入的命令的bit4为1,那么这个 8259A 就认为这是一个ICW1。OCW在初始化之后可以使用。
8259A 的初始化流程协议如下:
对于X86,bit0必须被设置成1。
注:在linux1.0中汇编语言还是用的intel格式:
端口操作指令:out 地址 值 in
mov al,#0x11 ! initialization sequence, ICW1=0x11
out #0x20,al ! send it to 8259A -1 ,将0x11写入0x20,也就是写入主中断控制器
call delay
out #0xA0,al ! and to 8259A -2,将0x11写入a0,也就是写入从中断控制器
call delay
mov al,#0x20 ! start of hardware int's (0x20),ICW2=020,中断向量的起始地址为0x20
out #0x21,al !送主控制器,要送奇地址
call delay
mov al,#0x28 !start of hardware int's 2 (0x28),从控制器的中断向量的起始地址为0X28
out #0xA1,al !送从控制器
call delay
mov al,#0x04 ! 8259-1 is master ,从 8259A 被挂在主 8259A 的IRQ2上
out #0x21,al !
call delay
mov al,#0x02 ! 8259-2 is slave,对于从8259来说ICW3=0x02,
out #0xA1,al !送从控制器
call delay
mov al,#0x01 ! 8086 mode for both,ICW4=0x01
out #0x21,al
call delay
out #0xA1,al
call delay
mov al,#0xFF ! mask off all interrupts for now,
out #0xA1,al
call delay
mov al,#0xFB ! mask all irq's but irq2 which
out #0x21,al ! is cascaded
而在linux 2.6.12 中arch/i386/boot/setup.S中,在确保所有的协处理器都被重启之后,在第800行来了一句# well, that went ok, I hope. Now we mask all interrupts - the rest is done in init_IRQ().
movb $0xFF, %al # mask all interrupts for now
outb %al, $0xA1
call delay
movb $0xFB, %al # mask all irq's but irq2 which
outb %al, $0x21 # is cascaded
也就是说中断可控制器的编程应该在init_IRQ()这个函数中。这个函数的位置在: