Reputation: 4547
I am trying to understand the memory management in Linux. In case of vmalloc I found this
Addresses returned cannot be translated into physical ones or into bus addresses, because you cannot assert that the memory is physically contiguous.
When i call virt_to_phys(), I get an address.
Do you mean the return value of virt_to_phys is incorrect
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("GPL");
static char *ptr;
int alloc_size = 4096*1234;
static int test_hello_init(void)
{
ptr = vmalloc(alloc_size);
if(!ptr) {
/* handle error */
pr_err("memory allocation failed\n");
return -ENOMEM;
} else {
int i;
for (i = 0; i < 1234; i++) {
pr_info("Page Index:%d\tPhysical address:%px\t Virtual Address:%llx\n",
i, ptr+(4096*i), virt_to_phys(ptr+(4096*i)));
}
}
return 0;
}
static void test_hello_exit(void)
{
vfree(ptr);
pr_info("Memory freed\n");
}
module_init(test_hello_init);
module_exit(test_hello_exit);
dmesg:
[26472.440426] Page Index:1217 Physical address:ffffa1f544336000 Virtual Address:12ce44336000
[26472.440427] Page Index:1218 Physical address:ffffa1f544337000 Virtual Address:12ce44337000
[26472.440427] Page Index:1219 Physical address:ffffa1f544338000 Virtual Address:12ce44338000
[26472.440428] Page Index:1220 Physical address:ffffa1f544339000 Virtual Address:12ce44339000
[26472.440428] Page Index:1221 Physical address:ffffa1f54433a000 Virtual Address:12ce4433a000
[26472.440428] Page Index:1222 Physical address:ffffa1f54433b000 Virtual Address:12ce4433b000
[26472.440429] Page Index:1223 Physical address:ffffa1f54433c000 Virtual Address:12ce4433c000
[26472.440429] Page Index:1224 Physical address:ffffa1f54433d000 Virtual Address:12ce4433d000
[26472.440429] Page Index:1225 Physical address:ffffa1f54433e000 Virtual Address:12ce4433e000
[26472.440430] Page Index:1226 Physical address:ffffa1f54433f000 Virtual Address:12ce4433f000
[26472.440430] Page Index:1227 Physical address:ffffa1f544340000 Virtual Address:12ce44340000
[26472.440430] Page Index:1228 Physical address:ffffa1f544341000 Virtual Address:12ce44341000
[26472.440431] Page Index:1229 Physical address:ffffa1f544342000 Virtual Address:12ce44342000
[26472.440431] Page Index:1230 Physical address:ffffa1f544343000 Virtual Address:12ce44343000
[26472.440431] Page Index:1231 Physical address:ffffa1f544344000 Virtual Address:12ce44344000
[26472.440432] Page Index:1232 Physical address:ffffa1f544345000 Virtual Address:12ce44345000
[26472.440432] Page Index:1233 Physical address:ffffa1f544346000 Virtual Address:12ce44346000
Upvotes: 0
Views: 1156
Reputation: 37220
Physical memory is split up into many pages, where each page might be a 4 KiB area; and the physical pages are mapped into virtual memory wherever the kernel feels like it.
For vmalloc()
; the kernel allocates "random" (non-consecutive) physical pages and maps them at consecutive virtual addresses. You can convert the address returned by vmalloc()
into a physical address, but it will only be a physical address within the first page and won't have anything to do with the physical address of the next page or any other page.
You can convert the virtual address of each separate page into a physical address. E.g. if you use vmalloc()
to allocate 1234 pages; then (using a loop like "for(virtual_address = start; virtual_addresss < end; virtual_address += PAGE_SIZE) {
) you can find 1234 completely unrelated physical addresses.
Upvotes: 2