2021-2022-1 20212812 《Linux内核原理与分析》第八周作业

一、实验:Linux 内核如何装载和启动一个可执行程

实验步骤

1.在shell中依次运行图中命令,获取本次实验的代码,并编译运行
在这里插入图片描述
2.启动gdb调试,设置三个断点:sys_execve,load_elf_binary,start_thread。

(gdb) b sys_execve

运行程序,在QEMU窗口中输入exec,系统就会停在上面设置的断点处,如图:
在这里插入图片描述
再设置二个断点来完整地跟踪进程:

(gdb) b load_elf_binary

(gdb) b start_thread

在这里插入图片描述
在这里插入图片描述
list列出来跟踪, 输入s可以进入do_execve的内部。按c继续执行,到load_elf_binary。list查看代码,输入n一句一句跟踪,追踪到start_thread。

二、问题与总结

1.新的可执行程序是从哪里开始执行的?

  • 当execve()系统调用终止且进程重新恢复它在用户态执行时,执行上下文被大幅度改变,要执行的新程序已被映射到进程空间,从elf头中的程序入口点开始执行新程序。

  • 如果这个新程序是静态链接的,那么这个程序就可以独立运行,elf头中的这个入口地址就是本程序的入口地址。

  • 如果这个新程序是动态链接的,那么此时还需要装载共享库,elf头中的这个入口地址是动态链接器ld的入口地址。

2 .为什么execve系统调用返回后新的可执行程序能顺利执行?
新的可执行程序执行,需要以下:

  • 它所需要的库函数。
  • 属于它的进程空间:代码段,数据段,内核栈,用户栈等。
  • 它所需要的运行参数。
  • 它所需要的系统资源。

如果满足以上4个条件,那么新的可执行程序就会处于可运行态,只要被调度到,就可以正常执行。我们一个一个看这几个条件能不能满足。

  • 条件1:如果新进程是静态链接的,那么库函数已经在可执行程序文件中,条件满足。如果是动态链接的,新进程的入口地址是动态链接器ld的起始地址,可以完成对所需库函数的加载,也能满足条件。
  • 条件2:execve系统调用通过大幅度修改执行上下文,将用户态堆栈清空,将老进程的进程空间替换为新进程的进程空间,新进程从老进程那里继承了所需要的进程空间,条件满足。
  • 条件3:我们一般在shell中,输入可执行程序所需要的参数,shell程序把这些参数用函数参数传递的方式传给给execve系统调用,然后execve系统调用以系统调用参数传递的方式传给sys_execve,最后sys_execve在初始化新程序的用户态堆栈时,将这些参数放在main函数取参数的位置上。条件满足。
  • 条件4:如果当前系统中没有所需要的资源,那么新进程会被挂起,直到资源有了,唤醒新进程,变为可运行态,条件可以满足。
    综上所述,新的可执行程序可以顺利执行。

3.对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同?

  • execve系统调用会调用sys_execve,然后sys_execve调用do_execve,然后do_execve调用do_execve_common,然后do_execve_common调用exec_binprm,在exec_binprm中:对于ELF文件格式,fmt函数指针实际会执行load_elf_binary,load_elf_binary会调用start_thread,在start_thread中通过修改内核堆栈中EIP的值,使其指向elf_entry,跳转到elf_entry执行。
  • 对于静态链接的可执行程序,elf_entry是新程序的执行起点。对于动态链接的可执行程序,需要先加载链接器ld,
    elf_entry = load_elf_interp(…) 将CPU控制权交给ld来加载依赖库,再由ld在完成加载工作后将CPU控制权还给新进程。

4.总结
Linux系统可以通过execve API启动一个新进程,该API又调用sys_execve,负责将新的程序代码和数据替换到新的进程中,打开可执行 文件,载入依赖的库文件,申请新的内存空间,最后执行 start_thread(regs, elf_entry, bprm->p) ,设置 new_ip, new_sp ,完成新进程的代码和数据替换,然后返回,接下来就是执行新的进程代码了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值