使用Port-mapped I/O时是否使用了虚拟内存?

Is virtual memory used when using Port-mapped I/O?

如果我有一个内存映射 I/O 设备,并且我想写入位于地址 0x16D34 的该设备的寄存器,0x16D34 地址实际上是一个虚拟地址地址,CPU会先翻译成物理地址,然后再把数据写入物理地址。

但是端口映射 I/O 设备(例如:串行端口)呢,所以如果我想写入位于地址 0x3F8 的串行端口的寄存器,是0x3F8地址是物理地址还是虚拟地址?


编辑:我在 x86 架构上。

x86/x86-64 上的端口映射 I/O(大多数其他现代架构甚至不支持它)发生在完全独立的地址 space 中。这个地址space不受内存映射影响,所以没有虚拟端口地址,只有物理地址。必须使用特殊的 inout 指令来执行端口 I/O,简单的内存访问(例如使用 mov)不能访问这个单独的地址 space。基于特权级别的访问保护是可能的;默认情况下,大多数现代操作系统会阻止用户 space 进程访问 I/O 端口。

详情可以查看Intel的"Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 1" (chapter 18 as of this writing).

章节"INPUT/OUTPUT"

请注意,在 x86 的早期,端口地址在每个设备中都是硬连线的,包括 ISA 附加卡。如果你幸运的话,该卡有一组 jumpers for selecting one of a limited set of possible port ranges for the device, in order to avoid range clashes between devices. Later, Plug & Play 被引入以在系统引导期间动态地进行选择。 PCI 进一步完善了这一点,因此 I/O BAR 几乎可以被操作系统 and/or 固件映射到 0x0000-0xffff 地址 space 内的任何地方。端口映射 I/O 由于其许多固有的局限性,现在在设计新硬件时强烈建议不要使用。

您的问题似乎是内存映射 I/O 和端口映射 IO 之间的区别。处理器连接外部设备通常有两种方法,内存映射或端口映射I/O.

内存映射I/O

内存映射 I/O 使用相同的地址 space 来寻址内存和 I/O 设备。所以当一个地址被CPU访问时,它可能指的是物理RAM的一部分,但它也可以指I/O设备的内存(基于Memory-mapped I/O on Wiki)。

第一个示例中的值 0x16D34 将是虚拟内存,并将映射到物理内存。 I/O 设备也将引用相同的物理内存以允许从 CPU.

进行访问

端口映射I/O

端口映射 I/O 使用单独的专用地址 space 并通过一组专用的微处理器指令访问。对于第二个示例中的 0x3F8 ,它是特定于内存和 I/O 设备的自身地址的地址。它不是我们之前在内存映射 I/O 中提到的内存和 I/O 设备之间共享的地址。您可能会在 Memory-mapped IO vs Port-mapped IO

中获得更详细的信息