Reputation: 528
I try to implement my own Linux driver for a reserved-memory area. I following on this description: https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841683/Linux+Reserved+Memory
The memory reservation already works as expected. Now I'm writing my Linux driver using the memremap()
function in my probe function:
paddr = r.start;
vaddr = memremap(paddr, 4096, MEMREMAP_WB);
printk("Allocated reserved memory, vaddr: 0x%0X, paddr: 0x%0X\n", (u32)vaddr, paddr);
printk("Allocated reserved memory, paddr (2): 0x%0x\n", virt_to_phys(vaddr));
I try to understand the memremap()
and virt_to_phys()
since it is important for the driver to access the right physical adders at paddr. With the linese above, I would expect, that I have two times the same physical address paddr.
Unfortunately the output is:
[10370.743577] Allocated reserved memory, vaddr: 0xE0847000, paddr: 0x20000000
[10370.750564] Allocated reserved memory, paddr (2): 0x20847000
So there is an offset of 0x847000 bytes when try to get the physical address back from vaddr using virt_to_phys()
. Where does this offset come from? I would expect that the driver reads and writes to 0x20000000 instead of 0x20847000.
Upvotes: 0
Views: 96
Reputation: 2253
virt_to_phys()
computes the physical address with a simple subtraction and works only for logical kernel addresses which are, for example, those got from kmalloc
. In a typical 3GB/1GB memory split layout, kernel is mapped starting from 0xC0000000
and a logical address (let's call it la
) is a virtual address corresponding to a physical address (pa
):
pa = la - 0xC0000000
In your case, the virtual address returned by memremap
is not a logical address but virt_to_phys
does not know it and performs the subtraction:
0xE0847000 - 0xC0000000 = 0x20847000
Upvotes: 0