内存映射函数mmap, 负责把文件内容或者其他对象映射到进程的虚拟内存空间, 通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用read,write等操作。文件或者其他对象被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。
 用法:

  1. void *mmap(void *start, size_t length, int prot, int flags,
  2. int fd, off_t offset);
  3. int munmap(void *start, size_t length);

参数:   
 start:映射区的开始地址。
 length:映射区的长度。
 prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起

  1. PROT_EXEC //页内容可以被执行
  2. PROT_READ  //页内容可以被读取
  3. PROT_WRITE //页可以被写入
  4. 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:被映射对象内容的起点。

返回值说明: 
 成功执行时,mmap()返回被映射区的指针。失败时,mmap()返回MAP_FAILED[其值为(void *)-1]。

  1. int   munmap(void *start, size_t length);

取消参数start所指向的映射内存,参数length表示欲取消的内存大小。
 
 返回值:解除成功返回0,否则返回-1,错误原因存于errno中。
 
 一个简单的实例,实现对framebuffer的操作:

  1. #include <stdio.h>
  2. #include <sys/mman.h>
  3. #include <string.h>
  4. #include <linux/fb.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <stdlib.h>
  10. #ifndef true
  11. #define true 1
  12. #endif
  13. #ifndef false
  14. #define false 0
  15. #endif
  16. int FB_Init()
  17. {
  18. fb = open("/dev/fb0", O_RDWR);
  19. if(fb < 0)
  20. {
  21. fprintf(stderr, "Open Failed\n");
  22. return false;
  23. }
  24. if(ioctl(fb, FBIOGET_FSCREENINFO, &f_info) < 0)
  25. {
  26. fprintf(stderr, "Get FSCREENINFO Failed\n");
  27. return false;
  28. }
  29. if(ioctl(fb, FBIOGET_VSCREENINFO, &v_info) < 0)
  30. {
  31. fprintf(stderr, "Get VSCREENINFO Failed\n");
  32. return false;
  33. }
  34. screen_size = v_info.xres * v_info.yres * (v_info.bits_per_pixel) / 8;
  35. fbuffer = mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
  36. if((int)fbuffer == -1)
  37. {
  38. fprintf(stderr, "Mmap error\n");
  39. return false;
  40. }
  41. }
  42. int FB_Close()
  43. {
  44. munmap(fbuffer, screen_size);
  45. close(fb);
  46. return true;
  47. }
  48. int point(int x,int y, ColorType color)
  49. {
  50. int temp;
  51. void *currPoint;
  52. if(x < 0 || x >= v_info.width)
  53. return false;
  54. if(y < 0 || y >= v_info.height)
  55. return false;
  56. temp = (x + v_info.xoffset) * (v_info.bits_per_pixel/8) +
  57. (y + v_info.yoffset) * f_info.line_length;
  58. *((unsigned short *)(fbuffer + temp)) = color;
  59. return true;
  60. }
  61. int main(int argc, char *argv[])
  62. {
  63. FB_Init();
  64. point(100, 100, 0x19ff1d00);
  65. FB_Close();
  66. return 0;
  67. }

编译运行后就在我们的framebuffer上的坐标为(100, 100)的地方画出一个点。

本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/857476,如需转载请自行联系原作者

Linux中mmap与munmap函数系统调用相关推荐

  1. 转:linux中fork()函数详解

    转:linux中fork()函数详解 https://blog.csdn.net/jason314/article/details/5640969 转载于:https://www.cnblogs.co ...

  2. 在linux下面实现检测按键(Linux中kbhit()函数的实现)

    //在linux下面实现检测按键(Linux中kbhit()函数的实现) #include <stdio.h> #include <termios.h> #include &l ...

  3. linux之getcwd函数解析,Linux 中C语言getcwd()函数的用法

    Linux 中C语言getcwd()函数的用法 先来看该函数的声明: #include char *getcwd(char *buf,size_t size); 介绍: 参数说明:getcwd()会将 ...

  4. linux下面实现检测按键(Linux中kbhit()函数的实现)

    在linux下面实现检测按键(Linux中kbhit()函数的实现)   #include <stdio.h> #include <termios.h> #include &l ...

  5. linux alarm 多个,linux中的alarm和 setitimer系统调用

    linux中的alarm和 setitimer系统调用 (2013-07-09 14:30:22) 标签: linuxc编程 alarm signal 文化 alarm和 setitimer系统调用 ...

  6. c语言open函数打开文件方式,Linux中C语言open函数打开或创建文件详细讲解

    Linux中C语言open函数打开或创建文件详细讲解 Linux中C语言open函数打开或创建文件详细讲解 头文件: #include #include #include 函数原型: int open ...

  7. Linux中的进程创建函数fork

    为什么80%的码农都做不了架构师?>>>    Linux中的进程通过fork创建,并通过exec执行,分为两步. 在Linux中所有的进程都是pid为1的init进程的子进程,内核 ...

  8. linux kbhit扫描键盘,(转)检测按键(Linux中kbhit()函数的实现)

    http://hi.baidu.com/jtntiivtemcnsue/item/90689ce172ee912c5a7cfb1b 编写过MS-DOS程序的人通常都会查找Linux下等同于kbhit的 ...

  9. linux中c语言kbhit函数用法,检测按键(Linux中kbhit()函数的实现)

    编写过MS-DOS程序的人通常都会查找Linux下等同于kbhit的函数,这个函数会检测一个按键是否被按下而并不实际的读取.不幸的是他们并没有找到这样的函数,因为并没有直接等同的函数.Unix程序员并 ...

最新文章

  1. 大多数人都不知道,人类基因组正在衰败
  2. 整体思考自动化测试发展和价值回报
  3. access导出MySQL表格_将ACCESS 的数据库中的表的文件 导出了EXCEL格式
  4. SQL Server技术问题之索引优缺点
  5. apache属于什么类型的软件
  6. AngularJs学习笔记--unit-testing
  7. 共济失调对我们的危害你知道吗
  8. Linux平台 Oracle 18c RAC安装Part3:DB配置
  9. Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)
  10. flac3d命令流实例大全_Activiti6.0工作流引擎深度解析
  11. jQuery插件Label Effect制作个性化的文字特效
  12. 【[USACO13NOV]没有找零No Change】
  13. DEM高程数据下载方法
  14. ArrayList的retainAll()方法使用
  15. sql往数据库里面添加数据
  16. 共模和差模电感电路分析方法及思路
  17. TrafficMonitor 网速监控悬浮窗软件
  18. lol人物模型提取(九)——终章
  19. 阿里云第二次实验——个人网盘的搭建
  20. python全栈工程师薪水_Python工程师薪资刷出新高度,有望成为世界上最流行的编程语言...

热门文章

  1. Java 8 中的方法引用,轻松减少代码量,提升可读性!
  2. 恕我直言,IDEA 的 Debug 调试,你可能只用了 10%
  3. 支付宝的架构到底有多牛逼!还没看完我就跪了!
  4. 数据清洗指南完整分享
  5. 数据挖掘竞赛指南:曾经的数据挖掘少年,如今的阿里算法大佬
  6. ShakeDrop:深度残差学习中的 ShakeDrop 正则化
  7. Hinton新论文:如何在神经网络中表示“部分-整体层次结构”?
  8. 模型花费几十万美元,五年之间指导无数项目,才发现负样本用的是null?
  9. 全网唯一秃头数据集:20 万张人像,网罗各类秃头
  10. 哪些“双一流”更得华为偏爱?这所高校人数远超清北华五