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

Posted

技术标签:

【中文标题】kmalloc 分配实际上不是连续的吗?【英文标题】:Is kmalloc allocation not virtually contiguous? 【发布时间】:2020-01-05 13:06:15 【问题描述】:

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

【问题讨论】:

我不完全确定这是否是你的问题,但在我探索 linux 内核的过程中,我发现使用 printk 方法的格式说明符 %p 返回了错误的地址。您确定带有 %p 说明符的 pr_info 返回有效的指针地址吗?我的解决方法是将地址转换为 unsigned long long 并使用 %llx。也许试试看? 【参考方案1】:

打印内核指针通常不是一个好主意,因为它基本上意味着将内核地址泄漏到用户空间,所以当在printk() 中使用%p(或类似pr_info() 等的宏)时,内核会尝试保护自己,不打印真实地址。相反,它会为该地址打印一个不同的散列唯一标识符。

如果你真的想打印那个地址,你可以使用%px


来自How to get printk format specifiers right (web) 或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 的方式 处理打印指针很高兴能够找到调用 网站。

【讨论】:

在 Linux 源代码中它存在于 Documentation/core-api/printk-formats.rst 文件中 Marco,在网络上它有更好的视图:kernel.org/doc/html/latest/core-api/printk-formats.html @0andriy 是的,确实这样更好,谢谢。

以上是关于kmalloc 分配实际上不是连续的吗?的主要内容,如果未能解决你的问题,请参考以下文章

KMALLOC 大小分配

linux内存池能分配连续物理内存吗

RK3399平台开发系列讲解(内存篇)18.3kmalloc

驱动基础之分配内存

Linux-3.14.12内存管理笔记kmalloc与kfree实现

一个类的内存布局是连续的吗?