do_execve
->open_exec->dentry_open
....
f->f_dentry = dentry;
....
f->f_op = fops_get(inode->i_fop);
....
设置f->f_dentry和f->f_op,我们考察执行ext2的情景,因此f_op将是 ext2_file_operations
->search_binary_handler->load_elf_binary->elf_map->do_mmap- >do_mmap_pgoff
....
vma->vm_file = file;
get_file(file);
error = file->f_op->mmap(file, vma);
....
设置vm_file,执行f_op->mmap,在ext2_file_operations中的mmap是generic_file_mmap,在 generic_file_mmap中主要是设置vma->vm_ops = ops,绝大多数情况下ops是file_private_mmap
static struct vm_operations_struct file_private_mmap = {
nopage: filemap_nopage,
};
执行do_mmap时,如果是代码段,一般只允许读和执行,如果是数据段,一般允许读和写,但是vma- >vm_page_prot中只设置有可读和可执行位(没有深入研究)
sys_execve做完映射后就退出了.当调度到该进程时并执行代码时,立即产生page fault,依次 do_page_fault->handle_mm_fault->handle_pte_fault->do_no_page
...
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, (vma->vm_flags & VM_SHARED)?0:write_access);
...
从前面知道,此处将调用filemap_nopage(基本所有这类的情景都执行这个函数)
filemap_nopage->page_cache_read
.....
page = page_cache_alloc();
if (!page)
return -ENOMEM;
if (!add_to_page_cache_unique(page, mapping, offset, hash)) {
int error = mapping->a_ops->readpage(file, page);
page_cache_release(page);
return error;
}
....