您的位置:首页 > 运维架构 > Linux

Linux 设备驱动--- mmap设备操作

2013-03-09 18:33 211 查看

mmap 系统调用-映射:

void * mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )

内存映射函数 mmap ,负责把 文件内容映射到进程的虚拟内存空间,通过对这段空间内存的读取和修改,

来实现对文件的读取和修改,而不再调用 read , write 等操作.

参数:

addr :指定映射的起始地址,通常设为 NULL ,由系统指定.

length :映射到内存的文件长度.

prot : 映射区的保护模式,可以是:

PROT_EXEC :映射区可被执行.

PROT_READ :映射区可被读取.

PROT_WRITE :映射区可被写入.

flags : 映射区的特性,可以是:

MAP_SHARED : 写入映射区的数据会复制回文件,且允许其他映射该文件的进程共享.

MAP_PRIVATE :对映射区的写入操作会产生一个映射区的复制,( cope-on-write ) ,对

此区域所做的修改不会写回原文件.

fd :由 open 返回的文件描述符.代表要映射的文件.

offset :以文件开始处的偏移量,必须是分页大小的整数倍,通常为0,表示从文件头开始映射.

示意图:



解除映射- munmap:

函数: munmap ( void * start , size_t length )

功能:取消参数 start 所指向的映射内存,参数 length 表示欲取消的内存大小.

返回值:解除成功返回 0 ,否则返回 -1 ,错误原因存于 errno 中.

eg:



需要说明的是 读写不能改变原来文件的大小 ,即原来有多少字符 ,修改以后 ,不管怎样,字符的数目不会改变.

虚拟内存区域:

虚拟内存区域是 进程 的虚拟地址空间中的一个同质区间,具有同样的特性的连续地址范围.

一个进程的内存映像由下面几部分组成:程序代码,数据,BSS 和 栈区域,以及内存映射的区域.



上图每一行的 域 为:



其描述结构-vm_area_struct :

Linux 内核使用结构 vm_area_strcut (< linux/mm_types.h > ) 来描述虚拟内存区域,

其中几个主要成员如下:

unsigned long vm_start :虚拟内存区域起始地址.

unsigned long vm_end :虚拟内存区域结束地址.

unsigned long vm_flags :该区域的标记. 如: VM_IO 和 VM_RESERVED .

VM_IO 将该VMA 标记为 内存映射的 IO 区域,VM_IO 会组织系统将该区域包含

在进程的存放转存 ( core dump ) 中, VM_RESERVED 标志内存区域不能被换出.

什么是映射一个设备:

映射一个设备是指把用户空间的一段地址关联到设备内存上.当程序读写这段用户空间时,它实际是在访问设备.

mmap 设备方法完成的功能:

mmap 方法是 file_oprations 结构的成员,在 mmap 系统调用发出时被调用,在此之前,内核已经完成了很多工作,

mmap 设备方法所需要做的就是
建立虚拟地址到物理地址的页表.

int ( * mmap ) ( struct file * , struct vm_area_struct * )

mmap 建立页表:

方法有二:

1,使用 remap_pfn_range 一次建立所有页表;

2,使用 nopage VMA 方法每次建立一个页表.

构建页表函数 :



参数:

vma:虚拟内存区域指针.

irt_addr :虚拟地址的起始地址.

pfn :要映射的物理地址所在的物理页帧号,可将物理地址 >>PAGE_SHIFT 得到.

size :要映射的区域的大小.

prot :VMA 的保护属性.

eg:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: