SA****6343 孙洪菠
对进程的创建与可执行程序的加载总结如下:
linux系统通过函数fork( )、exec()来创建一个新的进程,更确切的说,这两个函数是分别用于进程的创建和进程修改,函数fork( )用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝;函数族exec( )用来启动另外的进程以取代当前运行的进程。
一、进程的创建过程:
执行过fork( )函数后,子进程作为父进程的一个拷贝,与父进程使用相同的代码段,复制父进程的堆栈段和数据段。子进程不在于父进程共享数据,子进程自己修改数据后自然不会对父进程的数据造成影响。对于区分父进程和子进程,是通过不同的进程号来实现的。对父进程而言,它的进程号是由比它更低层的系统调用赋予的,而对于子进程而言,它的进程号即是fork函数对父进程的返回值。
二、可执行程序的加载过程:
通过总结可以得到,在进入execve系统调用之后,Linux内核就开始进行真正的装载工作。在内核中,execve()系统调用相应的入口是sys_execve(),它被定义在arch/x86/kernel/exec.c中。sys_execve()进行一些参数检查复制之后,调用do_execve()。do_execve会首先查找被执行的文件,如果找打文件。则读取文件的前128个字节以确定被检查的文件的格式。然后,继续调用search_binary_handle()去搜索合适的可执行文件装载处理过程。比如ELF可执行文件的装载处理工程是load_elf_binary()。他的主要步骤是:检查elf文件的有效性,寻找动态链接库的“.interp”段,设置动态链接器的路径,根据ELF的可执行文件的程序头表的描述,对ELF文件进行映射,比如代码、数据、只读数据,初始化ELF进程环境。将系统调用的返回地址修改为ELF可执行文件的入口点。在设置了eip之后,sys_execve返回到用户态时,程序就返回到新的程序开始执行,ELF可执行文件装载完成。
进程调用过exec( )函数族后,进程的代码段会被替换成新的程序的代码,原有的堆栈段和数据段也会被废弃,开辟新的数据段和堆栈段。唯一留下的是进程号。这样一个新的进程就创建成功。
附件: Linux内核之进程和系统调用