什么真正的平台将硬件端口映射到内存地址?

我有时会在某些平台上看到以下C或C ++代码的语句:

int* ptr; *ptr = 0; 

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

这些平台的真实例子是什么?

根据我的经验,大多数系统都使用内存映射I / O. x86平台有一个独立的非内存映射I / O地址空间(使用输入/ out系列处理器操作码),但PC架构也广泛使用标准内存地址空间用于设备I / O,它具有更大的地址空间,更快的访问(通常),以及更容易的编程(通常)。

我认为最初使用单独的I / O地址空间是因为处理器的内存地址空间有时非常有限,并且使用它的一部分进行设备访问没有多大意义。 一旦内存地址空间被打开到兆字节或更多,那么将I / O地址与内存地址分开的原因变得不那么重要了。

我不确定有多少处理器提供像x86那样的独立I / O地址空间。 作为单独的I / O地址空间如何不受欢迎的指示,当x86架构进入32位领域时,没有做任何事情来将I / O地址空间从64KB增加(尽管它们确实增加了这个能力)在一条指令中移动32位数据块)。 当x86进入64领域时,I / O地址空间保持在64KB,甚至没有添加以64位为单位移动数据的能力……

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

在较小的系统上,如嵌入式系统,I / O地址通常由应用程序直接访问。 对于使用内存映射地址的系统,通常只需使用设备I / O端口的物理地址设置指针并像使用其他指针一样使用该指针即可。 但是,为了确保访问发生并以正确的顺序发生,必须将指针声明为指向volatile对象。

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

这称为内存映射I / O,一个好的起点是维基百科的文章 。

除非您正在编写驱动程序,否则现代操作系统通常会保护您免受此操作,但这种技术甚至可以在PC架构上使用。 还记得DOS 640Kb的限制吗? 这是因为为I / O分配了640K到1Mb的内存地址。

PlayStation游戏机。 这就是我们如何获得对系统的低级图形(和其他)function的直接优化访问。

Windows上的NDIS驱动程序就是一个例子。 这称为内存映射I / O,其优点是性能。

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

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

摩托罗拉68k系列和PowerPC是最重要的。

你可以在现代Windows中做到这一点(我很确定Linux也提供它)。 它被称为内存映射文件。 您可以将文件加载到Windows上的内存中,然后通过操作指针来编写/更改它。