是否可以使用 dma_set_mask() 告诉内核不要使用 4G 以下的内存

Is it possible to use dma_set_mask() to tell kernel not to use memory under 4G

我的 pcie 设备有一个错误,它不能 dma 到 4G 以下的地址,我应该使用什么掩码 dma_set_mask 来告诉内核这个?

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

The consistent DMA mapping interfaces, for non-NULL dev, will by default return a DMA address which is 32-bit addressable. Even if the device indicates (via DMA mask) that it may address the upper 32-bits, consistent allocation will only return > 32-bit addresses for DMA if the consistent DMA mask has been explicitly changed via dma_set_coherent_mask(). This is true of the dma_pool interface as well.

然而,这个(dma_set_mask_and_coherent() 调用)不能保证有效(更多细节参见 HOWTO)。此外,您可能需要多次调用 dma_alloc_coherent() 直到获得大于 4GB 的 DMA 地址...

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

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

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

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

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