为什么在初始化PIC(8259)时将ICW 1分配给端口0x20,将其他ICWS分配给端口0x21?

时间:2019-08-16 08:02:40

标签: x86 kernel pic osdev

我正在编写一个键盘设备驱动程序。将PIC ICW1配置为端口0x20,将其他ICWS配置为端口0x21,但我不明白为什么我们有两个端口以及它们如何连接到8259芯片上的引脚? >

我已经阅读了手册,但仍然无法理解它与x86处理器上的端口的确切连接方式。

outb(0x20, 0x11);       /* send ICW1 */
outb(0xA0, 0x11);

/* send ICW2 */
outb(0x20 + 1, pic1);   /* remap */
outb(0xA0 + 1, pic2);   /*  pics */

/* send ICW3 */
outb(0x20 + 1, 4);  /* IRQ2 -> connection to slave */
outb(0xA0 + 1, 2);

/* send ICW4 */
outb(0x20 + 1, 0x01);
outb(0xA0 + 1, 0x01);

1 个答案:

答案 0 :(得分:3)

inout一起使用的端口号位于地址总线中,构成该总线的线已连接到设备。
设备未连接到端口,而是端口是发送到所有设备的号码。
在配置良好的系统中,只有单个设备会对放置在地址总线上的给定编号(端口)做出反应。
当然,这是总线模型的简化视图,从功能的角度来看,这就是PC / XT和ISA总线的工作方式。


8259A的CS引脚必须为低电平才能激活芯片。通过一些逻辑门,仅当地址总线具有一定范围的值时,才可以使该引脚有效。
例如,为了简短起见,假设地址总线为8位宽,如果将地址线A7-A4进行AND运算以形成CS,则8259A将响应范围0xf0-0xff。
简而言之,从计算CS的函数的输入中排除一些地址线,即可创建8259A响应的地址范围。
特别是,排除从A0到An的行,会形成一个连续的大小为2 n 的范围,该范围的起始地址清除了较低的 n 位。

8259A只有两个寄存器,因此我们需要一个大小为2的范围,或者等效地 n 等于1。
因此,A7-A1用于计算CS。请注意,某些架构可能具有 aliasing ,IIRC在ISA总线扩展期间也存在。
如果地址线可以由CPU驱动,但它既未连接到计算CS的块,也未连接到设备,则会发生混淆。

未用于CS的地址线必须用于选择设备内部的寄存器(如果未全部使用,则会发生别名)。
由于8259A只有两个寄存器,因此我们希望在这两个寄存器中选择一个引脚。
实际上,这就是A0引脚的作用:

  

A0地址线:此引脚与CS,WR和   RD引脚。 8259A使用它来解密各种命令字   CPU写入和CPU希望读取的状态。通常是   连接到CPU A0地址线(用于8086、8088的A1)。

通过使A7-A1线仅在其值(二进制)0010_000时将CS驱动为高电平,并且通过将CPU A0线连接到A0引脚,我们使8259A响应地址0x20和0x21。

            ____
----A7----O|    \             _________
----A7----O|     \           |         | 
----A6----O|      )-----CS---|         |
   ...     |     /           |         |
----A1----O|____/            |  8259A  |
                             |         |
----D7------------------D7---|         |
    ...                      |         |
----D0------------------D0---|         |
                             |         |
----A0------------------A0---|_________|

为什么ICW1变为0x20,而其他ICW变为0x21

好吧,正确的答案是:因为数据表也是如此。
我的解释是0x21端口用于读/写屏蔽寄存器,因为所有8位都用于8259A的8条IRQ线,因此可写到该端口的所有256个可能值已经有些含义了。
端口0x21后面的逻辑无法确定写入的字节是ICW还是OCW,因此端口0x21无法用于发送ICW1。

要触发ICW1,位4必须为1。这意味着,每当写入端口0x20时位4为1,8259A都会检测到ICW1并进入初始化序列。
由于ICW2和ICW3(对于主机)需要8个位的所有 (包括第4位),因此无法将其发送到端口0x20。
因此ICW2和ICW3必须转到端口0x21。
最后,ICW4也使用了D4,但可以重新设计为不使用它,但是由于前两个ICW使用的是端口0x21,所以它也用于ICW4。

会有所不同吗?当然是。也许有一个命令寄存器和一个数据寄存器(以及掩码寄存器访问权限),但显然在当时该解决方案更易于实现。
它具有较少的端口来解码,并且可能具有较短的DFA以处理设备状态(不过我没有检查)。


我不知道为什么对于8086/8系统,是将地址线A1连接到引脚A0。

相关问题