【问题标题】:Linux allocates memory at specific physical addressLinux 在特定物理地址分配内存
【发布时间】:2013-01-03 19:30:48
【问题描述】:

我正在测试一个 PCI 端点驱动程序,我想做从 PCI RootPort 端到 PCI 端点端的简单复制。在 PCI Endpoint 端,我们有从 PCI 地址到 CPU 物理地址的地址转换。我们可以在转换中配置 CPU 物理地址,使其映射到特定的 DRAM 区域。问题是我们如何在特定的 CPU 物理地址分配内存缓冲区以确保来自 RootPort 端的写入确实有效?

感谢任何建议。非常感谢!

【问题讨论】:

  • 从 PCI 地址到 CPU 物理地址的转换是在启动时固定的,还是可以通过您的代码即时更改?
  • 嗨@Adrian Cox,我们可以随时更改它。配置只是寄存器设置

标签: linux linux-device-driver device-driver pci


【解决方案1】:

您需要先保留物理内存区域。最简单但丑陋的方法是将“mem =”参数传递给内核命令行,从内核内存管理中排除您感兴趣的物理内存范围,然后使用ioremap() 获取虚拟映射那个。

例如,如果您的机器有 256 Mb 的 RAM,则使用 mem=255M 来保留最后一个 Mb 供您使用,然后通过 ioermap() 映射它

注意:根据@Adrian Cox 的反馈修复了原始答案。

【讨论】:

  • 这不是从前到后吗? ioremap 为您提供了访问 IO 资源的虚拟地址,但 @dien 想要在特定的转换窗口内分配 RAM。
  • 嗨@gby,谢谢你的回答!如果我们 ioremap ram 区域的一部分,我们如何确保我们不会弄乱其他内核/应用程序数据?
【解决方案2】:

如果您可以即时重新映射转换,那么您应该像使用 DMA 的任何驱动程序一样工作。您对此的基本参考是Chapter 15 of LDD3,加上Linux DMA API

您分配的是一个 DMA 相干缓冲区,通过 dma_alloc_coherent。在大多数平台上,您应该能够传入一个空的 struct device 指针并获得一个通用的 DMA 地址。这将为您提供一个内核虚拟地址来访问数据,以及一个 dma 地址,它是通过您的转换层映射的 CPU 物理地址。

如果您的地址转换不是很灵活,您可能需要修改端点的平台代码以尽早保留此缓冲区,以满足地址对齐要求。这有点复杂,但最近的内核有一个update of the bigphysarea 补丁,可以作为一个起点。

【讨论】:

  • 嗨 Adrian Cox 和 @gby,非常感谢您的回答。从内核命令行和 DMA 分配中保留的 1MB 都可以正常工作。选择 Cox 的答案作为最佳解决方案,因为他首先找到了解决方案。再次感谢你们!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 2014-11-11
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多