如果我只有设备缓冲区(PCIe)接口的物理地址,我怎么可以映射此缓冲用户空间? [英] If I have only the physical address of device buffer (PCIe), how can I map this buffer to user-space?
问题描述
如果我只有内存缓冲区的物理地址以被映射通过PCI-Ex的preSS BAR设备缓冲区(基址寄存器),我怎么可以映射此缓冲区以用户空间
If I have only the physical address of the memory buffer to which is mapped the device buffer via the PCI-Express BAR (Base Address Register), how can I map this buffer to user-space?
例如,如何通常code应该看起来像Linux的内核?
For example, how does usually the code should look like in Linux-kernel?
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的
从:<一href=\"http://stackoverflow.com/a/17278263/1558037\">http://stackoverflow.com/a/17278263/1558037
的ioremap()
物理地址映射到内核虚拟地址。
remap_pfn_range()
物理地址直接映射到用户空间。
ioremap()
maps a physical address into a kernel virtual address.remap_pfn_range()
maps physical addresses directly to user space.
来源: http://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 - 重映射内核内存用户空间
remap_pfn_range - remap kernel memory to userspace
可能是我可以用它呢?
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
,以及我必须pre-DO与 WMA
调用 remap_pfn_range()之前
?
Question: But, where can I get wma
, and what I must pre-do with wma
before call to remap_pfn_range()
?
推荐答案
Linux内核,至少,版本2.6.x的使用的ioremap()
功能。
The Linux kernel, at least, versions 2.6.x use the ioremap()
function.
void *vaddr = ioremap (phys_addr, size_addr);
if (vaddr) {
/* do stuff with the memory using vaddr pointer */
iounmap (vaddr);
}
您应该做一个previous调用 request_mem_region()
来检查,如果内存空间已经被其他司机回收,并礼貌地要求内存被国有您code(驱动器)。完整的例子应该是这样的:
You should make a previous call to request_mem_region()
to check if that memory space is already reclaimed by another driver, and politely request that memory to be owned by your code (driver). The complete example should look like this:
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中
检查你的所有权,这将反映在地址范围,并在你的系统中的每一块内存的所有者。
You can check your ownership by checking /proc/iomem
, which will reflect the address range and the owner of every piece of memory in your system.
更新:我真的不知道,如果这个工程的64位内核。它为32位。如果64位内核没有这些内核函数,他们将有类似的,我想。
UPDATE: I don't really know if this works for 64-bit kernels. It does for 32-bit. If 64-bit kernel don't have these kernel functions, they will have similar ones, I guess.
这篇关于如果我只有设备缓冲区(PCIe)接口的物理地址,我怎么可以映射此缓冲用户空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!