免费注册 查看新帖 |

Chinaunix

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

[内存管理] 能否获得物理地址 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-28 09:48 |只看该作者 |倒序浏览
我们在编写代码时,不管是用户空间的还是内核空间的,获得的
都是逻辑地址,我想问:能否获得物理地址?
如果能,怎么做?

论坛徽章:
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
2 [报告]
发表于 2013-10-28 10:29 |只看该作者
回复 1# netdoger
我们在编写代码时,不管是用户空间的还是内核空间的,获得的
都是逻辑地址,我想问:能否获得物理地址?
如果能,怎么做?


You can get the physical address from virtual address in kernel space.

BTW: Why need physical address?

   

论坛徽章:
0
3 [报告]
发表于 2013-10-28 10:34 |只看该作者
内核态有函数转,纯用户态就没法了。

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
4 [报告]
发表于 2013-10-28 10:52 |只看该作者
回复 1# netdoger


   1)如果是内核空间的 可以直接调用__pa()来转换.
   2)如果是用户空间。 必须要通过查找Pte映射才能获得

论坛徽章:
0
5 [报告]
发表于 2013-10-28 15:19 |只看该作者
是这样用吗:
物理地址=__pa(逻辑地址)

论坛徽章:
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
6 [报告]
发表于 2013-10-28 15:48 |只看该作者
本帖最后由 瀚海书香 于 2013-10-28 15:49 编辑

回复 5# netdoger
是这样用吗:
物理地址=__pa(逻辑地址)


Translate userspace virtual address to physical address more complex than kernel mode.

Just follow this:

  1. /*******************************************************************************
  2.   
  3.   Copyright(c) 2008-2012

  4.   This program is free software; you can redistribute it and/or modify it
  5.   under the terms and conditions of the GNU General Public License,
  6.   version 2, as published by the Free Software Foundation.

  7.   This program is distributed in the hope it will be useful, but WITHOUT
  8.   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9.   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  10.   more details.

  11.   You should have received a copy of the GNU General Public License along with
  12.   this program; if not, write to the Free Software Foundation, Inc.,
  13.   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  14.   The full GNU General Public License is included in this distribution in
  15.   the file called "COPYING".

  16.   Version:  0.1

  17.   Date: 2012-04-21 10:25:55 CST

  18.   Contact Information:
  19.   Tony <tingw.liu@gmail.com>
  20.   Home, Qingdao, China.
  21. *******************************************************************************/

  22. #include <linux/module.h>
  23. #include <asm/pgtable.h>
  24. #include <linux/version.h>
  25. #include <asm/page.h>
  26. #include <linux/gfp.h>
  27. #include <linux/page-flags.h>
  28. #include <linux/sched.h>//find_task_by_vpid
  29. #include <linux/mm.h>//find_vma
  30. #include <asm/uaccess.h>
  31. #include <asm/page.h>
  32. #include <asm/e820.h>

  33. #include <asm/pgtable_types.h>

  34. MODULE_LICENSE("GPL");
  35. MODULE_AUTHOR("Tony <tingw.liu@gmail.com>");
  36. MODULE_DESCRIPTION("CONVERT USER VIRTUAL ADDRESS TO PHYADDRESS");
  37. static int pid;
  38. static unsigned long va;
  39. module_param(pid, int, 0644);
  40. module_param(va, ulong, 0644);

  41. static int find_pgd_init(void)
  42. {
  43.         unsigned long pa=0;
  44.         struct task_struct *pcb_tmp=NULL;
  45.         struct page *ppage = NULL;
  46.         unsigned long pfn = 0;
  47.         pgd_t *pgd_tmp = NULL;
  48.         pud_t *pud_tmp = NULL;
  49.         pmd_t *pmd_tmp = NULL;
  50.         pte_t *pte_tmp = NULL;
  51.         printk(KERN_ALERT "PAGE_OFFSET=0x%lx\n", PAGE_OFFSET);
  52.         printk(KERN_ALERT "PGDIR_SHIFT=%d\n", PGDIR_SHIFT);
  53.         printk(KERN_ALERT "PUD_SHIFT=%d\n", PUD_SHIFT);
  54.         printk(KERN_ALERT "PMD_SHIFT=%d\n", PMD_SHIFT);
  55.         printk(KERN_ALERT "PAGE_SHIFT=%d\n", PAGE_SHIFT);
  56.         printk(KERN_ALERT "PTRS_PRE_PGD=%d\n", PTRS_PER_PGD);
  57.         printk(KERN_ALERT "PTRS_PRE_PUD=%d\n", PTRS_PER_PUD);
  58.         printk(KERN_ALERT "PTRS_PRE_PMD=%d\n", PTRS_PER_PMD);
  59.         printk(KERN_ALERT "PTRS_PRE_PTE=%d\n", PTRS_PER_PTE);

  60.         printk(KERN_ALERT "PAGE_MASK=0x%lx\n", PAGE_MASK);
  61.         if (!(pcb_tmp = pid_task(find_vpid(pid), PIDTYPE_PID))) {
  62.                 printk(KERN_ALERT "Can't find the task %d.\n", pid);
  63.                 return -1;
  64.         }
  65.         printk(KERN_ALERT "pgd=0x%p\n", pcb_tmp->mm->pgd);
  66.         if (!find_vma(pcb_tmp->mm, va)) {
  67.                 printk(KERN_ALERT "virt_addr 0x%p not available.\n", va);
  68.                 return -1;
  69.         }
  70.         pgd_tmp = pgd_offset(pcb_tmp->mm, va);
  71.         printk(KERN_ALERT "pgd_tmp=0x%p\n", pgd_tmp);
  72.         printk(KERN_ALERT "pgd_val(*pgd_tmp)=0x%p\n", pgd_val(*pgd_tmp));
  73.         if (pgd_none(*pgd_tmp) || pgd_bad(*pgd_tmp)) {
  74.                 printk(KERN_ALERT "Not mapped in pgd.\n");
  75.                 return -1;
  76.         }
  77.         pud_tmp = pud_offset(pgd_tmp,va);
  78.         if (pud_none(*pud_tmp) || pud_bad(*pud_tmp)) {
  79.                 printk(KERN_ALERT "Not mapped in pud.\n");
  80.                 return -1;
  81.         }
  82.         pmd_tmp = pmd_offset(pud_tmp,va);
  83.         if (pmd_none(*pmd_tmp) || pmd_bad(*pmd_tmp)) {
  84.                 printk(KERN_ALERT "Not mapped in pmd.\n");
  85.                 return -1;
  86.         }
  87.         /*FIXME:
  88.           Do I need to check Large Page ? PSE bit.
  89.                 if(pmd_large(*pmd_tmp) == 1){
  90.                         pa = (pmd_val(*pmd_tmp) & PMD_MASK) | (va & ~PMD_MASK);
  91.                 }
  92.           */
  93.         pte_tmp = pte_offset_kernel(pmd_tmp, va);
  94.         if (!pte_tmp || pte_none(*pte_tmp)) {
  95.                 printk(KERN_ALERT "Not mapped in pte.\n");
  96.                 return 0;
  97.         }
  98.         if (!pte_present(*pte_tmp)) {
  99.                 printk(KERN_ALERT "pte not in RAM,maybe swaped.\n");
  100.                 return 0;
  101.         }
  102.         ppage = pte_page(*pte_tmp);
  103.         pfn = page_to_pfn(ppage);
  104.         pa = page_to_phys(ppage);
  105.         pa = pa|(va&~PAGE_MASK);
  106.         printk(KERN_ALERT "virt_addr 0x%lx in RAM is 0x%lx.\n",va,pa);
  107.         printk(KERN_ALERT "content in 0x%lx is 0x%lx.\n",pa,*(unsigned int*)(__va(pa)));
  108.         return 0;
  109. }
  110. static void find_pgd_exit(void)
  111. {
  112.         printk(KERN_ALERT "Goodbey.\n");
  113. }
  114. module_init(find_pgd_init);
  115. module_exit(find_pgd_exit);
复制代码

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
7 [报告]
发表于 2013-10-28 19:50 |只看该作者
回复 5# netdoger


     对. 用户空间的, 版主已经给出来了.
   
      内核有相应的接口follow_pte(), 但是是一个static inline函数. 必须更改才能使用.

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
8 [报告]
发表于 2013-10-29 12:42 |只看该作者
回复 6# 瀚海书香
试了下,好像少了个头文件,呵呵~~
#include <asm/io.h>


   

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
9 [报告]
发表于 2013-10-29 12:45 |只看该作者
瀚海书香 发表于 2013-10-28 15:48
回复 5# netdoger


试了下,好像少了个头文件,呵呵~~
#include <asm/io.h>

论坛徽章:
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
10 [报告]
发表于 2013-10-29 15:47 |只看该作者
回复 9# humjb_1983
试了下,好像少了个头文件,呵呵~~
#include <asm/io.h>


It works fine on version 3.0, maybe others version need it!



   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP