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?
Asked
Active
Viewed 2,401 times
2
-
You probably should use something like `dma_alloc_coherent` instead of `kmalloc`. – zch May 18 '13 at 10:34
-
Like zch said, or some other DMA mechanism. You should read up on DMA in the LDD3. It's section is still relevant. http://tjworld.net/books/ldd3/#DirectMemoryAccess – Benjamin Leinweber May 20 '13 at 21:54
2 Answers
0
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.

Igmar Palsenberg
- 637
- 4
- 10
-
Here is what's happening. I have a busif driver which maps the PCI space as mentioned and also stores the physical as follows : base_addr = pci_resource_start(). Now this again gets maps to virtual address using ioremap_nocache(). On top of bus layer, i have another module which is responsible to read/write to registers using write()/read() calls. Also i need to program few Bar offsets with a physical memory location for HW to to DMA operations, put in requests from user, etc... As HW needs 64K of page, i do a kmalloc() and the physical address of this needs to go to offset... – pkumarn May 18 '13 at 12:08
0
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.

Vikrant Patel
- 17
- 1
- 7
-
Thanks for all the replies. My only concern is are all these memory allocated DMA'able ? After further reading, i have decided to use pc_alloc_consistent() which allocates a page and also DMA'able. Can any thwo some light on why pages allocated using kmalloc(), __get_free_pages() etc (any other function which gives kernel virtual address) and when converted to physical address is not recommended for DMA? I have a solution but i am not clear why? – pkumarn May 21 '13 at 10:50
-
Because your requirement is to deal with physical address space. so this functions gives fulfil your needs. – Vikrant Patel May 21 '13 at 11:13
-
-
DMA'ble means HW can do DMA transfer on the allocated region. My HW needs to DMA userland data to this location for driver to pick up and process it. – pkumarn May 24 '13 at 09:04
-
ok. I don't have much knowledge on that. But what i know is that if you want to access physical address then use page_alloc() function rather than kmalloc() if it will helpful and solve your problem. – Vikrant Patel May 24 '13 at 09:40