函数:__krealloc( )
文件包含:
#include<linux/slab.h>
函数定义:
在内核源码中的位置:linux-3.19.3/mm/slab_common.c
函数定义格式:
void * __krealloc(const void * p, size_t new_size, gfp_t f lags)
函数功能描述:
__krealloc( )函数的功能与krealloc( )函数的功能基本一致,都是重新分配内存,且不改变原地址空间中的内容。
输入参数说明:
p
:是需要重新分配的原内存空间的起始地址。-
new_size
:是重新分配内存所需要的字节数。 -
flags
:是分配模式,其取值及含义可参考关于kmalloc( )函数的分析。
返回参数说明:
返回值为重新分配的内存的起始地址,如果分配不成功则返回NULL。
注:如果参数p为NULL,则__krealloc( )函数的功能与kmalloc( )函数一致,参考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,会出现如图所示的结果。
执行命令rmmod __krealloc.ko卸载模块,执行命令dmesg -c,会出现如图所示的结果。
结果分析:
测试程序中调用了内核函数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( )函数是不同的。
酷客网相关文章:
评论前必须登录!
注册