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 thi
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);
}
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);
}
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.
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.
Mapping PCI resource is dependent on the architecture.
BARs are already available to userspace with the sysfs files /sys/bus/pci/devices/*/resource*
, which support mmap
.
This is implemented by the function pci_mmap_resource
in drivers/pci/pci-sysfs.c
, which ends up calling pci_mmap_page_range
.