gpt4 book ai didi

assembly - 关于x86 I/O口地址和IN/OUT指令的问题

转载 作者:行者123 更新时间:2023-12-03 13:54:11 28 4
gpt4 key购买 nike

据我所知,这是 PC 总线系统的简化 View (它不包括我知道的桥)。

如这张图片所示:
x86 Bus Simplified View

据我所知,我们在现代 x86 CPU 中有 65536 字节(0000-FFFF)的地址空间。这些是 I/O 地址。在 x86 中,IN 和 OUT 指令用于通过 I/O 端口与设备通信。

考虑到 PC(x86 cpu),以下是我的问题:

  • 我可以在不使用 PCI 或任何其他总线的情况下向此 I/O 总线添加设备吗?我的意思是与 IN/OUT 的直接通信。如果是,如何分配 I/O 地址?他们不冲突吗?
  • 如果我的 CPU 支持 PCI 和 I²C(是的,有些支持!),CPU 如何区分它们的 I/O 地址?它如何知道一个 I/O 地址属于 PCI 还是 I²C。

  • (顺便说一句,我不知道 I²C 地址是否只是逻辑而不是 I/O 端口,但这是另一个我也需要回答的问题)

    最佳答案

    1) Can I add a device to this I/O bus without using PCI or any other bus?



    理论上;是的。但是,对于现代系统,没有共享/公共(public)总线(现在是“点对点链接”);内存 Controller 和 PCI 主机都内置在与 CPU 相同的芯片中,这意味着(除非您是像英特尔这样的 CPU 供应商的员工)您将不得不处理高速串行链接(快速路径, Hyper-transport、PCIe 或 DMI),它们既不便宜也不易于连接(换句话说,它不像 1980 年代那样,您可以连接一个又好又慢的 ISA 总线)。

    If yes how are I/O addresses assigned? Don't they conflict?



    传统设备使用由历史/兼容性分配的固定 IO 端口。其他一切都由一种“IO 端口范围分配器”(内置于固件和/或操作系统中)动态分配,该分配器在 PCI 配置空间中配置 BAR(“基址范围”寄存器)。有一些(现已弃用/不存在)替代方案 - 由 ISA 卡上的物理跳线或 DIP 开关手动分配,ISA“即插即用”规范在许多设备支持它之前大部分被 PCI 取代,以及存在于其他类型的总线(MCA 和 EISA)用于动态资源分配。当然,大多数现代设备根本不使用 IO 端口(而是使用内存映射寄存器)。

    2-) If my CPU supports PCI and I²C (yes some do!), how does the cpu differentiate between their I/O addresses? How does it know that an I/O address belongs to PCI or I²C.



    对于 I²C,可能在某处(在 IO 端口地址空间或物理地址空间中)有一对寄存器用于向/从 I²C 总线发送和接收字节。 I²C 总线上的所有内容都将通过这 2 个寄存器访问,I²C 总线上的任何内容都无法访问 I²C 总线上的任何内容(包括无法访问任何 IO 端口和无法访问任何物理地址)。

    大多数情况下(如以太网、视频、USB 等),您有一个 Controller (具有 CPU 可以直接访问的寄存器)来控制 CPU 无法直接访问的内容(LAN、显示器信号、插入的 USB 设备) USB 总线,...)。

    (简化)示例

    让我们假设(由于 out dx,al 指令)CPU 在共享总线或链接上发送一条消息“ command = WRITE, space = IO port space, address = 0x1234, size = 1 byte, data = 0x56”。该消息可能被 PCI 主机 Controller 拦截,它查看详细信息(在哪个地址空间中的哪个地址)并决定将消息转发到 PCI 总线上的“PCI 到 LPC 桥接器”设备。当“PCI 到 LPC 桥接器”收到消息时,它可能会查看详细信息(地址空间中的哪个地址)并意识到它对应于 I²C 总线 Controller 并将其转发给 I²C 总线 Controller 。 I²C 总线 Controller 可能会解码消息并在 I²C 总线上发送字节 0x56(来自消息的“数据”部分)。然后,可能正在监听 I²C 总线的设备看到 0x56 字节并通过将字节 0x78 通过 I²C 总线发送回 I²C 总线 Controller 来响应,其中 Controller 将值 0x78 存储在内部缓冲寄存器中。

    下一个; (由于 in al,dx 指令)CPU 可能会发送另一条消息“ command = READ, space = IO port space, address = 0x1234, size = 1 byte”。此消息将遵循与前一个相同的路径(因为地址和地址空间相同)并最终到达 I²C 总线 Controller 。 I²C 总线 Controller 可能会解码该消息并意识到该消息要求从 I²C 总线 Controller 的内部缓冲寄存器(其保持之前的值 0x78)读取;所以 I²C 总线 Controller 发回消息“ command = READ_REPLY, space = IO port space, address = 0x1234, size = 1 byte, data = 0x78”。该回复消息将返回到 CPU(再次使用相同的路径,但方向相反——例如,到 PCI 到 LPC 桥,然后到 PCI 主机 Controller ,然后到 CPU)。当 CPU 收到回复时,它可以完成导致它的原始指令(例如,将 al 设置为“READ_reply”消息中的值以完成 in al,dx 指令)。

    这里的重点是 CPU 不能直接向 I²C 总线上的设备发送任何内容(CPU 只能与 I²C 总线 Controller 通信);并且 I²C 总线上的任何设备都不能直接向 CPU 发送任何内容(它们也只能与 I²C 总线 Controller 通信)。 I²C 总线上不需要知道任何关于 IO 端口的信息; CPU 总线/链路上的任何内容都不需要了解 I²C 总线上的字节。

    还; CPU 只是发送和接收消息。它不知道它们被发送后会发生什么,也不知道如何(例如)“ command = READ”消息将被转发到什么地方,也不知道哪个设备会发回“ command = READ_REPLY"消息。路由主要取决于消息所采用路径中每一步的逻辑。例如,PCI 主机 Controller 可能被配置为将 0x0000 到 0x2000 范围内的 IO 端口访问的所有消息转发到 PCI 总线,而 PCI 到 LPC 桥可能被配置为转发 0x1234 范围内的 IO 端口访问的所有消息到 0x1235 到 I²C 总线 Controller 。

    关于assembly - 关于x86 I/O口地址和IN/OUT指令的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56656650/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com