免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2203 | 回复: 6

[内存管理] linux x86内存分页时,pgd与cr3的疑问 [复制链接]

论坛徽章:
11
摩羯座
日期:2013-09-29 17:39:09白羊座
日期:2014-11-13 09:38:14技术图书徽章
日期:2014-01-17 15:07:36狮子座
日期:2013-12-25 14:01:52技术图书徽章
日期:2013-12-17 11:33:22技术图书徽章
日期:2013-12-03 10:27:57天秤座
日期:2013-11-08 15:47:19申猴
日期:2013-10-29 13:16:32未羊
日期:2013-10-12 22:28:56辰龙
日期:2013-10-09 14:39:5515-16赛季CBA联赛之山东
日期:2016-07-25 10:23:00
发表于 2016-06-06 13:50 |显示全部楼层
请教各位高手

每个进程都有独立的PGD,保存在当前进程的内存描述符mm_struct的pgd字段中,而该字段的值是从cr3中加载

但我通过运行以下内核模块,打印cr3与pgd的值时,发现二者并不一致
  1. #include <linux/kernel.h>  
  2. #include <linux/module.h>  
  3. #include <linux/init.h>  
  4. #include <linux/mm.h>  
  5. #include <linux/mm_types.h>  
  6. #include <asm/pgtable.h>  
  7. #include <linux/vmalloc.h>  
  8. #include <linux/sched.h>  

  9. static int __init show_pgd(void)
  10. {
  11.         unsigned long cr3, pgd_entry_index;
  12.         struct mm_struct *mm;
  13.         pgd_t *pgdir, *pgd_entry;
  14.         unsigned long vaddr = 0;
  15.         vaddr = (unsigned long)vmalloc(1000 * sizeof(char));
  16.         if (vaddr == 0) {
  17.                 printk("vmalloc failed..\n");
  18.                 return -1;
  19.         }
  20.         printk("vmalloc_vaddr=0x%lx\n", vaddr);

  21.         cr3 = read_cr3();
  22.         mm = current->mm;
  23.         pgdir = mm->pgd;
  24.         pgd_entry = pgd_offset(current->mm, vaddr);
  25.         pgd_entry_index = pgd_index(vaddr);

  26.         printk("cr3 = 0x%lx\n", cr3);
  27.         printk("pgdir = 0x%lx\n", pgd_val(*pgdir));
  28.         printk("pgd_entry = 0x%lx\n", pgd_val(*pgd_entry));
  29.         printk("pgd_entry_index = %ld\n", pgd_entry_index);

  30.         vfree((void*)vaddr);  

  31.         return 0;
  32. }

  33. static void __exit finish(void)
  34. {
  35.         printk("The module is exit\n");
  36. }

  37. module_init(show_pgd);  
  38. module_exit(finish);  
  39. MODULE_LICENSE("GPL");
复制代码
make并insmod,dmesg查看结果
  1. vmalloc_vaddr=0xffffc90009852000
  2. cr3 = 0x36b9a000
  3. pgdir = 0x3a2e1067
  4. pgd_entry = 0x3fad8067
  5. pgd_entry_index = 402
复制代码
PGD的值为0x3a2e1067,而cr3中的值为0x36b9a000

此处不解,请各位指点一下,谢谢。

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
发表于 2016-06-06 19:15 |显示全部楼层
cr3是什么玩意。。。

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
发表于 2016-06-06 19:21 |显示全部楼层

论坛徽章:
11
摩羯座
日期:2013-09-29 17:39:09白羊座
日期:2014-11-13 09:38:14技术图书徽章
日期:2014-01-17 15:07:36狮子座
日期:2013-12-25 14:01:52技术图书徽章
日期:2013-12-17 11:33:22技术图书徽章
日期:2013-12-03 10:27:57天秤座
日期:2013-11-08 15:47:19申猴
日期:2013-10-29 13:16:32未羊
日期:2013-10-12 22:28:56辰龙
日期:2013-10-09 14:39:5515-16赛季CBA联赛之山东
日期:2016-07-25 10:23:00
发表于 2016-06-07 05:26 |显示全部楼层
回复 3# qianguozheng

感谢,但不知道楼上想说什么?
   

论坛徽章:
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
发表于 2016-06-07 14:09 |显示全部楼层
回答不了楼主cr3和pgd不一致问题,但是用vmalloc做测试貌似是有问题的,
vmalloc修改的是init_mm的页表,而不是current->mm。——当然产生一次缺页中断之后就一致了。

论坛徽章:
11
摩羯座
日期:2013-09-29 17:39:09白羊座
日期:2014-11-13 09:38:14技术图书徽章
日期:2014-01-17 15:07:36狮子座
日期:2013-12-25 14:01:52技术图书徽章
日期:2013-12-17 11:33:22技术图书徽章
日期:2013-12-03 10:27:57天秤座
日期:2013-11-08 15:47:19申猴
日期:2013-10-29 13:16:32未羊
日期:2013-10-12 22:28:56辰龙
日期:2013-10-09 14:39:5515-16赛季CBA联赛之山东
日期:2016-07-25 10:23:00
发表于 2016-06-07 15:23 |显示全部楼层
回复 5# nswcfd

感谢楼上,cr3与current->mm->pgd确实是一致的,进程context 切换后,current->mm->pgd相当于二级指针,自身是一个地址,另指向页全局目录PGD的地址
  1. #include <linux/kernel.h>  
  2. #include <linux/module.h>  
  3. #include <linux/init.h>  
  4. #include <linux/mm.h>  
  5. #include <linux/mm_types.h>  
  6. #include <asm/pgtable.h>  
  7. #include <linux/vmalloc.h>  
  8. #include <linux/sched.h>  

  9. static int __init show_pgd(void)
  10. {
  11.         unsigned long cr3, vaddr, pgd_entry_index;
  12.         pgd_t *pgdir, *pgd_entry;
  13.         vaddr = (unsigned long)vmalloc(1000 * sizeof(char));
  14.         if (vaddr == 0) {
  15.                 printk("vmalloc failed..\n");
  16.                 return -1;
  17.         }
  18.         printk("vmalloc_vaddr=0x%lx\n", vaddr);

  19.         cr3 = read_cr3();
  20.         pgdir = current->mm->pgd;
  21.         pgd_entry = pgd_offset(current->mm, vaddr);
  22.         pgd_entry_index = pgd_index(vaddr);

  23.         printk("cr3 = 0x%lx\n", cr3);
  24.         printk("virtual pgd = %p\n", pgdir);
  25.         printk("physical pgd = 0x%lx\n", __pa(pgdir));
  26.         printk("pgd_entry = 0x%lx\n", pgd_val(*pgd_entry));
  27.         printk("pgd_entry_index = %ld\n", pgd_entry_index);

  28.         vfree((void*)vaddr);  

  29.         return 0;
  30. }

  31. static void __exit finish(void)
  32. {
  33.         printk("The module is exit\n");
  34. }

  35. module_init(show_pgd);  
  36. module_exit(finish);  
  37. MODULE_LICENSE("GPL");
复制代码
运行结果为
  1. vmalloc_vaddr=0xffffc90009c2d000
  2. cr3 = 0x38be9000
  3. virtual pgd = ffff880038be9000
  4. physical pgd = 0x38be9000
  5. pgd_entry = 0x3fad8067
  6. pgd_entry_index = 402
复制代码
另请教一下

怎样在kernel module中自行处理page fault,也就是pte不存在时手动分配页帧?

论坛徽章:
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
发表于 2016-06-12 16:43 |显示全部楼层
不是很清楚,或许现有的page fault流程有hook或者notifier可以使用,但不知道是否能够完全替代kernel自身的流程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP