我一直在使用 Linux(Ubuntu)。要与 IO 设备通信,需要使用 IO 端口地址。例如,0x378 是并行端口的地址。
IO 端口地址是实际的 RAM 地址吗?如果不是,那么它位于哪里?
答案1
回到使用 8088 微处理器的 IBM PC 的根源,RAM 和 IO 使用了单独的地址空间。8088 处理器在访问 RAM 时支持 20 位地址,但访问 IO 时仅使用 16 位地址。处理器上有一个额外的引脚,用于指示 RAM 或 IO 是否被寻址。
此过程称为端口映射 I/O,仍被实际的 X64 处理器使用。
因此并行端口的地址 0x378 在 RAM 中不存在地址。
答案2
假设一个 CPU 只有4引脚(位)来寻址设备。这意味着它可以从0000到1111。
现在想想 RAM 地址来自0000到0111(8地址,非常有限的RAM),它只留下其他8(从1000到1111) 用于其他设备(硬盘、串行端口、USB 端口、以太网、Wifi 等)。
同样的事情在实际的CPU上也非常普遍,它们有一个空间来寻址CPU上所有受物理引脚限制的硬件。当CPU启动时,BIOS识别安装的硬件并为每个硬件分配地址空间。
在较旧的系统中,如 DOS 和 Windows 3.1,它通常由配置文件作为自动执行程序和配置系统或拨码开关和跳线直接在硬件上。现代系统通过以下机制动态地实现这一点:PCI 和 PCI Express。
答案3
这不是操作系统的问题,而是 CPU 的问题。而且答案因 CPU 系列而异。
在 x86 (AMD/Intel) 上,答案是否定的。您给出的端口示例是 x86 PC 的典型示例,您可以从长度(16 位)中看出它不是 32 位或 64 位 RAM 地址。x86 具有与 IO 端口通信的特殊指令,这些 IO 指令知道 IO 地址是 16 位。
在 ARM 芯片上(您可能会在手机中找到这种芯片),IO 端口地址与 RAM 位于同一地址范围内(但显然位于不同的地址)。ARM 芯片使用相同类型的指令来读取 IO 端口和内存,因此在这两种情况下您都需要 32 位地址。