三、8259A的编程
8259A常常称之为PIC(可编程中断控制器),因此,在使用的时候我们必须通过编程对它进行初始化,需要完成的工作是指定主片与从片怎样相连,怎样工作,怎样分配中断号。在实模式下,也就是计算机加电或重启时,这是由BIOS自动完成的,然而当转到保护模式下后,我们却不得不对它进行编程重新设定,这都是由该死的IBM与Intel为维护兼容性而搞出来的麻烦:(。
在BIOS初始化PIC的时候,IRQ0~IRQ7被分配了0x8~0xF的中断号,然而当CPU转到保护模式下工作的时候,0x8~0xF的中断号却被CPU用来处理错误!一点不奇怪,CPU是Intel生产的,而计算机却是由IBM生产的,两家公司没有协调好:(。
因此,我们不得不在保护模式下,重新对PIC进行编程,主要的目的就是重新分配中断号。幸好这不是一件太难的工作。
对8259A的编程是通过向其相应的端口发送一系列的ICW(初始化命令字)完成的。总共需要发送四个ICW,它们都分别有自己独特的格式,而且必须按次序发送,并且必须发送到相应的端口,下面我们先来看看第一个ICW1的结构:
ICW1:发送到0x20(主片)及0xa0(从片)端口
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 1 | M | 0 | C | I |
I位:若置位,表示ICW4会被发送。(ICW4等下解释)
C位:若清零,表示工作在级联环境下。
M位:指出中断请求的电平触发模式,在PC机中,它应当被置零,表示采用“边沿触发模式”。
ICW2:发送到0x21(主片)及0xa1(从片)端口
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
A7 | A6 | A5 | A4 | A3 | 0 | 0 | 0 |
ICW2用来指示出IRQ0使用的中断号是什么,因为最后三位均是零,因此要求IRQ0的中断号必须是8的倍数,这又是一个很巧妙的设计。因为IRQ1的中断号就是IRQ0的中断号+1,IRQ2的中断号就是IRQ0的中断号+2,……,IRQ7的中断号就是IRQ0的中断号+7,刚好填满一个8个的中断向量号空间。
ICW3:发送到0x21(主片)及0xa1(从片)端口
ICW3只有在级联工作的时候才会被发送,它主要用来建立两个PIC之间的连接,对于主片与从片,它结构是不一样的。
(主片结构:)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
IRQ7 | IRQ6 | IRQ5 | IRQ4 | IRQ3 | IRQ2 | IRQ1 | IRQ0 |
上面,如果相应的位被置1,则相应的IRQ线就被用于与从片连接,若清零则表示被连接到外围设备。
(从片结构:)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | IRQ |
上面的IRQ位指出了是主片的哪一个IRQ连到了从片,这需要同主片上发送的上面的主片结构字一致。
ICW4:发送到0x21(主片)及0xa1(从片)端口
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | EOI | 80x86 |
80x86位:若置位则表示工作在80x86架构下。
EOI位:若置位则表示自动清除中断请求信号。在PC上这位需要被清零。要理解这一位,我们需要详细了解一下8259A的内部中断处理流程。