【问题标题】:map file in to the ram将文件映射到内存
【发布时间】:2010-12-28 20:04:45
【问题描述】:

Platofrm - Linux、Arch - ARM 编程语言——C/C++

目标 - 将常规(比如说文本)文件映射到 ram 中的一个预先知道的位置(物理地址),并将该物理地址传递给其他应用程序。我一次映射的块大小是 128K。

我正在尝试的方式是- 用户空间进程发出 ioctl 调用,要求设备驱动程序获取一块内存(ram),计算物理地址并将其返回给用户空间。

用户空间进程需要将文件映射到该物理地址空间 我不知道该怎么做。任何帮助表示赞赏。 ???

对文件调用 mmap 然后计算物理地址的问题是,页面在有人访问它们之前不在内存中,并且分配的物理内存页面可能不连续。

实际访问该文件的另一个进程来自第三方供应商应用程序。该应用程序要求一旦我们将物理地址传递给它,文件内容就需要存在于连续的内存中。

我现在是怎么做的 --

用户进程调用mmap到设备。 设备驱动程序执行 kmalloc,计算起始物理地址并将 VMA 映射到该物理地址。 现在用户进程读取文件并将其复制到在 mmap 期间获得的地址空间。

问题 - 文件的副本存在于 ram 中的两个位置,一个是从磁盘读取完成时,另一个是当我将它复制到使用 mmap 获得的缓冲区和相应的复制开销时。 在理想情况下,我想将文件直接从磁盘加载到已知/预定义的位置。

【问题讨论】:

  • 试图重新表述这个问题:对于设备(嵌入式 Linux?),IO 有一个硬编码的物理地址范围。这个地址范围应该映射到一个文件,所以任何读取或写入文件的人都会为设备做 IO。如何将地址范围映射到文件?

标签: c++ c linux mmap


【解决方案1】:

“映射文件”意味着使用虚拟地址而不是物理地址,所以这不会达到你想要的效果。

如果要将文件内容放入连续的物理内存块中,只需在获得连续缓冲区后使用open()read()

【讨论】:

  • 是的,你说得对。我正在按照您建议的方式进行操作。唯一的问题是,文件的副本同时存在于两个不同位置的内存中,还有所有额外的复制开销等。我试图将从磁盘读取的文件直接加载到预先知道的位置(物理内存),以避免文件在物理内存中的额外副本和相应的开销。
  • 你为什么不把mmap返回的缓冲区地址传递给read,这样它就可以直接读到那里?
【解决方案2】:

也许像madvise() 这样的MADV_SEQUENTIAL 建议参数会有所帮助?

需要考虑的一些事项:

  • 您要映射的文件有多大?
  • 即使您采用基于内核驱动程序的方法,这也可能会影响您获得连续 RAM 块的能力。
  • 对于基于内核驱动程序的方法,性能良好的驱动程序通常不应kmalloc()例如获取超过 32KB 的连续内存块。此外,您通常不能kmalloc() 超过 2MB(我已经尝试过这个:))。这是否适合您的需求?
  • 如果您需要非常大的内存块,类似内核的 alloc_bootmem() 函数可能会有所帮助,但它仅适用于静态“内置”驱动程序,不适用于动态可加载驱动程序。李>
  • 有什么方法可以重新设计您的设计,从而不再需要大的连续映射内存块?

【讨论】:

  • 是的.. 好点,我从来没有提到我要映射的块的大小。我不会超过 128K。我的内核驱动程序方法目前工作正常。我已经编辑了我的问题,以说明我现在的情况以及为什么它不是一个完美的解决方案。 madvise 看起来很有趣,我不知道这一点。
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 2023-04-06
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 1970-01-01
相关资源
最近更新 更多