__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,会出现如图所示的结果。
执行命令rmmod __get_free_pages.ko卸载模块,执行命令dmesg -c,会出现如图所示的结果。
结果分析:
在测试程序中调用内核函数__get_free_pages( ),分配2的3次方即8个连续物理页面,由addr接收该函数返回的第一个页面的逻辑地址。由输出信息可知该地址为0xffff880124470000。
在模块退出时调用free_pages( )函数释放起始地址为0xffff880124470000的8个页面,参考关于该函数的分析。