免费注册 查看新帖 |

Chinaunix

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

[内存管理] 怎么区分一个物理页面属于内核还是用户空间 [复制链接]

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
21 [报告]
发表于 2013-04-21 12:12 |只看该作者
本帖最后由 amarant 于 2013-04-21 12:13 编辑

回复 20# embeddedlwp


    能在x86下运行,直接编译。只是你要确定物理内存的该地址的内容和mmap读出来的内容是不是一样就不容易了。我只是用qemu的xp功能,很容易调试对比值是不是一样。
估计在x86下不用qemu还需要写一个简单模块,来从内核空间打印该物理地址的内容。
offset是偏移,我是在认为/dev/mem就是对整个内存的映射基础上,然后使用offset做偏移的。

论坛徽章:
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
22 [报告]
发表于 2013-04-21 12:14 |只看该作者
本帖最后由 embeddedlwp 于 2013-04-21 13:31 编辑

回复 21# amarant


应该是默认只能访问mmio,你禁了STRICT_DEVMEM选项。

论坛徽章:
0
23 [报告]
发表于 2013-04-21 16:10 |只看该作者
回复 20# embeddedlwp
对于/dev/mem设备文件来说,这个offset的意义就是物理地址的偏移吧
drivers/char/mem.c, mem设备文件的fops:
  1. static const struct file_operations mem_fops = {
  2.         .llseek                = memory_lseek,
  3.         .read                = read_mem,
  4.         .write                = write_mem,
  5.         .mmap                = mmap_mem,
  6.         .open                = open_mem,
  7.         .get_unmapped_area = get_unmapped_area_mem,
  8. };
复制代码
其中mmap和read接口来完成的内存的访问:

  1. /*
  2. * This funcion reads the *physical* memory. The f_pos points directly to the
  3. * memory location.
  4. */
  5. static ssize_t read_mem(struct file *file, char __user *buf,
  6.                         size_t count, loff_t *ppos)
  7. {
  8.         unsigned long p = *ppos;
  9.         ssize_t read, sz;
  10.         char *ptr;

  11.         if (!valid_phys_addr_range(p, count))
  12.                 return -EFAULT;
  13.         read = 0;
  14. #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
  15.         /* we don't have page 0 mapped on sparc and m68k.. */
  16.         if (p < PAGE_SIZE) {
  17.                 sz = size_inside_page(p, count);
  18.                 if (sz > 0) {
  19.                         if (clear_user(buf, sz))
  20.                                 return -EFAULT;
  21.                         buf += sz;
  22.                         p += sz;
  23.                         count -= sz;
  24.                         read += sz;
  25.                 }
  26.         }
  27. #endif

  28.         while (count > 0) {
  29.                 unsigned long remaining;

  30.                 sz = size_inside_page(p, count);

  31.                 if (!range_is_allowed(p >> PAGE_SHIFT, count))
  32.                         return -EPERM;

  33.                 /*
  34.                  * On ia64 if a page has been mapped somewhere as uncached, then
  35.                  * it must also be accessed uncached by the kernel or data
  36.                  * corruption may occur.
  37.                  */
  38.                 ptr = xlate_dev_mem_ptr(p);
  39.                 if (!ptr)
  40.                         return -EFAULT;

  41.                 remaining = copy_to_user(buf, ptr, sz);
  42.                 unxlate_dev_mem_ptr(p, ptr);
  43.                 if (remaining)
  44.                         return -EFAULT;

  45.                 buf += sz;
  46.                 p += sz;
  47.                 count -= sz;
  48.                 read += sz;
  49.         }

  50.         *ppos += read;
  51.         return read;
  52. }
复制代码
mmap实现:

  1. static int mmap_mem(struct file *file, struct vm_area_struct *vma)
  2. {
  3.         size_t size = vma->vm_end - vma->vm_start;

  4.         if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
  5.                 return -EINVAL;

  6.         if (!private_mapping_ok(vma))
  7.                 return -ENOSYS;

  8.         if (!range_is_allowed(vma->vm_pgoff, size))
  9.                 return -EPERM;

  10.         if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
  11.                                                 &vma->vm_page_prot))
  12.                 return -EINVAL;

  13.         vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
  14.                                                  size,
  15.                                                  vma->vm_page_prot);

  16.         vma->vm_ops = &mmap_mem_ops;

  17.         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
  18.         if (remap_pfn_range(vma,
  19.                             vma->vm_start,
  20.                             vma->vm_pgoff,
  21.                             size,
  22.                             vma->vm_page_prot)) {
  23.                 return -EAGAIN;
  24.         }
  25.         return 0;
  26. }
复制代码

论坛徽章:
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
24 [报告]
发表于 2013-04-21 16:12 |只看该作者
回复 23# junnyg


对!

   

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
25 [报告]
发表于 2013-04-21 22:13 |只看该作者
回复 24# embeddedlwp
回复 23# junnyg

刚好今天周末,也花了点时间看了下mem.c的源代码,在mmap函数中所作的检测只有下面这些

        if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
                return -EINVAL;

        if (!private_mapping_ok(vma))
                return -ENOSYS;

        if (!range_is_allowed(vma->vm_pgoff, size))
                return -EPERM;

        if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
                                                &vma->vm_page_prot))
                return -EINVAL;

没有看到说mmio之类的吧。恐怕万鹏兄说的有所偏差
   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
26 [报告]
发表于 2013-04-21 22:57 |只看该作者
CONFIG_STRICT_DEVMEM:

If this option is disabled, you allow userspace (root) access to all

of memory, including kernel and userspace memory. Accidental

access to this is obviously disastrous, but specific access can

be used by people debugging the kernel. Note that with PAT support

enabled, even in this case there are restrictions on /dev/mem

use due to the cache aliasing requirements.

If this option is switched on, the /dev/mem file only allows

userspace access to PCI space and the BIOS code and data regions.

This is sufficient for dosemu and X and all common users of    /dev/mem.

不知道代码哪里处理的,呵呵。

论坛徽章:
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
27 [报告]
发表于 2013-04-22 07:17 |只看该作者
回复 25# amarant


在这里实现的:

if (!range_is_allowed(vma->vm_pgoff, size))
                return -EPERM;


   

论坛徽章:
0
28 [报告]
发表于 2013-04-22 09:59 |只看该作者
感谢啊,一语中的!!!!回复 10# junnyg


   

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
29 [报告]
发表于 2013-04-22 10:23 |只看该作者
回复 27# embeddedlwp


    所以这个是和架构实现相关的,我一直没去看x86的代码。只有部分架构里有config strick devmem
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP