- 论坛徽章:
- 0
|
本帖最后由 futex 于 2011-07-06 11:18 编辑
回复 69# linewer
你是说进程使用mmap来map一个文件到用户地址空间,然后用内存地址的方式来访问文件内容的情况吧?我来回答一下这个问题:
1:进程调用mmap时,除非设定VM_LOCKED标志,否则只是为进程分配一个要map文件长度的vm_area_struct结构,表示这段进程虚拟地址空间已被占用,同时调用要map的文件的f_op->mmap()操作,我们知道,设备也可以作为一个文件打开并执行mmap动作(如果设备驱动允许的话),对于这类文件的f_op->mmap操作由设备驱动自己实现。这里以普通文件为例(ext2文件系统),f_op->mmap将vma->vm_ops设置为generic_file_vm_ops, 该ops中指定了fault函数为filemap_fault,到此整个mmap过程结束,可以看到,没有任何page被分配,没有任何页目录和页表被修改,仅仅是分配了一个虚拟地址空间。
2:当用户访问该地址空间时,mmu发现页表上没有该地址的映射,于是发生一个page fault,在这个page fault的过程中发现这个地址在当前进程已分配的虚拟地址空间中(找到了该地址所在的vm_area_struct结构),由于找到的vm_area_struct对象中的vm_ops被指定,并且该ops中的fault函数被指定,因此可以确定此虚拟地址空间是被map到一个文件中。之后就是调用vm_ops中的fault函数(这是一个函数指针,具体指向filemap_fault函数),该函数分配新的page, 读入page fault处的文件内容到page中并将该page放入到文件的page cache中。在fault函数返回后再在页表中增加指向该page的页表项,至此,大功告成,说的简单但过程比较复杂。
3:如果mmap是指定了VM_LOCKED标志呢?mmap过程主动调用handle_mm_fault函数来模拟上述page fault过程,分配page, 把所有已map的文件内容读入page中,再在页表中增加指向这些page的表项。
4:结论:mmap根据mmap的方式不同,分别使用COW方式和map时分配加载文件内容并建立页表项的方式来处理。一般情况下不指定VM_LOCKED而采用COW方式,除非有特别的需要(需要立即加载文件并建立页表映射)。
5:哈哈,俺的回答解决了你的问题吗?还是答非所问? |
|