繁体   English   中英

如果我只有设备缓冲区(PCIe)的物理地址,该如何将该缓冲区映射到用户空间?

[英]If I have only the physical address of device buffer (PCIe), how can I map this buffer to user-space?

如果我只有通过PCI-Express BAR(基址寄存器)将设备缓冲区映射到的内存缓冲区的物理地址 ,我如何将该缓冲区映射到用户空间

例如,代码在Linux内核中通常应如何显示?

unsigned long long phys_addr = ...; // get device phys addr
unsigned long long size_buff = ...l // get device size buff

// ... mmap(), remap_pfn_range(), Or what should I do now?

开启: Linux x86_64

来自: https : //stackoverflow.com/a/17278263/1558037

ioremap()将物理地址映射到内核虚拟地址。 remap_pfn_range()将物理地址直接映射到用户空间。

来自: https : //stackoverflow.com/a/9075865/1558037

int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, 
    unsigned long pfn, unsigned long size, pgprot_t prot);

remap_pfn_range-将内核内存重新映射到用户空间

可以使用吗?

unsigned long long phys_addr = ...; // get device phys addr
unsigned long long size_buff = ...l // get device size buff

remap_pfn_range(vma, vma->vm_start, (phys_addr >> PAGE_SHIFT), 
    size_buff, vma->vm_page_prot);

问题:但是,在哪里可以得到wma ,在调用remap_pfn_range()之前必须先使用wma进行remap_pfn_range()

映射PCI资源取决于体系结构。

BAR已通过sysfs文件/sys/bus/pci/devices/*/resource*用于用户空间,该文件支持mmap

这由drivers/pci/pci-sysfs.c的函数pci_mmap_resource实现,该函数最终调用pci_mmap_page_range

至少Linux内核2.6.x版使用ioremap()函数。

void *vaddr = ioremap (phys_addr, size_addr);
if (vaddr) {
  /* do stuff with the memory using vaddr pointer */
  iounmap (vaddr);
}

您应该事先调用request_mem_region()来检查该内存空间是否已被另一个驱动程序回收,并礼貌地请求该代码归您的代码(驱动程序)所有。 完整的示例应如下所示:

void *vaddr;
if (request_mem_region (phys_addr, size_addr, "my_driver")) {
  vaddr = ioremap (phys_addr, size_addr);
  if (vaddr) {
    /* do stuff with the memory */
    iounmap (vaddr);
  }
  release_mem_region (phys_addr, size_addr);
}

您可以通过检查/proc/iomem来检查您的所有权,这将反映地址范围和系统中每个内存的所有者。

更新:我真的不知道这是否适用于64位内核。 它适用于32位。 我猜如果64位内核没有这些内核功能,它们将具有类似的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM