0

dma_alloc_coherent()在我的自定义驱动程序中使用来获取虚拟地址和总线地址。

res->KernelAddress = (u64)dma_alloc_coherent( &DevExt->pdev->dev, size, &res->BusAddress, GFP_ATOMIC );

当打印 (%llx) 总线地址 (res->BusAddress) 时,我得到了 80009000 作为一个。我检查了 /proc/iomem 的日志以验证范围,但有多个条目。

/proc/iomem 的日志如下所示:

10000000-10000fff : /pcie-controller@10003000/pci@1,0
10003000-100037ff : pcie-pads
10003800-10003fff : pcie-afi
10004000-10004fff : /pcie-controller@10003000/pci@3,0
40000000-4fffffff : pcie-config-space
50100000-57ffffff : pcie-non-prefetchable
  50800000-52ffffff : PCI Bus 0000:01
    50800000-5087ffff : 0000:01:00.0
    51000000-51ffffff : 0000:01:00.0
    52000000-52ffffff : 0000:01:00.0
58000000-7fffffff : pcie-prefetchable
  58000000-58ffffff : PCI Bus 0000:01
    58000000-58ffffff : 0000:01:00.0
80000000-d82fffff : System RAM
  80080000-810fafff : Kernel code
  8123f000-814b3fff : Kernel data
d9300000-efffffff : System RAM
f0200000-275ffffff : System RAM
276600000-2767fffff : System RAM
  1. 80009000有效吗?它属于哪个部分?
  2. 是否有必要使用dma_mmap_coherent()afterdma_alloc_coherent()进行正确的映射?

提前致谢 !!

4

1 回答 1

0

来自https://www.kernel.org/doc/Documentation/bus-virt-phys-mapping.txt(此文件的一些详细信息现已过时,但它是对该问题的最佳概述):

本质上,寻址内存的三种方式是(这是“真实内存”,即普通 RAM——其他细节见后文):

  • CPU 未翻译。这是“物理”地址。物理地址 0 是 CPU 在内存总线上驱动零时看到的地址。

  • CPU 翻译地址。这是“虚拟”地址,完全在 CPU 内部,由 CPU 进行适当的转换为“未翻译的 CPU”。

  • 总线地址。这是其他设备看到的内存地址,而不是 CPU。现在,理论上可能有许多不同的总线地址,每个设备都以某种特定于设备的方式查看内存,但令人高兴的是,大多数硬件设计人员实际上并没有积极尝试让事情变得比必要的更复杂,所以你可以假设所有外部硬件以同样的方式看待内存。

现在,在普通 PC 上,总线地址与物理地址完全相同,事情确实非常简单。然而,它们是如此简单,因为内存和设备共享相同的地址空间,而在其他 PCI/ISA 设置上通常不一定如此。

最重要的是,您的问题的答案取决于架构。

在您的/proc/iomem代码段中,请注意该列表是嵌套的。该80009000地址似乎分为两个部分,因为其中一个部分是另一个部分的子集。如果该地址是物理内存地址,那么是的,它将是“内核代码地址”,从dma_alloc_coherent. 这让我相信物理地址架构上的总线地址不同。

dma_alloc_coherent还将内存映射到内核虚拟地址空间中,因此您无需执行任何其他操作即可从代码中访问它。(dma_mmap_coherent用于将内存映射到用户虚拟地址空间。)

于 2018-11-19T20:51:40.150 回答