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

Posted

技术标签:

【中文标题】内存映射 IO - 它是如何完成的?【英文标题】:Memory mapped IO - how is it done? 【发布时间】:2012-03-28 02:39:38 【问题描述】:

我已经了解了端口映射 IO 和内存映射 IO 之间的区别,但我无法弄清楚在现代操作系统(windows 或 linux)中如何实现内存映射 Io

我所知道的是,物理内存的一部分被保留用于与硬件通信,并且有一个 MMIO 单元参与处理总线通信和其他与内存相关的事情

驱动程序如何与底层硬件通信?驱动程序会使用哪些功能?与视频卡通信的地址是固定的,还是在使用它们之前有某种“协议”?

我还是比较迷茫

【问题讨论】:

你看过Using I/O Memory和Memory Mapping and DMA吗? 让我们看看我是否得到它(在 linux 中):1)我在硬件生产商告诉我的地址上分配了一个内存 IO 区域 2)我使用 ioremap 将其从物理地址转换为虚拟地址地址(所以我想这解决了分段和分页) 3)我使用 iowrite/ioread 和类似的读取和写入该区域。这是正确的吗? 没错,使用后记得释放分配内存区域。 【参考方案1】:

您问题中的以下陈述是错误的:

What I know is that a part of the physical memory is reserved to communicate with the hardware

物理内存的一部分保留用于与硬件通信。物理内存和内存映射 IO 映射到的物理地址空间的一部分是。这种内存布局是永久性的,但用户程序不会直接看到它 - 相反,它们会运行到自己的虚拟地址空间,内核可以决定将物理内存和 IO 范围映射到任何地方.

您可能想阅读以下文章,我相信这些文章包含了您大部分问题的答案:

http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory

【讨论】:

谢谢,我已阅读所有内容,发现它们对我的目的很有用【参考方案2】:

http://en.wikipedia.org/wiki/Memory-mapped_I/O

http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/IO/mapped.html

本质上它只是访问数据的一种形式,就好像您正在保存/从内存中读取一样。但是硬件会在地址总线上窥探,当它看到针对他的地址时,它只会在数据总线上接收数据。

【讨论】:

【参考方案3】:

您问的是内存映射文件还是内存映射端口 IO?

内存映射文件是通过分页页面并将页面错误拦截到这些地址来完成的。这一切都是由操作系统通过文件系统管理器和页面错误处理程序之间的协商来完成的。

内存映射端口 IO 在 CPU 级别通过重载地址线作为端口 IO 线来完成,这允许对内存的写入作为端口 IO 转换到 QPI 总线上。这一切都是由处理器与主板交互来完成的。操作系统需要做的另一件事是告诉 MMU 不要通过 PAE 必须写入和无缓存位来合并读取和写入。

【讨论】:

缩略词的一些扩展在这里会很有帮助。 这实际上是引导我写作方向的答案。 “就程序而言,其逻辑地址空间中的地址始终可用。但是,如果应用程序访问当前不在物理 RAM 中的内存页面上的地址,则会发生页面错误。发生这种情况时,虚拟内存系统调用一个特殊的页面错误处理程序来立即响应错误。”这个处理程序可能会做不同的事情,包括与磁盘的交互。

以上是关于内存映射 IO - 它是如何完成的?的主要内容,如果未能解决你的问题,请参考以下文章

八文件IO——存储映射

内存映射 IO - IO 设备如何知道值已更改?

内存映射 io 和 io 映射 io 有啥区别

Java NIO - 内存映射文件

DMA 和内存映射 IO 有啥区别?

存储映射IO