/proc/mem日志中有多个PCIe地址范围条目



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

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

当打印(%lxx(总线地址(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_alloc_coherent()之后使用dma_mmap_coherent()进行正确映射

提前感谢!!

来源https://www.kernel.org/doc/Documentation/bus-virt-phys-mapping.txt(这个文件的一些细节现在已经过时了,但它是这个问题的最佳概述(:

本质上,寻址内存的三种方式是(这是"真实内存",也就是说,普通的RAM——请稍后参阅其他详细信息(:

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

  • CPU转换地址。这是"虚拟"地址完全在CPU内部,由CPU执行适当的操作翻译成"CPU未翻译"。

  • 总线地址。这是OTHER设备看到的存储器地址,而不是CPU。现在,理论上可能有很多不同的公共汽车地址,每个设备都以某种特定于设备的方式查看内存,但是令人高兴的是,大多数硬件设计师实际上并没有积极尝试事情比必要的更复杂,所以你可以假设外部硬件对内存的看法也是一样的。

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

问题的答案取决于体系结构。

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

dma_alloc_coherent还将内存映射到内核虚拟地址空间中,因此您不需要做任何其他事情来从代码中访问它。(dma_mmap_coherent用于将存储器映射到用户虚拟地址空间。(

最新更新