内存管理-2---分配内存常用函数(按页分配)

Makefile

  1 LINUX_SRC :=/home/liuye/tiny4412/FriendlyARM_kernel/linux-3.5
  2 #obj-m  += module.o            #生成module.ko   但我们写module.o就可以
  3 #module-objs=param.o     #这里写要编译文件
  4 obj-m +=mmc.o       #这是单文件的编译:上面两行是多文件的编译,更加方便
  5 
  6 all:
  7         make -C $(LINUX_SRC) M=`pwd` modules
  8 clean:
  9         make -C $(LINUX_SRC) M=`pwd` modules clean

mmc.c

 Makefile  mmc1.c  mmc.c                                                                                                                                                                                                                                                                                          X
  1 #include <linux/init.h>
  2 #include <linux/sched.h>
  3 #include <linux/module.h>
  4 #include <linux/mm.h>
  5 #include <linux/highmem.h>
  6 //内核代码工作在两种环境下:
  7 //      1/中断上下文  不允许睡眠
  8 //      2/进程上下文    允许睡眠
  9 
 10 /*
 11 内核中存放很多个page结构体都是连续的:page+1就是下一个page的地址
 12 page
 13 page
 14 page
 15 page
 16 page
 17 page
 18 */
 19 
 20 static __init int test_init(void)
 21 {
 22         //申请大内存
 23         struct page *pages,*page_4k;
 24         char *v;
 25         //GFP_KERNEL:再分配内存的时候允许睡眠
 26         //GFP_ATOMIC:再分配内存的时候不允许睡眠
 27         //申请2^n此方个page
 28         //方式1 申请2个页
 29         pages = alloc_pages(GFP_KERNEL,1);
 30         //获取申请的物理内存的虚拟地址
 31         v = page_address(pages);
 32         //使用
 33         memcpy(v,"111111",6);
 34         printk("v1=%s
",v);
 35         printk("v1=%x
",v);
 36         //释放内存
 37         __free_pages(pages,1);
 38 
 39         //方式2 只是申请一个页4k
 40         page_4k = alloc_page(GFP_KERNEL);
 41         v = page_address(page_4k);
 42         memcpy(v,"222222",6);
 43         printk("v2=%s
",v);
 44         printk("v2=%x
",v);
 45         __free_pages(page_4k,0);
 46 
 47         //方式3 申请2个页
 48         v = (void*)__get_free_pages(GFP_KERNEL,1);
 49         memcpy(v,"333333",6);
 50         printk("v3=%s
",v);
 51         printk("v3=%x
",v);
 52         free_pages((unsigned long)v,1);
 53 
 54         //方式4 下面只申请一个页
 55         //__GFP_HIGH :在高端内存申请
 56         pages = alloc_page(__GFP_HIGH);
 57         //永久映射:会睡眠:所以这个方法只能在进程上下文使用
 58         v = kmap(pages);
 59         memcpy(v,"444444",6);
 60         printk("v4=%s
",v);
 61         printk("v4=%x
",v);
 62         //高端内存需要自己解除映射,normal内存是内核自己映射的,不需要我们来解除映射
 63         kunmap(pages);
 64         __free_page(pages);
 65 
 66         //方式5 临时映射:用完之后赶快释放,因为是环形缓存,有可能被覆盖掉
 67         pages = alloc_page(__GFP_HIGH);
 68         //不会睡眠:所以这个方法可以在中断上下文使用
 69         //临时映射:速度快,用完之后赶快释放,因为是环形缓存,有可能被覆盖掉
 70         v = kmap_atomic(pages);
 71         memcpy(v,"555555",6);
 72         printk("v5=%s
",v);
 73         printk("v5=%x
",v);
 74         //高端内存需要自己解除映射,normal内存是内核自己映射的,不需要我们来解除映射
 75         __kunmap_atomic(v);
 76         __free_page(pages);
 77 
 78         printk("mmc init!
");
 79         return 0;
 80 }
 81 static __exit void test_exit(void)
 82 {
 83         printk("mmc exit!
");
 84 }
 85 
 86 module_init(test_init);
 87 module_exit(test_exit);
 88 MODULE_LICENSE("GPL");
 89 

board:

root@board liuye_dir#insmod mmc.ko 
[  165.700000] v1=111111
[  165.700000] v1=ec44e000
[  165.705000] v2=222222
[  165.705000] v2=ecbcf000
[  165.705000] v3=333333
[  165.705000] v3=ec44e000
[  165.705000] v4=444444
[  165.705000] v4=ecbcf000
[  165.705000] v5=555555
[  165.705000] v5=ecbcf000
[  165.705000] mmc init!
root@board liuye_dir#rmmod mmc.ko 
[  167.770000] mmc exit!
root@board liuye_dir#
有时候,不小心知道了一些事,才发现自己所在乎的事是那么可笑。
原文地址:https://www.cnblogs.com/axjlxy/p/8971201.html