2
votes

I have a PCI device which exposes a BAR and few offsets in the bar for accessing the device. On one of the Bar offset, i need to program a 64KB allocated memory. In my Linux driver, i allocate a 64KB of memory using kmalloc() which as i know returns virtual address. If this is programmed into the offset, HW won't be able to see the same. How do i convert this virtual address to physical ? When i Google, i see few links pointing to virt_to_phys() but few responses says this doesn't work well with kmalloc(). Any idea how to go about this?

2
You probably should use something like dma_alloc_coherent instead of kmalloc.zch
Like zch said, or some other DMA mechanism. You should read up on DMA in the LDD3. It's section is still relevant. tjworld.net/books/ldd3/#DirectMemoryAccessBenjamin Leinweber

2 Answers

0
votes

You normally use pci_resource_start() / pci_resource_end() from within a kernel driver. I assume you are writing a device driver ?

I won't map the memory yourself : That's where the kernel functions are for. That way, you're sure it works on all platforms. That 64k block I assume is some memory map that is provided by the PCI device ? if yes, then the above is correct. If no, please give more information.

0
votes

Rather than using kmalloc() , use alloc_pages() function.

struct page* alloc_pages(gfp_t gfp_mask, 4 );

one page is of 4K, so it will allocate 2^4=16 pages which is equal to 16 * 4K = 64K memory and returns physical address.