X86 为什么在初始化PIC(8259)时,我们将ICW 1指定给端口0x20,而将其他ICW指定给端口0x21?

X86 为什么在初始化PIC(8259)时,我们将ICW 1指定给端口0x20,而将其他ICW指定给端口0x21?,x86,kernel,pic,osdev,X86,Kernel,Pic,Osdev,我正在编写一个键盘设备驱动程序。在配置PIC ICW1时,将其提供给端口0x20,将其他ICW提供给端口0x21,但我不明白为什么我们有两个端口,以及它们如何连接到8259芯片上的引脚 我已经阅读了手册,但仍然无法理解它是如何准确连接到x86处理器上的端口的 outb(0x20, 0x11); /* send ICW1 */ outb(0xA0, 0x11); /* send ICW2 */ outb(0x20 + 1, pic1); /* remap */ outb(0xA0

我正在编写一个键盘设备驱动程序。在配置PIC ICW1时,将其提供给端口0x20,将其他ICW提供给端口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);

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


8259A的CS引脚必须为低电平才能激活芯片。通过一位逻辑门,只有当地址总线有一个值范围时,才能断言该引脚。
例如,为了简短起见,假设地址总线为8位宽,如果地址线A7-A4被和在一起形成CS,则8259A将响应范围0xf0-0xff。
简单地说,从计算CS的函数的输入中排除一些地址行将创建8259A响应的地址范围。
特别地,排除从A0到An的行使得大小为2n的连续范围,其中起始地址的n位被清除

8259A只有两个寄存器,因此我们需要一个大小为2的范围,或者相当于n等于1。
因此,A7-A1被用来计算CS。请注意,某些体系结构可能存在别名,IIRC这在ISA总线扩展期间也存在。
如果一条地址线可以由CPU驱动,但既没有连接到计算CS的块,也没有连接到设备,则会发生别名

不用于CS的地址行必须用于选择设备内部的寄存器(如果不是全部使用,则会出现别名)。
由于8259A只有两个寄存器,我们希望在这两个寄存器之间选择一个引脚。
事实上,A0引脚就是这样做的:

A0地址线:该引脚与CS、WR和 RD引脚。8259A使用它来破译各种命令字 CPU写入和CPU希望读取的状态。这是典型的 连接到CPU A0地址线(A1用于8086、8088)

通过使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。

在PC的IO地址空间中为每个传统PIC(8259A)保留了2个IO端口。一个是comand端口,另一个是数据端口。8259A的A0线连接到PC的地址总线,该总线在被寻址的端口之间切换。