Linux内核API __krealloc

__krealloc函数功能描述:__krealloc( )函数的功能与krealloc( )函数的功能基本一致,都是重新分配内存,且不改变原地址空间中的内容。

__krealloc文件包含

#include<linux/slab.h>

__krealloc函数定义

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

函数定义格式:

void * __krealloc(const void * p, size_t new_size, gfp_t f lags)

__krealloc输入参数说明

  • p:是需要重新分配的原内存空间的起始地址。
  • new_size:是重新分配内存所需要的字节数。
  • flags:是分配模式,其取值及含义可参考关于kmalloc( )函数的分析。

__krealloc返回参数说明

返回值为重新分配的内存的起始地址,如果分配不成功则返回NULL。

注:如果参数p为NULL,则__krealloc( )函数的功能与kmalloc( )函数一致,参考krealloc( )函数的分析。

__krealloc实例解析

编写测试文件:__krealloc.c

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

#include <linux/string.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init __krealloc_init(void);
static void __exit __krealloc_exit(void);
struct page * pages = NULL;
#define new_size   26

模块初始化函数:

int __init __krealloc_init(void)
{
    pages = alloc_pages( GFP_KERNEL, 0 ); //分配一个物理页,pages为指向该页的指针
    if(! pages)
    {
        printk("alloc failed! \n");
        return -ENOMEM;
    }
    else
    {
        char * temp = (char *)pages;
        char x;
        *temp = 'a';
        int i = 0;
        for(; i < new_size; i ++)           //为分配的页前new_size个字节进行赋值
        {
            x = *temp;
            temp ++;
            *temp = x+1;
        }

        // 调用函数,重新分配内pages为起始地址的前new_size个字节的内容不改变
        char * addr = __krealloc( pages, new_size, GFP_KERNEL);
        printk("addr = 0x%lx\n", (unsigned long)addr);        //输出所拷贝的目标起始地址
        printk("*addr = %c\n", *addr);                      //输出第一个字符
        printk("*addr+4 = %c\n", *(addr+4));                //输出第五个字符

        i = 0 ; temp = addr;
        for(; i < new_size; i ++, temp ++)                    //输出新内存中的内容
            printk("%c", *temp);
    }
    return 0;
}

模块退出函数:

void __exit __krealloc_exit(void)
{
    if(pages)
    {
        __free_pages(pages,0);             //释放由alloc_pages( )所分配的页。
        printk("\n__free_pages succeed! \n");
    }
    printk("exit ok! \n");
}

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

module_init(__krealloc_init);
module_exit(__krealloc_exit);

实例运行结果及分析:

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

Linux内核API __krealloc

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

Linux内核API __krealloc

结果分析:

测试程序中调用了内核函数alloc_pages( )和__free_pages( )进行分配和释放页的操作,其具体功能参考本教程中关于它们的分析。

在本测试程序中,首先分配一个物理页作为原内存空间,然后将其new_size字节(这里取new_size为26)空间填充字符值,填充完后依次为abcd…xyz。之后调用__krealloc( )函数,参数值依次为pages、new_size、GFP_KERNEL,由字符型指针addr接收返回值。输出addr的值以及addr、addr+4的内容进行测试,输出信息中下面部分为一些警告信息。由输出信息可知addr = 0xffff8800a447500; *addr = a; *(addr + 4) = e;最后再输出新内存空间new_size字节的内容(这里通过循环实现),输出值为abcd…xyz,这也说明重新分配内存空间后保留了原地址空间的内容。最后由__free_pages( )函数释放原内存空间pages。

__krealloc( )与krealloc( )两个函数实现相同的功能,而二者的差别仅在于__krealloc( )函数不会释放原来的内存空间,即当参数p不为NULL而参数new_size为0时,它也不会释放参数p所指向的内存空间,这一点与krealloc( )函数是不同的。

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

评论 抢沙发

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