Linux内核API __get_free_pages

__get_free_pages函数功能描述:__get_free_pages( )函数以gfp_mask分配方式分配2的order次方(1<<order)个连续的物理页。该函数的实现主要是调用了alloc_pages( )函数(参考alloc_pages( )函数的分析),它返回所分配的连续物理页中第一个页的逻辑地址。

__get_free_pages文件包含

#include<linux/gfp.h>

__get_free_pages函数定义

在内核源码中的位置:linux-3.19.3/mm/page_alloc.c

函数定义格式:

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

__get_free_pages输入参数说明

  • gfp_mask:是分配标志,它提供了多种分配内存的方式,指示内核如何分配和在哪分配所需的内存,其中分配标志(gfp_mask)的常见取值及其所表示的含义参考函数alloc_pages( )的分析。
  • order:指要释放的物理页数,其取值为2的order次方个。

__get_free_pages返回参数说明

__get_free_pages( )函数返回所分配的连续物理页中第一个页的逻辑地址,如果分配失败的话,则返回0。

__get_free_pages实例解析

编写测试文件:__get_free_pages.c

头文件及全局变量声明如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/gfp.h>
MODULE_LICENSE("GPL");
static int __init __get_free_pages_init(void);
static void __exit __get_free_pages_exit(void);
unsigned long addr = 0;

模块初始化函数:

int __init __get_free_pages_init(void)
{
    addr = __get_free_pages( GFP_KERNEL, 3 );  //分配8个物理页

    if(! addr)
    {
        return -ENOMEM;
    }
    else
        printk("__get_free_pages Successfully! , \naddr = 0x%lx\n", addr);

    return 0;
}

模块退出函数:

void __exit __get_free_pages_exit(void)
{
    if(addr)
    {
        free_pages(addr,3);                    //释放所分配的物理页
        printk("free_pages ok! \n");
    }
    printk("exit! \n");
}

模块初始化及退出函数调用:

module_init(__get_free_pages_init);
module_exit(__get_free_pages_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod __get_free_pages.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。

Linux内核API __get_free_pages

执行命令rmmod __get_free_pages.ko卸载模块,执行命令dmesg -c,会出现如图所示的结果。

Linux内核API __get_free_pages

结果分析:

在测试程序中调用内核函数__get_free_pages( ),分配2的3次方即8个连续物理页面,由addr接收该函数返回的第一个页面的逻辑地址。由输出信息可知该地址为0xffff880124470000。

在模块退出时调用free_pages( )函数释放起始地址为0xffff880124470000的8个页面,参考关于该函数的分析。

赞(0)
未经允许不得转载:极客笔记 » Linux内核API __get_free_pages
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址