快速业务通道

Linux关于地址空间和MMAP映射

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-24
_mmap():创建地址区间

  内核使用do_mmap()函数创建一个新的线性地址区间.但是说给函数创建一个新VMA并不非常准确,如果创建的地址区间和一个已经存在的地址区间相邻,并且它们具有相同的访问权限的话,那么两个区间将合并为一个.如果不能合并,那么就确实需要创建一个新的VMA了.但无论哪种情况,do_mmap()函数都会将一个地址区间加入到进程的地址空间中——无论是扩展已经存在的内存区域还是创建一个新的区域.

  do_mmap()函数声明在文件<linux/mm.h>中,原型如下:

  unsigned long do_mmap(struct file *file, unsigned long addr,

  unsigned long len, unsigned long prot,

  unsigned long flag, unsigned long offset)

  在用户空间可以通过mmap()函数调用获取内核函数do_mmap()的功能.mmap()系统调用原型如下:

  void *mmap2(void *start, size_t length,

  int prot, int flags,

  int fd, off_t pgoff)

  do_munmap()函数从特定的进程地址空间中删除指定地址区间,该函数在文件<linux/mm.h>中声明:

  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)

  系统调用munmap()给用户空间程序提供了一种从自身地址空间中删除指定地址区间的方法,它和系统调用mmap()的作用相反:

  int munmap(void *start, size_t length)

  mmap设备操作

  对于驱动程序来说,内存映射可以提供给用户程序直接访问设备内存的能力.映射一个设备,意味着使用户空间的一段地址关联到设备内存上.无论何时,只要程序在分配的地址范围内进行读取或者写入,实际上就是对设备的访问.

  并不是所有的设备都能进行mmap抽象.例如,串口设备和其他面向流的设备就无法实现这种抽象.mmap的另一个限制是映射都是以PAGE_SIZE为单位的.内核只能在页表一级处理虚拟地址;因此,被映射的区域是PAGE_SIZE的整数倍,位于起始于PAGE_SIZE整数倍地址的物理内存内.如果区域的大小不是页大小的整数倍,内核就通过生成一个稍微大一些的区域来容纳它.

  mmap方法是file_operations结构中的一员,并且在执行mmap系统调用时就会调用该方法.在调用实际方法之前,内核会完成很多工作,该方法的原型与系统调用的原型由很大区别.

  文件操作声明如下:

  int (*mmap) (struct file * filp, struct vm_area_struct *vma);

  其中vma参数包含了用于访问设备的虚拟地址区间的信息.大部分工作已经由内核完成了,要实现mmap,驱动程序只要为这一地址范围构造合适的页表即可,如果需要的话,就用一个新的操作集替换vma->vm_ops.

  有两种建立页表的方法:使用remap_page_range函数可一次建立所有的页表,或者通过nopage VMA方法每次建立一个页表.

  构造用于映射一段物理地址的新页表的工作是由remap_page_range完成的,它的原型如下:

  int remap_page_range(unsigned long virt_add, unsigned long phys_add,

  unsigned long size, pgprot_t prot);

  nopage方法具有如下原型:

  struct page (*nopage) (struct vm_area_struct *vma, unsigned long address, int write_access);

  当用户进程访问当前不在内存中的VMA页面时,就会调用关联的VMA操作集中的nopage函数.参数address包含导致失效的虚拟地址,该地址向下取整到所在页的起始地址.函数nopage定位并返回指向用户所期望的页的struct page指针.这个函数还要调用get_page宏,以增加它所返回的页面的使用计数:get_page(struct page *pageptr).

  nopage方法在mremap系统调用中非常有用.应用程序使用mremap来改变应该映射区域的边界地址.mremap系统调用的原型如下:

  void * mremap(void *old_address, s

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号