内存映射函数mmap, 负责把文件内容映射到进程的虚拟内存空间,通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用read, write等。
void *mmap (*addr, len, port, flags, fd, offset)
addr: 指定起始地址,通常设为NULL,由系统指定
length: 映射到内存的文件长度
port:映射区的保护方式可以为以下:
PROT_EXEC:映射区可被执行
PROT_READ:映射区可被读取
PORT_WRITE:映射区可被写入
flags:
MAP_SHARED:写入映射区的数据会复制回文件,且允许其他映射该文件的进程共享。
MAP_PRIVATE:对映射区的写入操作会产生一个映射区的复制(copy-on-write),对此区域所做的修改不会回写回去。
特点:回写时不会修改原文件的长度。
返回值为起始地址
解除映射 int munmap(*start, length)
取消参数start所指向的映射内存,参数length表示欲取消的内存大小
进程的内存映像的组成:程序代码、数据、BSS和栈区间
查看虚拟内存区域 /proc/pid/maps
查看的组成
start_end perm offest major:minor inode
start:该区域起始虚拟地址
end:该区域结束虚拟地址
perm:读、写和执行权限,表示对这个区域,允许进程做什么。这个域的最后一个字符要么是P表示 私有的,要么是s表示共享的。
offset:被映射部分在文件中的起始地址
Major、minor:主次设备号
iNode:索引结点
内核里面的MMAP
映射一个设备是指把用户空间的一段地址关联到设备内存上。当程序读写这段用户空间的地址时,它实际上是访问设备。
mmap设备方法要做的是建立虚拟地址到物理地址的页表。
int (*mmap)(struct file *, struct vm_area_struct *)
mmap页表的建立:
1、使用remap_pfn_range 一次建立所有的页表
2、使用nopage VMA方法每次建立一个页表