kmalloc 分配实际上不是连续的吗?

问题描述 投票:0回答:1

我发现

kmalloc
返回物理上和虚拟上连续的内存。

我编写了一些代码来观察行为,但只有物理内存似乎是连续的,而不是虚拟内存。我有什么错误吗?

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>

MODULE_LICENSE("GPL");

static char *ptr;
int alloc_size = 1024;

module_param(alloc_size, int, 0);

static int test_hello_init(void)
{
    ptr = kmalloc(alloc_size,GFP_ATOMIC);
    if(!ptr) {
        /* handle error */
        pr_err("memory allocation failed\n");
        return -ENOMEM;
    } else {
        pr_info("Memory allocated successfully:%p\t%p\n", ptr, ptr+100);
        pr_info("Physical address:%llx\t %llx\n", virt_to_phys(ptr), virt_to_phys(ptr+100));
    }

    return 0;
}

static void test_hello_exit(void)
{
    kfree(ptr);
    pr_info("Memory freed\n");

}

module_init(test_hello_init);
module_exit(test_hello_exit);

dmesg
输出:

Memory allocated successfully:0000000083318b28  000000001fba1614
Physical address:1d5d09c00   1d5d09c64
c linux memory-management linux-kernel linux-device-driver
1个回答
11
投票

打印内核指针通常是一个坏主意,因为它基本上意味着将内核地址泄漏到用户空间,因此当在

%p
中使用
printk()
(或类似的宏,如
pr_info()
等)时,内核会尝试保护自身并且不打印真实地址。相反,它会打印该地址的不同哈希唯一标识符。

如果您真的想要打印该地址,您可以使用

%px


来自

Documentation/core-api/printk-formats.rst
网页版git):

指针类型

不带说明符扩展打印的指针(即未经修饰的

%p
是 散列以提供唯一标识符,而不会将内核地址泄露给用户 空间。在 64 位机器上,前 32 位被清零。如果你真的 想要地址请看下面
%px

%p    abcdef12 or 00000000abcdef12

然后,下面:

未修改的地址

%px   01234567 or 0123456789abcdef

用于当您确实想要打印地址时打印指针。请 考虑您是否正在泄露有关 使用

%px
打印指针之前内存中的内核布局。
%px
是 功能上等同于
%lx
%px
优于
%lx
,因为它更 独特的 grep'able。如果将来我们需要修改Kernel的方式 处理打印指针,能够找到调用会很高兴 网站。


无论如何,在打印之前转换指针的代码可以在here找到。 Linux 6.6 中的调用链为:

_printk()
vprintk()
vprintk_default()
vprintk_emit()
vprintk_store()
printk_sprint()
 vscnprintf()
vsnprintf()
pointer()
default_pointer()
ptr_to_id()

© www.soinside.com 2019 - 2024. All rights reserved.