Chinaunix首页 | 论坛 | 博客
  • 博客访问: 105272
  • 博文数量: 17
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 184
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-20 11:19
个人简介

学习内核中~

文章分类

全部博文(17)

文章存档

2013年(17)

我的朋友

分类: LINUX

2013-06-22 18:14:10

通过下面的程序来测试各种内核内存分配函数的不同。

点击(此处)折叠或打开

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/types.h>
  4. #include <linux/slab.h>
  5. #include <linux/gfp.h>
  6. #include <linux/mm.h>
  7. MODULE_LICENSE("Dual BSD/GPL");

  8. void *k_DMA = NULL, *k_KERN = NULL, *k_HM = NULL,
  9.     *gfp_DMA = NULL, *gfp_KERN = NULL, *gfp_HM = NULL,
  10.     *v = NULL;
  11. struct page *ap_DMA = NULL, *ap_KERN = NULL, *ap_HM = NULL;

  12. static int main_init(void)
  13. {
  14.     k_DMA = kmalloc(4096, GFP_KERNEL | __GFP_DMA);
  15.     k_KERN = kmalloc(4096, GFP_KERNEL);
  16.     k_HM = kmalloc(4096, GFP_KERNEL | __GFP_HIGHMEM);
  17.         printk(KERN_INFO "kmalloc(DMA) address is 0x%x\n", k_DMA);
  18.     printk(KERN_INFO "kmalloc(KERN) address is 0x%x\n", k_KERN);
  19.     printk(KERN_INFO "kmalloc(HM) address is 0x%x\n", k_HM);

  20.     
  21.         gfp_DMA = __get_free_pages(GFP_KERNEL | __GFP_DMA, 1);
  22.     gfp_KERN = __get_free_pages(GFP_KERNEL, 1);
  23.     // oops!
  24.     //gfp_HM = __get_free_pages(GFP_KERNEL | __GFP_HIGHMEM, 1);
  25.     printk(KERN_INFO "get_free_pages(DMA) address is 0x%x\n", gfp_DMA);
  26.     printk(KERN_INFO "get_free_pages(KERN) address is 0x%x\n", gfp_KERN);
  27.     
  28.     ap_DMA = alloc_pages(GFP_KERNEL | __GFP_DMA, 1);
  29.     ap_KERN = alloc_pages(GFP_KERNEL, 1);
  30.     ap_HM = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 1);
  31.     printk(KERN_INFO "alloc_pages(DMA) address is 0x%x\n", page_address(ap_DMA));
  32.     printk(KERN_INFO "alloc_pages(KERN) address is 0x%x\n", page_address(ap_KERN));
  33.     printk(KERN_INFO "alloc_pages(HM) address is 0x%x\n", page_address(ap_HM));
  34.     
  35.     v = vmalloc(PAGE_SIZE);
  36.     printk(KERN_INFO "vmallo address is 0x%x\n", v);
  37.     
  38.     return 0;
  39. }

  40. static void main_exit(void)
  41. {
  42.     vfree(v);
  43.     __free_pages(ap_HM, 1);
  44.     __free_pages(ap_KERN, 1);
  45.     __free_pages(ap_DMA, 1);
  46.     free_pages(gfp_KERN, 1);
  47.     free_pages(gfp_DMA, 1);
  48.     kfree(k_HM);
  49.     kfree(k_KERN);
  50.     kfree(k_DMA);
  51. }

  52. module_init(main_init);
  53. module_exit(main_exit);
程序的输出为:
[  122.429134] kmalloc(DMA) address is 0xc0e08000
[  122.429143] kmalloc(KERN) address is 0xf1570000
[  122.429149] kmalloc(HM) address is 0xf1575000

[  122.429158] get_free_pages(DMA) address is 0xc0e02000
[  122.429163] get_free_pages(KERN) address is 0xef37e000

[  122.429173] alloc_pages(DMA) address is 0xc0e04000
[  122.429178] alloc_pages(KERN) address is 0xef160000
[  122.429184] alloc_pages(HM) address is 0x0

[  122.429194] vmallo address is 0xf7e69000

由程序的输出可以看出,kmalloc不能分配高端内存,get_free_pages也是,并且后者如果指定了__GFP_HIGHMEM标志还会产生oops。
alloc_pages可以分配高端内存,当分配的内存页位于高端内存时,page_address函数就无法获得这个内存页的逻辑地址了(page_address实际上是返回page结构的virtual域),因为内存页和内核地址空间不是简单的线性关系了。
kmalloc,get_free_pages和alloc_pages返回的都是连续的物理空间。

vmalloc分配的内存的虚拟地址位于内核地址空间的高128M。
get_free_pages和alloc_pages的分配结果会反映在/proc/buddyinfo文件中。
阅读(2587) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~