内存分配函数1

  do_mmap_pgoff函数调用结果  2011-04-01 10:40:08

分类: LINUX

unsigned long addr1 = do_mmap_pgoff(NULL,0x1000,0x7000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);
注意如果这个函数不映射文件(第一个参数为NULL),那么必须带有MAP_PRIVATE或者MAP_SHARED标志 否则函数会返回-22 无效的参数。从源码中我们也可以看到。
  1. if (file) {
  2.  989 switch (flags & MAP_TYPE) {
  3.  990 case MAP_SHARED:
  4.  991 if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
  5.  992 return -EACCES;
  6.  993 
  7.  994 /*
  8.  995 * Make sure we don't allow writing to an append-only
  9.  996 * file..
  10.  997 */
  11.  998 if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE))
  12.  999 return -EACCES;
  13. 1000 
  14. 1001 /*
  15. 1002 * Make sure there are no mandatory locks on the file.
  16. 1003 */
  17. 1004 if (locks_verify_locked(inode))
  18. 1005 return -EAGAIN;
  19. 1006 
  20. 1007 vm_flags |= VM_SHARED | VM_MAYSHARE;
  21. 1008 if (!(file->f_mode & FMODE_WRITE))
  22. 1009 vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
  23. 1010 
  24. 1011 /* fall through */
  25. 1012 case MAP_PRIVATE:
  26. 1013 if (!(file->f_mode & FMODE_READ))
  27. 1014 return -EACCES;
  28. 1015 break;
  29. 1016 
  30. 1017 default:
  31. 1018 return -EINVAL;
  32. 1019 }
  33. 1020 } else {
  34. 1021 switch (flags & MAP_TYPE) {
  35. 1022 case MAP_SHARED:
  36. 1023 vm_flags |= VM_SHARED | VM_MAYSHARE;
  37. 1024 break;
  38. 1025 case MAP_PRIVATE:
  39. 1026 /*
  40. 1027 * Set pgoff according to addr for anon_vma.
  41. 1028 */
  42. 1029 pgoff = addr >> PAGE_SHIFT;
  43. 1030 break;
  44. 1031 default:
  45. 1032 return -EINVAL;
  46. 1033 }
  47. 1034 }

default:

        return -EINVAL;

以下四种情况调用这个函数 所得到的结果:

1)找一个低地址区间,此区间还没有被映射。

unsigned long addr1 = do_mmap_pgoff(NULL,0x1000,0x7000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);

模块代码编译执行后,得到的dmesg输出结果为

这个函数被调用前的线性区情况(作为对比):

vm_area_struct:280000 - 281000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:98c1000 - 98e2000
vm_area_struct:b7f57000 - b7f59000
vm_area_struct:bf90f000 - bf924000
VMA nr:14
第一次调用的结果:

vm_area_struct:1000 - 8000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:e58000 - e59000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:9509000 - 952a000
vm_area_struct:b7f9b000 - b7f9d000
vm_area_struct:bfdea000 - bfdff000
VMA nr:15
OK....没有发生任何合并和删除

简单的示意图:(不考虑其余已经存在的线性区,在我们的例子中是已经存在了14个VMA)

2)在映射的区间上执行do_mmap_pgoff函数但是新区间的标志以原来的区间不同,不能进行合并

        unsigned long addr1 = do_mmap_pgoff(NULL,0x1000,0x7000, PROT_WRITE,MAP_FIXED|MAP_SHARED,0);
        unsigned long addr = do_mmap_pgoff(NULL,0x8000,0x2000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);

vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:657000 - 658000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:898a000 - 89ab000
vm_area_struct:b7f55000 - b7f57000
vm_area_struct:bfa76000 - bfa8b000
VMA nr:14
vm_area_struct:1000 - 8000
vm_area_struct:8000 - a000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:657000 - 658000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:898a000 - 89ab000
vm_area_struct:b7f55000 - b7f57000
vm_area_struct:bfa76000 - bfa8b000
VMA nr:16
3)新区间的标志以新区间之前的区间标志相同,能进行合并

        unsigned long addr1 = do_mmap_pgoff(NULL,0x1000,0x7000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);
        unsigned long addr = do_mmap_pgoff(NULL,0x8000,0x2000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);
这种情况有一点需要注意:匿名共享的线性区(MAP_SHARED)是不允许合并的;

vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:b24000 - b25000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:9537000 - 9558000
vm_area_struct:b7fd0000 - b7fd2000
vm_area_struct:bfab7000 - bfacc000
VMA nr:14
vm_area_struct:1000 - a000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000

 


vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:b24000 - b25000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:9537000 - 9558000
vm_area_struct:b7fd0000 - b7fd2000
vm_area_struct:bfab7000 - bfacc000
VMA nr:15
4)新的线性区在一个已有的线性区中间 切标志与前后的线性区都不同。不能进行合并。

        unsigned long addr1 = do_mmap_pgoff(NULL,0x1000,0x9000, PROT_WRITE,MAP_FIXED|MAP_PRIVATE,0);
        unsigned long addr = do_mmap_pgoff(NULL,0x2000,0x1000, PROT_WRITE,MAP_FIXED|MAP_SHARED,0);

vm_area_struct:435000 - 436000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:86bb000 - 86dc000
vm_area_struct:b7f5c000 - b7f5e000
vm_area_struct:bf822000 - bf837000
VMA nr:14
vm_area_struct:1000 - 2000
vm_area_struct:2000 - 3000
vm_area_struct:3000 - a000
vm_area_struct:435000 - 436000
vm_area_struct:469000 - 483000
vm_area_struct:483000 - 484000
vm_area_struct:484000 - 485000
vm_area_struct:487000 - 5c6000
vm_area_struct:5c6000 - 5c7000
vm_area_struct:5c7000 - 5c9000
vm_area_struct:5c9000 - 5ca000
vm_area_struct:5ca000 - 5cd000
vm_area_struct:8048000 - 8049000
vm_area_struct:8049000 - 804b000
vm_area_struct:86bb000 - 86dc000
vm_area_struct:b7f5c000 - b7f5e000
vm_area_struct:bf822000 - bf837000
VMA nr:17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值