Ste*_*eve 6 c linux x86 device-driver virtual-memory
如果我有一个内存映射的I/O设备,并且我想写入位于0x16D34该0x16D34地址的该设备的寄存器,该地址实际上是一个虚拟地址,CPU将首先将其转换为物理地址,然后写入数据到物理地址.
但对于端口映射I/O设备(例如:串行端口),所以如果我想要写一个寄存器位于地址串口0x3F8,是0x3F8地址的物理地址或虚拟地址?
编辑:我在x86架构上.
x86/x86-64 上的端口映射 I/O(大多数其他现代架构甚至不支持它)发生在完全独立的地址空间中。这个地址空间不受内存映射的影响,所以没有虚拟端口地址,只有物理端口地址。必须使用特殊in和out指令来执行端口 I/O,简单的内存访问(例如使用mov)无法访问这个单独的地址空间。可以基于权限级别进行访问保护;大多数现代操作系统默认阻止用户空间进程访问 I/O 端口。
例如,您可以查看英特尔的“英特尔® 64 位和 IA-32 架构开发人员手册:第 1 卷” (撰写本文时第 18章)的“输入/输出”一章以了解详细信息。
请注意,在 x86 的早期,每个设备(包括 ISA 附加卡)中的端口地址都是硬连线的。如果幸运的话,该卡有一组跳线,用于为设备选择一组有限的可能端口范围中的一个,以避免设备之间的范围冲突。后来,引入了即插即用以在系统启动期间动态进行选择。PCI 进一步完善了这一点,以便操作系统和/或固件几乎可以将 I/O BAR 映射到 0x0000-0xffff 地址空间内的任何位置。由于其许多固有限制,现在在设计新硬件时强烈建议不要使用端口映射 I/O。