【问题标题】:why do we give ICW 1 to port 0x20 but other ICWS to port 0x21 when initializing a PIC(8259)?为什么我们在初始化 PIC(8259) 时将 ICW 1 提供给端口 0x20 而将其他 ICWS 提供给端口 0x21?
【发布时间】:2019-08-16 08:02:40
【问题描述】:

我正在编写一个键盘设备驱动程序。虽然将 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);

【问题讨论】:

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

标签: x86 kernel pic osdev


【解决方案1】:

inout 一起使用的端口号放置在地址总线中,构成该总线的线路连接到设备。
设备不连接到端口,而是端口是发送到所有设备的数字。
在配置良好的系统中,只有单个设备对放置在地址总线上的给定编号(端口)做出反应。
当然,这是总线模型的简化视图,从功能的角度来看,它是 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。

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 2012-01-17
    相关资源
    最近更新 更多