【问题标题】:Is virtual memory used when using Port-mapped I/O?使用端口映射 I/O 时是否使用虚拟内存?
【发布时间】:2017-06-03 09:40:13
【问题描述】:

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

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


编辑:我使用的是 x86 架构。

【问题讨论】:

  • 这看起来像 x86 而不是内存映射外围设备。这个特定的问题不会帮助您理解。你需要了解全貌。一本关于 PC 架构的好书将是一本好书。你问什么?虚拟内存/内存映射设备驱动程序?它们是两种截然不同的方法!
  • @Olaf 看起来不像是外围设备,你的意思是地址0x16D34?这只是我给出的一个数字示例,它没有指向任何东西。
  • @harold “IO 端口不是内存地址,所以你不能问它们是物理的还是虚拟的。” 但实际上我可以假设 IO 端口是物理的地址,就像我写地址0x3F8一样,数据将被写入地址0x3F8,而不是一些翻译后的地址,对吧?
  • @Cody Gray 那么如果0x3F8 不是地址,那么它是什么?我到处读到它是串行/COM 端口的基本 地址
  • 我也一直称它们为地址。即使是带有 BAR(基地址寄存器)的 PCI 规范,也将它们称为地址。它们是 IO 端口地址,但仍然是地址。无论如何,IO 地址空间从未被虚拟化,因为 1)它不是 GP 地址空间 2)除非设置了允许端口的位图,否则它始终是特权的。此外,英特尔手册说,向对齐的端口 X 写入一个字将在单个总线周期内写入端口 X 和端口 X+1,就像内存写入一样。值得注意的是,设备可以不同地对待写入 X 的单词。在 VGA 程序中写字很常见。

标签: c linux x86 device-driver virtual-memory


【解决方案1】:

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

如需了解详情,您可以查看英特尔“Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 1”(chapter 18 as of this writing) 的“INPUT/OUTPUT”一章。

请注意,在 x86 的早期,端口地址在每个设备中都是硬连线的,包括 ISA 附加卡。如果幸运的话,该卡有一组jumpers 用于为设备选择一组有限的可能端口范围中的一个,以避免设备之间的范围冲突。后来引入了Plug & Play,在系统启动时动态进行选择。 PCI 进一步完善了这一点,因此 I/O BAR 几乎可以通过操作系统和/或固件映射到 0x0000-0xffff 地址空间内的任何位置。现在在设计新硬件时强烈建议不要使用端口映射 I/O,因为它存在许多固有限制。

【讨论】:

  • 当地址在总线上时,x86 CPU 是否仍然包含一个用于选择内存或 I/O 的引脚?这就是我记忆事物的方式,但对我来说,大学是很多年前的事了(来自Memory-Mapped I/O):“IN 和 OUT 以及从内存加载和存储之间的唯一区别是 CPU 上的单个输出引脚。这个如果地址总线上的地址是内存地址,则 pin 将被输出,例如,0,如果地址是 I/O 地址,则输出 1".
  • @jww 我对此表示怀疑,今天的 CPU 内置了内存控制器,因此有很多引脚直接连接到内存模块,不需要在那里进行 I/O 寻址。它们也有直接的 PCI Express 通道。 PCIe 使用非常少的引脚,消息(包括地址和有效负载数据)仅在一对导线(每个方向)上串行传输,以使用差分信号。也许对于一些遗留的外围设备,但它们可能无论如何都在南桥。
【解决方案2】:

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

内存映射 I/O

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

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

端口映射 I/O

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-15
    • 2016-11-16
    • 2016-05-27
    • 1970-01-01
    • 2010-09-17
    • 2015-09-11
    • 2017-06-08
    • 2011-12-31
    相关资源
    最近更新 更多