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

r8xiu3jd  于 2023-11-17  发布在  Linux
关注(0)|答案(1)|浏览(113)

我发现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

1tu0hz3e

1tu0hz3e1#

打印内核指针通常是一个坏主意,因为它基本上意味着将内核地址泄漏到用户空间,所以当在printk()中使用%p(或类似的宏,如pr_info()等)时,内核试图保护自己,不打印真实的地址。相反,它为该地址打印不同的哈希唯一标识符。
如果你真的想打印这个地址,你可以使用%px
Documentation/core-api/printk-formats.rstweb versiongit)开始:

指针类型

没有指定扩展名的指针(即未修饰的%p被哈希以给予一个唯一的标识符,而不会将内核地址泄漏到用户空间。在64位机器上,前32位被归零。如果你真的需要地址,请参阅下面的%px

%p    abcdef12 or 00000000abcdef12

字符串
然后,下面稍后:

未修改的配置文件

%px   01234567 or 0123456789abcdef


当你真的想打印地址时打印指针。在使用%px打印指针之前,请考虑你是否泄露了内存中内核布局的敏感信息。%px在功能上等同于%lx%px%lx更好,因为它更独特。如果将来,我们需要修改内核处理打印指针的方式,如果能够找到调用点就好了。
在Linux 6.6中的调用链是:_printk()vprintk()vprintk_default()vprintk_emit()vprintk_store()printk_sprint()vscnprintf()vsnprintf()pointer()default_pointer()ptr_to_id()

相关问题