alloc_页面返回值的使用

alloc_页面返回值的使用,c,linux,memory-management,linux-kernel,kernel-module,C,Linux,Memory Management,Linux Kernel,Kernel Module,我想知道alloc_page的返回值的用法,它分配page并返回struct page的实例来表示保留块的开始。然而,我不知道如何使用分配后的保留页面。我很难理解这些东西,kmalloc非常简单,例如,我们可以将内存分配到char*buf中,但是这个内核函数返回一个结构,我不知道如何根据需要使用它 #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> struct

我想知道
alloc_page
的返回值的用法,它分配page并返回
struct page
的实例来表示保留块的开始。然而,我不知道如何使用分配后的保留页面。我很难理解这些东西,
kmalloc
非常简单,例如,我们可以将内存分配到
char*buf
中,但是这个内核函数返回一个结构,我不知道如何根据需要使用它

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>

struct page *p;

static int __init sys_module_init(void)
{
    p = alloc_page(GFP_KERNEL);

    pr_info(KBUILD_MODNAME ": Hello, World!\n");
    return 0;
}

static void __exit sys_module_exit(void)
{
    __free_page(p);
    
    pr_info(KBUILD_MODNAME ": Bye, World!\n");
}

module_init(sys_module_init);
module_exit(sys_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("StackOverflow");
#包括
#包括
#包括
结构页*p;
静态整数初始化系统模块初始化(无效)
{
p=alloc_页面(GFP_内核);
pr_info(KBUILD_MODNAME):你好,世界!\n);
返回0;
}
静态无效\退出系统\模块\退出(无效)
{
__免费网页(p);
pr_info(KBUILD_MODNAME):再见,世界!\n);
}
模块初始化(系统模块初始化);
模块退出(系统模块退出);
模块许可证(“GPL”);
模块_作者(“StackOverflow”);

alloc\u page()
的级别低于
kmalloc()
。如果
struct页面
来自用户空间程序,则需要首先使用
kmap()
将其映射到内核地址空间。但是,由于您正在使用
GFP\u内核
分配内核内存,因此您只需获取页面结构,然后使用
page\u address()
将其转换为虚拟地址即可。然后,您可以在类似
memcpy()
的函数中使用地址向其写入数据。我相信还有其他方法可以从页面中进行写/读操作,包括将内存强制转换为不同的类型,但是您可能需要自己进行内存管理。这一切都取决于您对页面的具体操作。

好的,谢谢。有一件事我不明白,为什么
alloc\u page
会返回一个结构,如果我们对它毫无用处的话?为什么不直接返回内存地址呢?内核中的不同用途。有时您需要
struct页面
,以便可以修改结构中的标志,有时您需要地址,这就是
kmalloc
存在的基本原因。这是一种更简单的方法,用更少的低级工作来设置内存。非常感谢你,伙计,我现在明白了很多。太好了!不客气。如果这个或任何答案已经解决了你的问题,请考虑通过点击复选标记接受它。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。然而,没有义务这样做。