[英]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.