【发布时间】: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