Linux kernel 确保支持DMA的内存

Linux kernel 确保支持DMA的内存,linux-kernel,x86,linux-device-driver,dma,Linux Kernel,X86,Linux Device Driver,Dma,我正在阅读下面的“PartID”部分,我不确定该文档与内核2.6.35有多大关系;具体来说,它说: ..the DMA address of the memory must be within the dma_mask of the device.. 他们建议将某些标志(如GFP_DMA)传递给kmalloc,以确保内存位于提供的DMA掩码内 但是,如果内存是从kmem\u cache\u create创建的缓存池中分配的,并且使用kmem\u cache\u alloc(…GFP\u ATO

我正在阅读下面的“PartID”部分,我不确定该文档与内核2.6.35有多大关系;具体来说,它说:

..the DMA address of the memory must be within the dma_mask of the device..
他们建议将某些标志(如
GFP_DMA
)传递给
kmalloc
,以确保内存位于提供的DMA掩码内

但是,如果内存是从
kmem\u cache\u create
创建的缓存池中分配的,并且使用
kmem\u cache\u alloc(…GFP\u ATOMIC)
,这不符合DMA-API.txt中概述的要求

另一方面,LDD谈到有关传统ISA设备的
\uugfp\uDMA
标志,因此我不确定这是否适用于PCI/PCIe设备

这是x86 64位平台,如果重要的话:

pci_set_dma_mask(dev, 0xffffffffffffffffULL);
pci_set_consistent_dma_mask(dev, 0xffffffffffffffffULL);
我希望能听到一些解释

  • 对于GFP*对于DMA

    在x86上:

    • ISA-使用
      kmalloc()
      时,需要使用
      GFP\u内核
      (或
      \u原子
      )按位或
      GFP\u DMA
      ,原因如下:

      GFP\U DMA
      保证:

      (1) 当
      get\u free\u page
      返回多个页面且

      (2) 仅返回低于
      MAX\u DMA\u ADDRESS
      的地址<由于ISA限制,电脑上的代码>最大DMA地址为16MB

    • PCI-不需要使用
      GFP\u DMA
      ,因为没有
      MAX\u DMA\u地址限制

  • 调用
    dma\u-map.*
    dma\u-alloc\u-coherent
    时,设备会检查
    dma\u掩码

    dma\u alloc\u coherent
    确保分配的内存能够被
    dma\u map.*
    使用,这也带来了其他好处。(实现可以选择忽略影响返回内存位置的标志,如GFP_DMA)


  • 您可以参考

    谢谢。我在书中读到的另一个要求是“建议驱动程序编写器映射从页面边界开始和结束的虚拟区域”。什么内核API保证以页面为单位分配?这可以用kmem\u alloc\u缓存吗?
    \u get\u free\u page()
    \u get\u free\u page()
    是您想要的
    kmem\u alloc\u cache
    不能保证为您提供完整的页面。有关alloc页面的更多内核API,请参阅
    /mm/page\u alloc.c
    。您可以将
    SLAB\u HWCACHE\u ALIGN
    标志传递给
    kmem\u cache\u create
    ,以确保从
    kmem\u cache\u alloc
    获得的所有内存都与缓存线对齐
    kmalloc
    也做了类似的事情。因此
    kmalloc
    还可以保证内存与缓存线对齐。它在内部分配1+个连续的内存,称为slab。但是您不能通过调用
    kmem\u cache.*
    直接获得一个slab。相反,返回给您的内存
    kmem\u cache\u alloc
    的大小是您在它之前提供的
    kmem\u cache\u create