免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: yjcq
打印 上一主题 下一主题

内核虚拟地址转换为物理地址(模拟__pa) [复制链接]

论坛徽章:
0
31 [报告]
发表于 2011-09-27 20:47 |只看该作者
通过虚拟地址访问必然要通过MMU映射得到物理地址,在内核直接映射区域物理地址必然由_pa()能得到。但是内核区域线性地址到物理地址并不一定是要按这种小页面规则的PGD/PUD/PMD...一级一级来填。大一点的连续区间按大一点的区域来映射,那可能就没这么多级了。这个MMU查表也是很灵活的。

论坛徽章:
0
32 [报告]
发表于 2011-09-27 21:39 |只看该作者
通过虚拟地址访问必然要通过MMU映射得到物理地址,在内核直接映射区域物理地址必然由_pa()能得到。但是内核 ...
鸟菜小 发表于 2011-09-27 20:47

即使灵活也是要有设置的,还是无法解释啊

论坛徽章:
0
33 [报告]
发表于 2011-09-27 21:51 |只看该作者
我也做了实验,确实很费解。

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
34 [报告]
发表于 2011-09-28 08:20 |只看该作者
回复 32# tsinhi
其实原因在于:如果你开启了PSE,也就是说开启了大尺寸页。那么在这种情况下,pmd就是最后一级页表了,也就没有pte了。
原来的代码中应该做如下修改:
在计算出pmd后,应该调用函数pmd_large()检查一下,是否是大尺寸页。如果不是,则使用原理的流程;如果是则直接进行计算物理地址。代码如下:
  1. if(!pmd_none(*k_pmd))
  2.                         {
  3.                                 if(!pmd_large(*k_pmd)){
  4.                                         k_pte = pte_offset_kernel(k_pmd, ka);
  5.                                         if(!pte_none(*k_pte))
  6.                                         {
  7.                                                 kpa = (pte_val(*k_pte) & PAGE_MASK) |
  8.                                                         (ka & ~PAGE_MASK);
  9.                                                 if(!pte_present(*k_pte))
  10.                                                         printk(KERN_ALERT "k-page not in RAM\n");
  11.                                         }
  12.                                         else
  13.                                                 printk(KERN_ALERT "pte is none\n");
  14.                                 }else{
  15.                                         printk(KERN_ALERT "Use Large Page. PSE = 1\n");
  16.                                         kpa = (pmd_val(*(k_pmd)) & PMD_MASK) | (ka & ~PMD_MASK);
  17.                                 }
  18.                         }
复制代码

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
35 [报告]
发表于 2011-09-28 08:20 |只看该作者
回复 33# flikelinux
其实原因在于:如果你开启了PSE,也就是说开启了大尺寸页。那么在这种情况下,pmd就是最后一级页表了,也就没有pte了。
原来的代码中应该做如下修改:
在计算出pmd后,应该调用函数pmd_large()检查一下,是否是大尺寸页。如果不是,则使用原理的流程;如果是则直接进行计算物理地址。代码如下:
  1. if(!pmd_none(*k_pmd))
  2.                         {
  3.                                 if(!pmd_large(*k_pmd)){
  4.                                         k_pte = pte_offset_kernel(k_pmd, ka);
  5.                                         if(!pte_none(*k_pte))
  6.                                         {
  7.                                                 kpa = (pte_val(*k_pte) & PAGE_MASK) |
  8.                                                         (ka & ~PAGE_MASK);
  9.                                                 if(!pte_present(*k_pte))
  10.                                                         printk(KERN_ALERT "k-page not in RAM\n");
  11.                                         }
  12.                                         else
  13.                                                 printk(KERN_ALERT "pte is none\n");
  14.                                 }else{
  15.                                         printk(KERN_ALERT "Use Large Page. PSE = 1\n");
  16.                                         kpa = (pmd_val(*(k_pmd)) & PMD_MASK) | (ka & ~PMD_MASK);
  17.                                 }
  18.                         }
复制代码

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
36 [报告]
发表于 2011-09-28 08:21 |只看该作者
回复 25# yjcq
其实原因在于:如果你开启了PSE,也就是说开启了大尺寸页。那么在这种情况下,pmd就是最后一级页表了,也就没有pte了。
原来的代码中应该做如下修改:
在计算出pmd后,应该调用函数pmd_large()检查一下,是否是大尺寸页。如果不是,则使用原理的流程;如果是则直接进行计算物理地址。代码如下:
  1. if(!pmd_none(*k_pmd))
  2.                         {
  3.                                 if(!pmd_large(*k_pmd)){
  4.                                         k_pte = pte_offset_kernel(k_pmd, ka);
  5.                                         if(!pte_none(*k_pte))
  6.                                         {
  7.                                                 kpa = (pte_val(*k_pte) & PAGE_MASK) |
  8.                                                         (ka & ~PAGE_MASK);
  9.                                                 if(!pte_present(*k_pte))
  10.                                                         printk(KERN_ALERT "k-page not in RAM\n");
  11.                                         }
  12.                                         else
  13.                                                 printk(KERN_ALERT "pte is none\n");
  14.                                 }else{
  15.                                         printk(KERN_ALERT "Use Large Page. PSE = 1\n");
  16.                                         kpa = (pmd_val(*(k_pmd)) & PMD_MASK) | (ka & ~PMD_MASK);
  17.                                 }
  18.                         }
复制代码

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
37 [报告]
发表于 2011-09-28 11:40 |只看该作者
回复 27# 瀚海书香


   


为什么您的程序我make之后,产生这个警告阿,然后是:
  1. kernel-lwp@kernel-lwp:~/mm/test$ sudo insmod test.ko
  2. insmod: error inserting 'test.ko': -1 Unknown symbol in module
复制代码

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
38 [报告]
发表于 2011-09-28 13:32 |只看该作者
回复 37# embeddedlwp
你的内核版本高于2.6.25,从2.6.25开始内核常量init_mm将不再export,所以编译的时候提示warning,insert的时候无法添加。
你需要将代码k_pgd = pgd_offset_k(ka) 修改为 k_pgd = pgd_offset(current->mm, ka)就可以了。

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
39 [报告]
发表于 2011-09-28 15:57 |只看该作者
回复 38# 瀚海书香


    init_mm这个问题解决了,但是WARNING: "__phys_addr" [/home/kernel-lwp/mm/test/test.ko] undefined!

    kernel 2.6.38

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
40 [报告]
发表于 2011-09-28 16:35 |只看该作者
回复 39# embeddedlwp
我已经跟你说了第一个的原因了,那么第二个应该自己就可以解决了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP