gpt4 book ai didi

linux-kernel - 从 DMA 地址 (dma_addr_t) 获取 PFN?

转载 作者:行者123 更新时间:2023-12-04 10:42:51 45 4
gpt4 key购买 nike

我想获得与 dma_alloc_coherent 分配的内存块相关联的 PFN用于 PCIe 设备,如下所示:

unsigned long pfn;

buffer = dma_alloc_coherent(&pcie->dev, size, &bus_addr, GFP_KERNEL);

// Get PFN?
virt_to_phys(buffer) >> PAGE_SHIFT;

我知道这可能不是正确的方法,但它似乎有效......我只是在寻找正确的解决方案来将潜在的总线地址(因为我不知道是否有 IOMMU)转换为PFN。提前致谢。

注意:内核中似乎有一个名为 dma_to_pfn 的 ARM 函数,这似乎正是我需要的,但对于 x86。

最佳答案

你的做法确实是错误的。来自 virt_to_phys() 的手册页:

This function does not give bus mappings for DMA transfers. In almost all conceivable cases a device driver should not be using this function.



DMA 地址的等效函数是 dma_to_phys() , 在 include/linux/dma-direct.h 中定义如下:

phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);

因此你可以这样做:

dma_to_phys(&pcie->dev, bus_addr) >> PAGE_SHIFT;

请注意,我使用的是 bus_addrdma_alloc_coherent() 返回,而不是 buffer ,因为您显然需要将 DMA 地址 ( dma_addr_t ) 传递给此函数,而不是虚拟地址。

好像还有一个宏 PHYS_PFN() 定义于 include/linux/pfn.h获取给定物理地址的 PFN,如果您更喜欢使用它:

PHYS_PFN(dma_to_phys(&pcie->dev, bus_addr));

关于linux-kernel - 从 DMA 地址 (dma_addr_t) 获取 PFN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59847162/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com