免费注册 查看新帖 |

Chinaunix

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

用户申请很大的一块内存,如何得到每页对应的物理地址? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-29 20:32 |只看该作者 |倒序浏览
想做linux下的零拷贝驱动程序。用户态申请内存,直接通过DMA给这块内存写数据,可否?望大家多多发表意见,说说看法。谢谢大家。

论坛徽章:
0
2 [报告]
发表于 2008-08-29 22:04 |只看该作者
是可以的  把用户空间的虚拟地址通过ioctl传到内核态   通过页表转换成物理地址,然后存在描述符里就可以了

论坛徽章:
0
3 [报告]
发表于 2008-08-29 22:47 |只看该作者
我改了个函数,或许能满足你的要求,用户态分配内存的虚拟地址你自己传下来,然后用这个函数得到pfn,pfn<<PAGE_SHIFT就是物理地址,即可以直接把物理地址给设备做DMA。此外在用户态要用mlock锁住内存不要swap出去

  1. pfn_t userpage_to_pfn(unsigned long user_va)
  2. {
  3.         struct page *page[1];
  4.         int npages;
  5.         pfn_t pfn;

  6.         might_sleep();

  7.         npages = get_user_pages(current, current->mm, user_va, 1, 1, 1, page,
  8.                                 NULL);

  9.         if (unlikely(npages != 1)) {
  10.                 struct vm_area_struct *vma;

  11.                 vma = find_vma(current->mm, user_va);
  12.                 if (vma == NULL || user_va < vma->vm_start ||
  13.                     !(vma->vm_flags & VM_PFNMAP)) {
  14.                         get_page(bad_page);
  15.                         return page_to_pfn(bad_page);
  16.                 }

  17.                 pfn = ((user_va - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
  18.         } else
  19.                 pfn = page_to_pfn(page[0]);

  20.         return pfn;
  21. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2008-09-01 11:16 |只看该作者
用户态申请的内存超过4K不是就可能不连续了吗?这时候是不是需要现将用户态的内存分页然后多次调用这个函数?userpage_to_pfn。是这样吗?xiexie

论坛徽章:
0
5 [报告]
发表于 2008-09-02 09:10 |只看该作者
原帖由 hui03090402 于 2008-9-1 11:16 发表
用户态申请的内存超过4K不是就可能不连续了吗?这时候是不是需要现将用户态的内存分页然后多次调用这个函数?userpage_to_pfn。是这样吗?xiexie

是的,你要逐页计算

论坛徽章:
0
6 [报告]
发表于 2008-09-03 11:28 |只看该作者
知道了。谢谢。我做的试一下。

论坛徽章:
0
7 [报告]
发表于 2008-09-08 16:28 |只看该作者

回复 #3 zx_wing 的帖子

你好,再次向你请教,你给出的函数中current实在那块定义的?user_va变量是不是要求必须是页对齐的?用户态的内存是咋么分页的啊?例如我在用户进程用malloc申请4097字节的数据,得到它的首地址是:0x86cf008。这段内存对应的物理地址应该是两页,页的分界点在那块?怎么分别得到其对应的物理地址啊?肯盼解答

论坛徽章:
0
8 [报告]
发表于 2008-09-08 18:55 |只看该作者
觉得适合在驱动里面做,申请到连续的物理内存,在通过mmap映射给用户~

论坛徽章:
0
9 [报告]
发表于 2008-09-08 20:25 |只看该作者
原帖由 Roemer 于 2008-9-8 18:55 发表
觉得适合在驱动里面做,申请到连续的物理内存,在通过mmap映射给用户~


对,应该是这样,在用户空间不能保证分配的内存是连续的

论坛徽章:
0
10 [报告]
发表于 2008-09-09 09:47 |只看该作者
直接在驱动里面申请内存,然后映射给用户我考虑过。就是觉得这样做的话,提供给用户的接口就必须重新定义啦。给用户的接口和以前的很不一样,我们的用户会不高兴。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP