为什么 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个完全不相关的物理地址。