linux内核API----内存管理(-)

来源:互联网 发布:中国电影进出口数据 编辑:程序博客网 时间:2024/06/01 11:33

1.  __free_pages()

  所在头文件: #include <linux/gfp.h>

  函数实现位置: mm/page_alloc.c

  函数定义: void __free_pages(struct page *page, unsigned int order);

  功能: __free_pages()函数用来释放页面块,该函数从给定的页面page开始,释放的页面块格式为 1<<order 个。

  参数:

    page: page结构体指针,指向呆释放的物理页中的第一个页结构体。

    order: 指要释放的物理页数,其取值为2的order次方。


2.  __get_free_pages()

  所在头文件: #include <linux/gfp.h>

  函数实现位置: mm/page_alloc.c

  函数定义: unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);

  功能: __get_free_pages()函数用于以gfp_mask分配方式分配2的order次方个连续的物理页。它返回所分配的连续物理页中第一个页的虚拟地址。

  参数:

    gfp_mask: 是分配标志,它提供了多种分配内存的方式,指示内核如何分配以及在哪里分配所需的内存。

      gfp_t类型的标记用于控制申请内存时的内存分配方式和分配行为, 此标记有两类,一类是不带下划线的,一类是带双下划线的。

        不带双下划线前缀的GFP标志:

           GFP_ATOMIC: 用来从中断上下文和进程上下文之外的其他代码中分配内存,从不睡眠。

           GFP_KERNEL: 内核内存的正常分配方式,它可能睡眠。

           GFP_USER: 用来为用户空间分配内存,可能睡眠。

           GFP_HIGHUSER: 和GPF_USER有相同的属性,但如果有高端内存,就从高端内存分配。

           带双下划线前缀的GFP标志:

            __GFP_DMA: 要求分配可用于DMA的内存。

             __GFP_HIGHMEM: 分配的内存可以位于高端内存。

             __GFP_COLD: 正常地分配器尽力地返回“缓冲热(可能在处理器缓冲中找到的页)”的页;而这个标志请求返回一个“冷(一段时间内没有使用的页)”页。

             __GFP_NOWARN: 当一个分配无法满足时,阻止内核发出警告。

             __GFP_HIGH: 高优先级请求,允许为紧急状况消耗被内核保留的最后一页内存页。

             __GFP_REPEAT: 分配器满足一个分配有困难时,努力再尝试一次,仍有可能失败。

             __GFP_NOFAIL:分配器满足一个分配有困难时, 告诉分配器尽最大努力来满足要求,始终不返回失败。

             __GFP_NORETRY: 分配器满足一个分配有困难时, 告知分配器如果无法满足请求,立即返回。

      order: 指要释放的物理页数,其取值为2的order次方。

  返回值:

       __get_free_pages()函数返回所分配的连续物理页中第一个页的逻辑地址,如果分配失败的话,则返回0.


例子:

#include <linux/init.h>#include <linux/module.h>#include <linux/gfp.h>MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Text for __get_free_pages() API");MODULE_AUTHOR("rony <tclrony@163.com>");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 pages allocatedif (!addr) {printk(KERN_ERR "error for __get_free_page()\n");return -ENOMEM;} else {printk(KERN_INFO "__get_free_pages() Successfully!, addr = 0x%lx\n", addr);}return 0;}void __exit __get_free_pages_exit(void){if (addr) {free_pages(addr, 3);//__free_pages(virt_to_page((void *)addr), 3);printk(KERN_INFO "free_pages ok!\n");}printk(KERN_INFO "exit!\n");}module_init(__get_free_pages_init);module_exit(__get_free_pages_exit);


Makefile内容:

obj-m := get_free_pages.o

get_free_pages-objs := __get_free_pages.o


编译方法:

    当前目录下运行如下命令:

             make -C /lib/modules/$(kernel-version)/build M=`pwd`


编译结果:

             生成的文件其中包括get_free_pages.ko


运行:

          加载模块:sudo insmod get_free_pages.ko

          卸载模块: sudo rmmod get_free_pages.ko

          察看运行log: dmesg        

0 0