我发现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
型
1条答案
按热度按时间1tu0hz3e1#
打印内核指针通常是一个坏主意,因为它基本上意味着将内核地址泄漏到用户空间,所以当在
printk()
中使用%p
(或类似的宏,如pr_info()
等)时,内核试图保护自己,不打印真实的地址。相反,它为该地址打印不同的哈希唯一标识符。如果你真的想打印这个地址,你可以使用
%px
。从
Documentation/core-api/printk-formats.rst
(web version,git)开始:指针类型
没有指定扩展名的指针(即未修饰的
%p
)被哈希以给予一个唯一的标识符,而不会将内核地址泄漏到用户空间。在64位机器上,前32位被归零。如果你真的需要地址,请参阅下面的%px
。字符串
然后,下面稍后:
未修改的配置文件
型
当你真的想打印地址时打印指针。在使用
%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()
。