mmap函数及其映射失败原因分析

原创 2012年10月16日 09:27:03

mmap函数

头文件:#include <sys/mman.h>

函数原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

参数  start:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址。
  length:映射区的长度。
  prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起
  PROT_EXEC //页内容可以被执行
  PROT_READ //页内容可以被读取
  PROT_WRITE //页可以被写入
  PROT_NONE //页不可访问
  flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
  MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。
  MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。
  MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。
  MAP_DENYWRITE //这个标志被忽略。
  MAP_EXECUTABLE //同上
  MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。
  MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。
  MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。
  MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。
  MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。
  MAP_FILE //兼容标志,被忽略。
  MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。
  MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。
  MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。
  fd:有效的文件描述词。如果MAP_ANONYMOUS被设定,为了兼容问题,其值应为-1。

  offset:被映射对象内容的起点。

第三个参数一般只用PROT_READ|PROT_WRITE,第四个参数一般用MAP_SHARED。

mmap设备操作  mmap操作提供了一种机制,让用户程序直接访问设备内存,这种机制,相比较在用户空间和内核空间互相拷贝数据,效率更高。在要求高性能的应用中比较常用。mmap映射内存必须是页面大小的整数倍,面向流的设备不能进行mmap,mmap的实现和硬件有关。

 

mmap失败原因分析:若第二个参数length或者其大小不是页面大小的整数倍时会导致映射失败。

相关文章推荐

mmap 错误

int readlen = 5*1024*1024; //int readlen = 1024; int fd = open("/home/bonc/BC000D0300420131210000001...
  • tina_j
  • tina_j
  • 2013年12月16日 15:59
  • 966

mmap ENOMEM(errno 12) 错误

今天触发了一个大坑,发现mmap在映射大量文件的时候,会失败,返回ENOMEM错误。 找了一圈,有的说是swap不够,增加了swap也没用,可见不是这个问题。 后来看了美军一个文章...

Linux mmap学习及遇到的问题解决

Linux mmap的学习 本来以前mmap是很简单的,看下参数用法就ok,结果遇到了一大堆麻烦,google了很多博客,都写得很浅显,就介绍一下参数然后再给了一个简单得不得了的代码,就完了,所以纠...

通过mmap将连续物理地址映射到用户空间

由于MMU对用户空间的内存采用页式管理,用户空间的内存都是虚拟的,只有当真正写入物理内存时,系统才会判断是否为该虚拟内存分配物理内存,如果未分配就会触发缺页中断,然后分配一整页的内存给应用程序。所以用...

大块数据申请及DMA

在内核中有时需要申请一段大内存,方法之一是可以采取如下方法: 示例: 如何将1M的物理内存作为私人使用(假设物理内存大小为256M): 1. 在内核启动时,通过mem=255M参数,让内核只能使用...

linux mmap 和 mmap64

今天心头一热把mmap改成mmap64,其他什么都没改变,结果收到SIGSEGV。

写mmap内存变慢的原因

有很多系统读写大文件时用的是这个办法:将大文件mmap到内存,然后直接对内存读写。这样就化read/write为memcpy操作,代码开发上很简便。被修改的内存页由kernel负责挑个时间写入硬盘,程...
  • Fybon
  • Fybon
  • 2014年09月30日 16:42
  • 1410

mmap失败追踪

今天在小试mmap函数的时候,本以为会一路畅通没想到执行的时候出现了段错误,调试了一下发现在mmap返回以后访问返回的指针出了问题,代码如下 #define REC_NUM 100 typedef s...
  • tohsduo
  • tohsduo
  • 2016年08月19日 14:52
  • 116

遇到过——Xcode开发错误、警告⚠️——小集合

1. error: Assertion failure in -[UITextView _firstBaselineOffsetFromTop], /BuildRoot/Library/Caches/...

linux内存映射mmap原理分析

一直都对内存映射文件这个概念很模糊,不知道它和虚拟内存有什么区别,而且映射这个词也很让人迷茫,今天终于搞清楚了。。。下面,我先解释一下我对映射这个词的理解,再区分一下几个容易混淆的概念,之后,什么是内...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mmap函数及其映射失败原因分析
举报原因:
原因补充:

(最多只允许输入30个字)