哪些实际平台将硬件端口映射到内存地址?

10

我有时会看到这样的说法,在某些平台上,以下 C 或 C++ 代码:

int* ptr;
*ptr = 0;

如果ptr恰好存储了映射到硬件输入输出端口的地址,则可能导致向该端口写入数据。通常它们被称为“嵌入式平台”。

有哪些实际的这样的平台示例?


2
只是为了补充所有答案,你的x86平台也会这样做(内存映射I/O)。你只是习惯于在操作系统创建的受保护环境[1]中工作,因此您不必(或者无意中不能)接触真实硬件的所有肮脏方面。编写驱动程序,或者更好的是,操作系统,您将不得不处理大量的内存映射I/O,以及许多其他有趣的事情。 :) [1] http://en.wikipedia.org/wiki/Protected_mode - Bjarke Freund-Hansen
请参考以下链接:https://dev59.com/4G_Xa4cB1Zd3GeqP2ZC1。 - Pacerier
8个回答

12

在我个人的经验中,大多数系统都使用内存映射I/O技术。x86平台有一个单独的、非内存映射的I/O地址空间(使用in/out处理器操作码系列),但PC架构还广泛地使用标准内存地址空间进行设备I/O,这个地址空间更大、访问速度更快(通常情况下),编程也更容易(通常情况下)。

我认为最初使用单独的I/O地址空间是因为处理器的内存地址空间有时相当有限,将其一部分用于设备访问是没有意义的。一旦内存地址空间扩展到了兆字节或更多,将I/O地址从内存地址中分离出来的理由就变得不那么重要了。

我不确定有多少处理器像x86一样提供了单独的I/O地址空间。作为单独I/O地址空间不再流行的一个迹象是,在x86架构进入32位领域时,没有任何措施增加I/O地址空间的大小(虽然他们确实添加了一次性移动32位数据块的能力)。当x86进入64位领域时,I/O地址空间仍保持在64KB,并且他们甚至没有添加以64位单位移动数据的能力......

此外,请注意,现代桌面和服务器平台(或其他使用虚拟内存的系统)通常不允许应用程序访问I/O端口,无论它们是否是内存映射的。这种访问受到设备驱动程序的限制,即使是设备驱动程序也会有一些操作系统接口来处理物理地址的虚拟内存映射和/或设置DMA访问。

在像嵌入式系统这样的小型系统中,I/O地址通常被应用程序直接访问。对于使用内存映射地址的系统,通常只需设置指向设备I/O端口的物理地址的指针,并像任何其他指针一样使用该指针。然而,为确保访问发生并按正确顺序进行,必须将指针声明为指向volatile对象。

为了访问使用非内存映射I/O端口(例如x86的I/O地址空间)的设备,编译器通常会提供允许您读取或写入该地址空间的扩展。如果没有这样的扩展,您需要调用汇编语言函数来执行I/O操作。


最近我一直在研究这个话题,你的回答证明非常有用。我有几个问题:哪些设备使用i/o地址空间?另外,由于内存将用于内存映射设备和所有程序(在内存映射i/o中),当内存映射空间正在被使用时会发生什么?那个空间在那段时间内是否不可用? - Cygnus
一些使用PC的I/O地址空间的设备示例包括PS/2键盘、传统COM端口等。我相信还有很多其他的设备。我不是硬件设计师,因此我不知道新设计的设备是否会使用I/O空间,即使涉及到的端口数量很少(似乎除了视频适配器之外,几乎所有东西现在都插入USB或SATA)。 - Michael Burr
关于应用程序访问内存映射I/O,在支持虚拟地址的系统中,该内存通常不会被映射到进程空间中,除非通过某些特定请求进行映射,以便系统仍然可以在应用程序之间进行仲裁。 - Michael Burr
@MichaelBurr,为什么你说大多数系统使用内存映射I/O,而大多数英特尔微处理器使用端口映射呢?(Intel x86和兼容处理器都使用端口映射。) - Pacerier
@Pacerier:你认为哪个部分有争议?8080和8088的文档描述了相关行为。至于“大多数系统”,微控制器远远超过台式电脑,并且任何基于PIC、68HCxx家族或ARM的系统都会使用内存映射I/O。还有一些其他的控制器,包括8x51,使用固定地址指令进行I/O,但是即使是这三个家族也远远超过它们的数量。 - supercat
显示剩余6条评论

2
这被称为内存映射I/O,一个好的起点是查看维基百科文章。现代操作系统通常会保护您,除非您正在编写驱动程序,但即使在PC架构上,这种技术也很重要。还记得DOS的640Kb限制吗?那是因为640K到1Mb的内存地址被分配给了I/O。

1

PlayStation。这就是我们如何获得对系统低级图形(和其他)功能的一些直接优化访问。


1

Windows上的NDIS驱动程序就是一个例子。这被称为内存映射I/O,其好处是提高了性能。


1

请参考嵌入式系统,了解使用内存映射I/O的设备示例,例如路由器、ADSL调制解调器、微控制器等。


1

它主要用于编写驱动程序,因为大多数外围设备通过内存映射寄存器与主 CPU 通信。


0

摩托罗拉68k系列和PowerPC是其中的佼佼者。


-2
你可以在现代的Windows系统中实现这个功能(我相信Linux也提供了类似的功能)。它被称为内存映射文件。你可以将一个文件加载到Windows的内存中,然后通过操作指针来写入/修改它。

我认为这不是原帖所讨论的内容。内存映射I/O与内存映射文件是不同的。 - Bjarke Freund-Hansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接