【问题标题】:Using static data structures for DMA为 DMA 使用静态数据结构
【发布时间】:2010-12-22 20:41:39
【问题描述】:

我有一个用于 linux 内核 (2.6.18) 的驱动程序,其中我使用 kmalloc(sizeof(my_struct_t), GFP_ATOMIC) 来分配内存,该内存后来用于使用某些设备的 DMA 控制器进行数据传输。后来我不得不增加 my_struct 的大小。它变得太大,以至于 kmalloc() 代码使用静态断言并编译了 __you_cannot_kmalloc_that_much 符号来通知内存块太大而无法分配。所以我想我会将 my_struct_t 声明为静态变量,根本不必分配它。

我定义了 静态 my_struct_t my_struct;

但 DMA 事务运行不佳,我将无效数据 DMA 到缓冲区。

我的问题是:dma 是否禁止使用静态(全局)缓冲区?如果是,那么这些缓冲区在内核内存映射中的确切位置。

谢谢

【问题讨论】:

    标签: linux-kernel kernel


    【解决方案1】:

    您通常不能将任何旧内存用于 DMA。问题是您的内存区域可能会跨越页面边界并被分割到物理内存的不同区域。此外,它可能会被换出,然后再换回与以前不同的物理位置。在某些体系结构中,有些内存区域在设备总线上根本不可见。有时您可能很幸运,您获取不正确的 DMA 缓冲区可以正常工作,但这并不能保证。

    查看dma_alloc_coherent() 等dma 分配函数。还有LDD3第15章。

    如果您在分配 DMA 缓冲区时遇到问题,因为它们太大,那么您还有另一个问题,需要您手动拆分 DMA 传输,或者使用分散-聚集 DMA。

    【讨论】:

      【解决方案2】:

      问题会出现,如果您在堆栈上分配内存,则无法保证内存位于连续的物理内存块中。如果不是,则无法对其进行 DMA。

      将您的 DMA 传输分成多个您可以使用 kmalloc 的块不是更容易吗?然后,您可以发送 n 次 DMA 传输而不是仅发送 1 次。与您当前的问题不同,它对您的总线利用率几乎没有什么影响,并且可以正常工作。

      【讨论】:

      • 实际上我没有在堆栈上分配我使用全局变量,该变量分配在内核模块内的某些数据部分。该部分被加载到内核内存中,我假设该部分位于可继续访问的内存中。有人可以详细说明内核内存加载到内核内存时实际发生的情况
      • 它仍然不太可能被分配到物理内存中。通常一个程序被加载到虚拟内存中,因此你不能再保证块是连续的......
      猜你喜欢
      • 2011-05-04
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2012-09-08
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 2011-10-28
      相关资源
      最近更新 更多