linux可执行程序加载,深入理解Linux之进程的创建和可执行程序的加载

SA12226242 施健

一.进程的创建

Linux创建进程是通过子进程复制父进程所拥有的资源来实现的。现代Linux通过写时复制、共享数据等方法优化这一过程,提高创建子进程的效率。

在Linux中,进程创建实际上是通过do_fork函数处理的。do_fork函数的功能相对简单:

.结束并返回子进程的ID

copy_process则负责对进程创建的相关资源的申请:

.将total_forks增加1

task_struct进程控制块与进程地址空间的联系:

在task_struct结构体内的struct mm_struct成员执行内存区描述符的指针。在进程描述符中,还应该存储进程空间的页表信息,和将逻辑地址转换成页号和页内偏移地址所需的相关信息。

通过总结可以得到:进程的创建的系统调用clone fork vfork都是调用do_fork实现的,而do_fork在做了一些参数检查之后。调用了copy_process函数,copy_process函数在进行安全性检查之后,使用dup_task_struct复制父进程的结构体。对新进程描述符的一些标志信息和时间信息进行初始化,之后将父进程的所有进程信息拷贝到子进程空间,包括IO、文件、内存信息等。然后,设置新进程的pid,将新进程加入进程调度队列中。子进程的eax设置为0,父进程则返回新进程的pid,所以在fork调用中,子进程返回的是0,父进程返回的是新进程的pid。详细代码分析,请参加附录。

二.可执行程序的加载

在Linux中提供了一系列的函数,这些函数能用可执行文件所描述的新上下文代替进程的上下文。这样的函数名以前缀exec开始。所有的exec函数都是调用了execve()系统调用。

sys_execve接受参数:1.可执行文件的路径  2.命令行参数字符串 3.环境变量字符串

sys_execve是调用do_execve实现的。do_execve则是调用do_execve_common实现的,依次执行以下操作:

. 释放linux_binprm数据结构,返回从该文件可执行格式的load_binary中获得的代码。

对load_binary分析如下:

1.检查存放在文件前128字节的一些魔数进行匹配以确认文件格式。2.读可执行文件的首部。3.从可执行文件中确定动态链接程序的路径名,并用它来确定共享库的位置并把他们映射到内存。4.获得动态链接程序的目录项对象。5.检查动态链接的执行许可权。6.把动态链接程序的前128字节拷贝到缓冲区。7.对动态链接程序类型执行一致性检查。8.调用arch_pick_mmap_layout(),以选择进程线性区的布局。9.调用setup_arg_pages()函数为进程的用户态堆栈分配一个新的线性区描述符。10.调用do_mmap()函数创建一个新线性区来对可执行文件正文段进行映射。11.调用装入动态链接程序的函数12.把可执行格式的linux_binfmt对象的地址放在进程描述符的binfmt字段。13.创建动态链接程序表,并把它们放在用户态堆栈。14.调用do_brk()函数创建一个新的匿名线性区来映射程序的bss段。15.调用start_thread()宏修改保存在内核态堆栈。16.返回0.

总结:Linux内核使用execve系统调用就开始进行程序的装载。execve()系统调用相应的实现是sys_execve()。

sys_execve()进行一些参数检查复制之后,调用do_execve()。

do_execve会首先查找被执行的文件,如果找打文件。则读取文件的前128个字节以确定被检查的文件的格式。然后,继续调用search_binary_handle()去搜索合适的可执行文件装载处理过程。

对ELF可执行文件的装载处理工程是load_elf_binary()。步骤是:检查elf文件的有效性,寻找动态链接库的“.interp”段,设置动态链接器的路径,根据ELF的可执行文件的程序头表的描述,对ELF文件进行映射,初始化ELF进程环境。

最后,将系统调用的返回地址修改为ELF可执行文件的入口点。在设置了eip之后,sys_execve返回到用户态时,程序就返回到新的程序开始执行,ELF可执行文件装载完成。

详细的代码分析,请参加附录。

ELF文件格式与进程地址空间的联系:在壮载ELF文件时,会将文件头部的.init、.text、.rodata段装载到进程的代码段中,将ELF中数据相关的部分,装载到数据段中。

在动态链接的过程中,ELF文件全局变量的数据区的部分会在进程空间中拷贝一份,代码段则多个进程进行共享。

exec执行之后,EIP指向的地方:EIP指向新程序的入口点,在sys_execve执行完成进入用户态之后,将从新的程序入口点继续执行。

三.附录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值