免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4072 | 回复: 10
打印 上一主题 下一主题

[内存管理] 虚拟内存与物理内存的映射问题 [复制链接]

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-06 23:09 |只看该作者 |倒序浏览
在一个32位系统上,假如只有128M的物理内存,因为是低端内存,会与虚拟地址一一映射。
如果使用vmalloc()申请内存时,占用了页帧号为262144(对应1M位置)的一个page,由于该page同时对应于虚拟地址3G+1M=0xC0100000,
那么如果我操作该地址会发生什么问题呢?

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
2 [报告]
发表于 2015-07-07 20:04 |只看该作者
一个物理地址被多个虚拟地址映射着,感觉没有什么问题。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
3 [报告]
发表于 2015-07-07 20:30 |只看该作者
回复 2# nswcfd


    后来想了一下,实际应用中不会出现这种情况,既然通过vmalloc占用了该page,那么我后面再申请内存的时候,就不会再次申请到该页。
如果强行对__va(page_address(page))进行操作的话,应该会出现异常。
你怎么看?

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
4 [报告]
发表于 2015-07-07 21:06 |只看该作者
题外话,vmalloc返回虚地址,不去反查vmalloc list的话,怎么得到是哪个page呀?(确切的说是哪些pages)

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
5 [报告]
发表于 2015-07-07 21:10 |只看该作者
回复 4# nswcfd

我这里使用__va(page_address(page))想表达的意思,仅仅是操作已经被占用的一个page,而不是想通过查询vmalloc的链表找到一个page,再使用page得到一个虚拟地址。
对于低端内存是一一映射的,所以__va()得到的地址,与vmalloc得到的地址肯定是不同的,但是对应同一个物理page。
   

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
6 [报告]
发表于 2015-07-07 21:26 |只看该作者
本帖最后由 nswcfd 于 2015-07-07 21:27 编辑
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/vmalloc.h>
  4. #include <linux/err.h>
  5. void *va;
  6. int init(void)
  7. {
  8.         va = vmalloc(32);
  9.         printk("va=%p pa=%lx va2=%lx\n", va, __pa(va), __pa(va)+PAGE_OFFSET);
  10.         if (!va || IS_ERR(va))
  11.                 return -ENOMEM;
  12.         *(long *)va = jiffies;
  13.         *((long *)va + 1) = 0xfacebead;
  14.         return 0;
  15. }
  16. void fini(void)
  17. {
  18.         vfree(va);
  19. }
  20. module_init(init);
  21. module_exit(fini);
  22. MODULE_LICENSE("GPL");
复制代码
crash> log | tail -n 1
va=ffffc2000001a000 pa=41000001a000 va2=ffffc2000001a000

crash> p va
va = $7 = (void *) 0xffffc2000001a000 #跟log的输出吻合

crash> rd 0xffffc2000001a000 2  #以va访问内容
ffffc2000001a000:  0000000104ded138 00000000facebead   8............... #跟程序逻辑一致

crash> kmem -v 0xffffc2000001a000
   VM_STRUCT                 ADDRESS RANGE               SIZE
ffff81003a6cf280  ffffc2000001a000 - ffffc2000001c000    8192  #得到vm_struct的地址  ffff81003a6cf280

crash> * vm_struct.addr,pages,nr_pages ffff81003a6cf280
  addr = 0xffffc2000001a000
  pages = 0xffff81003fd06e60        # struct page **pages
  nr_pages = 1

crash> rd 0xffff81003fd06e60
ffff81003fd06e60:  ffff81000506d838                    8.......        #费了半天功夫就是为了得到page*

crash> * -x page.index ffff81000506d838
  index = 0x3e16                #pfn是0x3e16

crash> kmem ffff81000506d838
      PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
ffff81000506d838 29f01000                0     3e16  1 28080000000000        #得到page的物理地址

crash> ptov 29f01000
VIRTUAL           PHYSICAL        
ffff810029f01000  29f01000        #物理地址+PAGE_OFFSET

crash> rd ffff810029f01000 2
ffff810029f01000:  0000000104ded138 00000000facebead   8...............        #内容跟前面是一样的

#最后对比输出一下
crash> rd 0xffffc2000001a000 2
ffffc2000001a000:  0000000104ded138 00000000facebead   8...............
crash> rd 0xffff810029f01000 2
ffff810029f01000:  0000000104ded138 00000000facebead   8...............

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
7 [报告]
发表于 2015-07-08 22:35 |只看该作者
回复 6# nswcfd

好强大,我得慢慢消化一下。
谢谢。


   

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
8 [报告]
发表于 2015-07-09 22:10 |只看该作者
回复 6# nswcfd


从你做的实验来看,通过直接地址再去访问,内核应该不会发生异常。

非常感谢你的回答。   

论坛徽章:
0
9 [报告]
发表于 2015-08-17 21:05 |只看该作者
linux跳过第一个MB,如果这1M处的页框是内核用到的,那么就会被置为保留,所以也就不会被伙伴系统回收,因此你vmalloc也申请不到此页

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-08-19 06:20:002015亚冠之本尤德科
日期:2015-08-31 23:24:47
10 [报告]
发表于 2015-08-17 21:50 |只看该作者
回复 9# 梦中的人在做梦

哥们,那只是随便举了个例子
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP