如何在Linux内核中正确使用分散列表

时间:2018-09-05 14:17:07

标签: c linux module kernel dma

所以!可能已经有人问过这个问题,但是我找不到适合我需求的东西。我想制作一个可以映射到用户空间(虚拟连续内存)的缓冲区,同时还能够在其中构建分散列表以进行DMA操作。

这是我想象的样子:

  1. 分配缓冲区(vmalloc
  2. 找到此缓冲区的每个字节的总线地址,构建下表(仅当phys addr的差值大于PAGE_SIZE时,在其中插入新行)

    • ({struct scatterlist*:总线地址|长度)
  3. 调用dma_map_sg,它将填充dma_address个字段。

  4. 将dma_address以及每个物理缓冲区的长度发送到设备。
  5. 以某种方式将虚拟缓冲区映射到用户空间。

我用这种方法遇到的问题:

  1. 使用vmalloc不能指定需要多少个连续内存,尽管我的设备只能接受8192个总线地址,但不能接受更多的内存,这可能会导致PCI设备可以接受的内存更多。
  2. 除了this之外,我还没有在上述算​​法的步骤2)上找到任何内容,并且它实际上并没有编译。
  3. ioremap用于将物理内存映射到内核remap_pfn_range-通过MMAP操作将物理内存映射到用户空间。他们俩都希望将物理地址作为参数。如何将虚拟内核地址映射到用户空间?

基本上,我认为有些事情我不理解,我找不到一个很好的例子来说明如何正确地做到这一点。 Internet上充满了参考表,邮件列表和其他内容,但是每个实际示例都是一个包含成千上万个文件的项目,对于新手来说,这是很难快速完成的。对于我正在尝试实现的方法,感觉就像我正在尝试解决X/Y problem。有更好的方法吗?

编辑:找到了this。看起来我无法直接获取使用vmalloc分配的所有内存物理地址。我应该怎么用呢?

编辑2 :有人会认为我可以简单地使用CMA来代替,而根本不用理会分散列表-由于某些项目规定,我无法重建内核,因此它是内置的默认情况下没有CMA支持。我需要以某种方式分配3个4 GB的内存块,以便我的设备正常工作。

编辑3 :我不知道它是否对某人有帮助...虽然直到我知道它可行,否则它不会作为Q / A回答。

基本上,目前,我可以分配12 GB的内存,而不会引起内核崩溃(这要求您的设备支持64位地址):

dma_set_mask_and_coherent(pdev, DMA_BIT_MASK(64));
dma_pool_create(...);
dma_pool_alloc(...) for as many chunks of memory as you need.

现在的问题是,我是否能够映射所有这些内存块,并有效地循环遍历它们。

0 个答案:

没有答案