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

Posted

技术标签:

【中文标题】哪些真实平台将硬件端口映射到内存地址?【英文标题】:What real platforms map hardware ports to memory addresses? 【发布时间】:2011-05-19 01:03:58 【问题描述】:

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

int* ptr;
*ptr = 0;

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

这类平台的真实例子有哪些?

【问题讨论】:

只是添加到所有答案中,您的 x86 平台也执行此操作(内存映射 I/O)。您只是习惯于在由您的操作系统创建的受保护环境[1] 中工作,因此您不必(或偶然可以)触摸真实硬件的所有脏方面。编写一个驱动程序,或者更好的是,一个操作系统,你将不得不处理大量的内存映射 I/O,以及许多其他有趣的事情。 :) [1] en.wikipedia.org/wiki/Protected_mode 见***.com/questions/15371953/… 【参考方案1】:

您可以在现代 Windows 中执行此操作(我很确定 Linux 也提供此功能)。它被称为内存映射文件。您可以在 Windows 上将文件加载到内存中,然后仅通过操作指针来写入/更改它。

【讨论】:

我认为这不是 OP 所说的。内存映射 I/O 不同于内存映射文件。【参考方案2】:

根据我的经验,大多数系统都使用内存映射 I/O。 x86 平台有一个单独的、非内存映射的 I/O 地址空间(使用in/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 端口,无论它们是否是内存映射的。这种访问仅限于设备驱动程序,甚至设备驱动程序也会有一些操作系统接口来处理物理地址的虚拟内存映射和/或设置 DMA 访问。

在较小的系统(如嵌入式系统)上,I/O 地址通常由应用程序直接访问。对于使用内存映射地址的系统,这通常通过简单地设置一个带有设备 I/O 端口物理地址的指针并像使用其他任何指针一样使用该指针来完成。但是,为了确保访问发生并以正确的顺序发生,必须将指针声明为指向volatile 对象。

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

【讨论】:

我最近一直在研究这个话题,你的回答被证明是非常有用的。我有几个问题:哪些设备使用 i/o 地址空间?而且,由于内存对于内存映射设备和所有程序(在内存映射 i/o 中)都是通用的,所以在使用内存映射空间时会发生什么?那个空间在那个时候是不可用的吗? 在 PC 上使用 I/O 地址空间的设备示例有 PS/2 键盘、旧版 COM 端口等。我敢肯定还有其他一些事情。我不是硬件设计师,所以我不知道设计的新设备是否会使用 I/O 空间或更喜欢内存映射空间,即使所涉及的端口数量很少(在我看来,几乎所有除了现在插入 USB 或 SATA 的视频适配器)。 至于应用程序对内存映射 I/O 的访问,在支持虚拟地址的系统中,内存通常不会映射到进程空间中,除非通过某些特定请求允许系统仍然在它们之间进行仲裁应用程序。 迈克尔·伯尔:非常感谢!! 在 8080 上对 I/O 使用单独的指令意味着如果 RST 向量意外指向 RST 指令,它可能会浪费所有内存,但不会命中随机 I/O 设备。 8088 在很大程度上是 8080 的一个分支,并且出于类似的原因可能会追随它的脚步,即使 8088 上的堆栈指针不会到达 64K 段之外。【参考方案3】:

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

【讨论】:

【参考方案4】:

有关使用内存映射 I/O 的设备示例,请参阅 Embedded-Systems。路由器、adsl 调制解调器、微控制器等。

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

Windows 上的An NDIS 驱动程序就是一个例子。这称为内存映射 I/O,这样做的好处是性能。

【讨论】:

【参考方案7】:

这称为内存映射 I/O,一个很好的起点是Wikipedia article。

除非您正在编写驱动程序,否则现代操作系统通常会保护您免受这种情况的影响,但这种技术即使在 PC 架构上也很重要。还记得 DOS 640Kb 的限制吗?那是因为为 I/O 分配了从 640K 到 1Mb 的内存地址。

【讨论】:

【参考方案8】:

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

【讨论】:

以上是关于哪些真实平台将硬件端口映射到内存地址?的主要内容,如果未能解决你的问题,请参考以下文章

什么时候在ARM板上安装操作系统?调用端口的地址会映射到真实地址还是虚拟地址?

内存映射 IO - 它是如何完成的?

linux 操作 I/O 端口

内存映射(Linux设备驱动程序)

操作系统学习

Windows 逆向使用 CE 工具挖掘关键数据内存真实地址 ( CE 找出子弹数据内存地址是临时地址 | 挖掘真实的子弹数据内存地址 )