【问题标题】:Is it possible to use dma_set_mask() to tell kernel not to use memory under 4G是否可以使用 dma_set_mask() 告诉内核不要使用 4G 以下的内存
【发布时间】:2015-05-14 09:29:18
【问题描述】:

我的 pcie 设备有一个错误,它无法 dma 到低于 4G 的地址,我应该使用什么掩码和 dma_set_mask 来告诉内核?

【问题讨论】:

  • 不,你不能。 DMA 掩码定义从地址 0x00000000 开始的区域。
  • 你是指soc端的DMA还是外部设备端的DMA?

标签: linux-kernel linux-device-driver kernel-module dma pci-e


【解决方案1】:

没有。 pci_set_dma_mask() 与您想要的完全相反:它告诉内核不要使用更高的地址。

最简单的做法可能是在启动时保留高端内存并仅使用该内存。看看linux/include/linux/dma-contiguous.h 以获得灵感。特别是dma_declare_contiguous()

如果无法提前分配内存,事情就会变得更加棘手。在这种情况下,您必须通读“正常”PCI 分配代码的作用,然后自己动手。

我发现去年的嵌入式 Linux 大会上的 the slides of this presentation 很有见地。它们当然包含许多指向有用的标头和源代码的指针以供阅读。

【讨论】:

    【解决方案2】:

    查看DMA_API_HOWTO 似乎需要dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) 才能启用>32 位映射地址。特别是(对于一致的映射):

    一致的 DMA 映射接口,对于非 NULL 开发,将由 默认返回一个 32 位可寻址的 DMA 地址。即使 设备指示(通过 DMA 掩码)它可以寻址高 32 位, 如果满足以下条件,则一致分配只会为 DMA 返回 > 32 位地址 一致的 DMA 掩码已通过显式更改 dma_set_coherent_mask()。 dma_pool 接口也是如此 嗯。

    但是,这个(dma_set_mask_and_coherent() 调用)不能保证有效(有关详细信息,请参阅 HOWTO)。此外,您可能需要多次调用dma_alloc_coherent(),直到获得大于 4GB 的 DMA 地址...

    我不知道有什么方法可以强制特定映射高于 32 位。

    【讨论】:

    • 使用 dma_alloc_coherent() 后我应该使用 dma_map_single() 吗?或者我的设备可以 dma 到返回的总线地址吗?
    猜你喜欢
    • 2015-10-21
    • 2015-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2010-11-05
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多