为什么 vmalloc 返回的地址不能转换为物理地址
Why the addresses returned by vmalloc cannot be translated to physical address
我正在尝试了解 Linux 中的内存管理。在 vmalloc 的情况下,我发现了这个
Addresses returned cannot be translated into physical ones or into
bus addresses, because you cannot assert that the memory is physically
contiguous.
当我调用 virt_to_phys() 时,我得到一个地址。
您是说 virt_to_phys 的 return 值不正确吗
#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
物理内存被分成许多页,其中每个页可能是一个 4 KiB 区域;并且物理页面被映射到内核喜欢的任何地方的虚拟内存中。
对于vmalloc()
;内核分配 "random"(非连续)物理页面并将它们映射到连续的虚拟地址。可以将vmalloc()
返回的地址转换为物理地址,但它只是第一页内的物理地址,与下一页或其他页的物理地址无关。
您可以将每个单独页面的虚拟地址转换为物理地址。例如。如果使用vmalloc()
分配1234页;然后(使用像“for(virtual_address = start; virtual_addresss < end; virtual_address += PAGE_SIZE) {
这样的循环)你可以找到1234个完全不相关的物理地址。
我正在尝试了解 Linux 中的内存管理。在 vmalloc 的情况下,我发现了这个
Addresses returned cannot be translated into physical ones or into bus addresses, because you cannot assert that the memory is physically contiguous.
当我调用 virt_to_phys() 时,我得到一个地址。
您是说 virt_to_phys 的 return 值不正确吗
#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
物理内存被分成许多页,其中每个页可能是一个 4 KiB 区域;并且物理页面被映射到内核喜欢的任何地方的虚拟内存中。
对于vmalloc()
;内核分配 "random"(非连续)物理页面并将它们映射到连续的虚拟地址。可以将vmalloc()
返回的地址转换为物理地址,但它只是第一页内的物理地址,与下一页或其他页的物理地址无关。
您可以将每个单独页面的虚拟地址转换为物理地址。例如。如果使用vmalloc()
分配1234页;然后(使用像“for(virtual_address = start; virtual_addresss < end; virtual_address += PAGE_SIZE) {
这样的循环)你可以找到1234个完全不相关的物理地址。