设置8259A芯片只需要按照上一节的说明向相应的端口写入ICW即可,具体实现如代码清单2-9所示。
1 movb $0x11,%al
2 outb%al,$0x20
3 .word 0x00eb,0x00eb
4 outb%al,$0xA0
5 .word 0x00eb,0x00eb
6 movb $0x20,%al
7 outb%al,$0x21
8 .word 0x00eb,0x00eb
9 movb $0x28,%al
10 outb%al,$0xA1
11 .word 0x00eb,0x00eb
12 movb $0x04,%al
13 outb%al,$0x21
14 .word 0x00eb,0x00eb
15 movb $0x02,%al
16 outb%al,$0xA1
17
18 .word 0x00eb,0x00eb
19 movb $0x01,%al
20 outb%al,$0x21
21 .word 0x00eb,0x00eb
22 outb%al,$0xA1
23 .word 0x00eb,0x00eb
24 movb $0xff,%al
25 outb%al,$0x21
26 .word 0x00eb,0x00eb
27 outb%al,$0xA1
整个初始化的过程分为4步。
1)往端口20h(主片)或A0h(从片)写入ICW1。
2)往端口21h(主片)或A1h(从片)写入ICW2。
3)往端口21h(主片)或A1h(从片)写入ICW3。
4)往端口21h(主片)或A1h(从片)写入ICW4。
以上步骤顺序不能错乱,必须按顺序进行设置。
上述代码的第1~5行,向端口20h(主片)和A0h(从片)写入0x11,结合ICW1的定义,可以知道这是将ICW1的第0位和第4位设置为1,其余位是0。ICW1的取值表示中断向量是8字节,并且是级联的8259A芯片,同时需要设置ICW4。0x00eb是向前跳转0条指令,这么做的原因是I/O指令要通过总线与中断控制器通信,所需要时间比较长,CPU需要进行延时等待。
第6~11行设置主片和从片的端口对应的中断向量号,将IRQ0的中断号设置为0x20,即第32号中断,将从片上的IRQ8的中断号设置为0x28,设置完以后,主片的IRQ0~IRQ7就对应中断向量0x20~0x27,从片的IRQ8~IRQ15对应中断向量0x28~0x2f。
第12~17行设置ICW3,根据定义,这代表主片的IRQ2连接从片。第18~22行设置ICW4,规定了EOI的方式为手动结束。第24~27行,向端口0x21和0xA1写入OCW1(值为0xff,写成二进制,即11111111b)就可以屏蔽所有外部中断。