提问人:md.jamal 提问时间:9/2/2019 最后编辑:John Kugelmanmd.jamal 更新时间:11/7/2023 访问量:560
kmalloc 分配实际上不是连续的吗?
Is kmalloc allocation not virtually contiguous?
问:
我发现它返回了物理和几乎连续的记忆。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
答:
打印内核指针通常是一个坏主意,因为它基本上意味着将内核地址泄漏到用户空间,因此当使用 in(或类似的宏等)时,内核会尝试保护自己,并且不会打印真实地址。相反,它会为该地址打印不同的哈希唯一标识符。%p
printk()
pr_info()
如果确实要打印该地址,可以使用 。%px
来自(网络版,git):Documentation/core-api/printk-formats.rst
指针类型
打印时不带说明符扩展名(即朴素)的指针是 哈希处理以在不向用户泄露内核地址的情况下提供唯一标识符 空间。在 64 位计算机上,前 32 位为零。如果您真的想要地址,请参见下文。
%p
%px
%p abcdef12 or 00000000abcdef12
然后,稍后如下:
未修改的地址
%px 01234567 or 0123456789abcdef
当您真正想要打印地址时,用于打印指针。请 考虑您是否泄露了有关 在使用 打印指针之前在内存中进行内核布局。 是 在功能上等同于 。 是首选,因为它更 独特的 grep'able。如果将来我们需要修改内核的方式 处理打印指针 能够找到呼叫会很好 网站。
%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
()
”。 %p
评论