get_zeroed_page函数功能描述:get_zeroed_page( )函数获取一个物理页,它保证该页不属于高端内存,并将该页的内容清零。
get_zeroed_page文件包含
#include<linux/gfp.h>
get_zeroed_page函数定义
在内核源码中的位置:linux-3.19.3/mm/page_alloc.c
函数定义格式:
unsigned long get_zeroed_page(gfp_t gfp_mask)
get_zeroed_page输入参数说明
gft_mask
:是分配标志,它提供了多种分配内存的方式,指示内核如何分配和在哪分配所需的内存,其常见取值及说明参考alloc_pages( )函数的分析。
get_zeroed_page返回参数说明
返回值是一个无符号长整型,它表示所分配的页的起始地址,该地址是一个逻辑地址。
get_zeroed_page实例解析
编写测试文件:get_zeroed_page.c
头文件及全局变量声明如下:
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init get_zeroed_page_init(void);
static void __exit get_zeroed_page_exit(void);
char * addr;
模块初始化函数:
int __init get_zeroed_page_init(void)
{
addr = (char *)get_zeroed_page(GFP_KERNEL);
if(addr == NULL )
printk("get_zeroed_page failed! \n");
else
{
printk("get_zeroed_page successfully! addr = 0x%lx\n", (unsigned long)addr );
printk("the content of mem_spvm+2 is: %d\n", *(addr+2));
printk("the content of mem_spvm+500 is: %d\n", *(addr+500));
}
return 0;
}
模块退出函数:
void __exit get_zeroed_page_exit(void)
{
if(addr ! = NULL)
{
free_pages((unsigned long)addr , 1); //由于分配一页,这里也释放一页
printk("free_pages ok! \n");
}
printk("exit! \n");
}
模块初始化及退出函数调用:
module_init(get_zeroed_page_init);
module_exit(get_zeroed_page_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod get_zeroed_page.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
该测试文件调用get_zeroed_page( )函数以gft_mask分配标志分配一个物理页,并测试该页内容为零。由输出结果可知,该页的逻辑起始地址为0xffff8800a38ce000。再通过输出该页任一偏移处的内容(这里以地址偏移2和500举例)可知由get_zeroed_page( )函数获取的页内容为零。最后模块退出时调用内核函数free_pages( )释放所获取的物理页,参考极客笔记网中该函数的分析。