Linux sys_exec中可执行文件映射的建立及读取(4)
sys_exec("/bin/apache") 执行过程
当前进程进入sys_exec系统调用;
以下为load_elf_binary:打开apache文件,读取其128字节头,依据头找到elf处理模块(假设这里apache为elf文件);
确定程序所使用的动态库,一般为/usr/lib/ld_linux.so.2(从apache文件头部分分析出),随后打开该库文件(也就是解释器);
读取解释器的首部;
以下为flush_old_exec(执行该函数之后,调用sys_exec的进程将直接消失,从此与当前进程无关,而是被apache完全代替),为apache日后运行能拥有自己独立的信号,以免影响其他进程,这里为apache创建新的信号表;
释放所有的current->mm->mmap;
释放原来老的信号表(刚刚前面在创建新的信号表时还没有释放老信号表);
以下为setup_arg_pages:为命令行参数args建立相应的vm_area_struct(start=3G-args's size;end=3G),自栈顶往下,由于sys_execv刚开始时就已经将args读取到内核内存中,这里在put_dirty_page函数中为vm_start----- vm_end这段用户空间对应的页目录项创建相应的页表,并设置相应的该页表的页表项指向args所在的物理页面;
以下为 elf_map:为apache中的.code、.data等段建立vm_area_struct,并建立到apache磁盘文件中对应磁盘页面的映射, vm_area_struct的vm_start、vm_end和vm_pgoff已经在apache elf文件中由编译器指明,注意这里没有为对应的页目录表项创建页表,更不存在设置页表项了;
以下为load_elf_interp:为解释器ld_linux.so.2建立vm_area_struct,并建立到该文件的磁盘映射;
重新设置current->mm的参数,简历bss段,设置新的EIP(指向解释器的代码段)和ESP(指向位于栈顶的args参数底部);当sys_exec从内核系统调用中返回到用户空间时,将从该EIP处开始执行;
注意:例如在test程序中调用execve("/bin/apache"),则执行完毕后,test程序就不存在了,被apache完全代替,pid保持不变。
文章来源CU社区:Linux sys_exec中可执行文件映射的建立及读取
相关文章