一.内存映射介绍
在linux外围设备的常见操作中,用户空间不能直接访问外围设备,而是通过内核空间间接访问磁盘,如下图所示
虽然对速度要求不敏感的程序没有太大影响,但在照相机和视频显示设备上,此操作会导致视频卡等
linux提供了一种直接操作内存映射的方法
二. linux内存映射函数
映射函数
功能:将一个文件或其他对象映射到内存。 文件映射到了多个页面。 如果文件大小不是所有页面大小的总和,则最后一页未使用的空间将清零
后退:成功,如果指针返回到映射区域失败,则失败,MAP_FAILED (这是(void* )-1 )
void*mmap(void*start,size_t length,int prot,int flags,int fd,off_t offsize );
参数:
start :地图区域的开始地址
长度:地图区域的长度
prot :地图区域的保护方式。 以下几种方法可以组合使用
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 //堆栈,告知内核虚拟机系统可以向下扩展地图空间
MAP_ANONYMOUS //匿名映射,映射区域与任何文件都没有关联
是MAP_ANON //MAP_ANONYMOUS的别称,不再使用
MAP_FILE //兼容标志,被忽略
将MAP_32BIT //映射区域配置在进程地址空间的低位2GB,如果用MAP_FIXED指定,则被忽略。 当前,仅在x86-64平台上支持此徽标
为MAP_POPULATE //文件映射预读准备页面表。 然后,对映射区域的访问不会因页面违规而被阻止。
只有在与map_nonblock//map_populate一起使用时才有意义。 不执行预读,只对内存中已经存在的页面创建页面表条目
软盘:有效的文件描述词。
offset :映射对象内容的起点
munmap未映射函数
功能:删除特定地址区域的对象映射
返回:成功0失败-1
intmunmap(void*start,size_t length );
参数:
start :地图区域的开始地址
长度:地图区域的长度
三.例子
1、液晶显示屏
FFD=open((/dev/FB0 )、O_RDWR ); FBP=mmap(0,屏幕大小,PROT_READ | PROT_WRITE,MAP_SHARED,fbfd,0 ); *(FBDy*vinfo.xresx )=c;