Linux内核API get_zeroed_page

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,会出现如图所示的结果。

Linux内核API get_zeroed_page

结果分析:

该测试文件调用get_zeroed_page( )函数以gft_mask分配标志分配一个物理页,并测试该页内容为零。由输出结果可知,该页的逻辑起始地址为0xffff8800a38ce000。再通过输出该页任一偏移处的内容(这里以地址偏移2和500举例)可知由get_zeroed_page( )函数获取的页内容为零。最后模块退出时调用内核函数free_pages( )释放所获取的物理页,参考极客笔记网中该函数的分析。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程