使用端口映射I / O时是否使用虚拟内存?

时间:2017-06-03 09:40:14

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

如果我有一个内存映射的I / O设备,并且我想写入位于地址0x16D34的此设备的寄存器,则0x16D34地址实际上是一个虚拟地址,并且CPU会先将其转换为物理地址,然后将数据写入物理地址。

但是端口映射的I / O设备(例如:串行端口)怎么样,所以如果我想写一个位于地址0x3F8的串口的寄存器,那就是{{1}寻址物理地址或虚拟地址?

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

2 个答案:

答案 0 :(得分:4)

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

有关详细信息,您可以查看英特尔“英特尔®64和IA-32架构开发人员手册:第1卷”(chapter 18 as of this writing)中的“输入/输出”一章。

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

答案 1 :(得分:0)

看来你的问题是内存映射I / O和端口映射IO之间的区别。处理器通常有两种连接外部设备的方法,即内存映射或端口映射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

中获得更详细的信息