Linux内核如何装载和启动一个可执行程序
王昭(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
-
Linux内核如何装载和启动一个可执行程序
- ELF文件是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储的标准文件格式,由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。
![]()
- 新可执行程序的执行起点及对应的堆栈状态:
- 新的可执行程序的执行起点为返回的内核态程序装载到用户态的可执行程序的入口程序地址,对应的堆栈状态因为被重新init,所以均为空,可以顺次执行在用户态的程序。
-
总结部分:Linux内核装载时首先对相应的可执行程序分配好资源,进行装配过程,完成执行上下文环境设置,变量赋值等操作,然后返回到用户态的主程序,对环境进行修改。在用户态执行的新可执行程序,用户态程序为其分配寄存器,调度资源执行其代码段程序。启动一个可执行程序后,接着利用内核态为其准备的上下文执行环境,执行它的程序。
- exec*系统调用fork系统调用只是将父进程的环境拷贝到子进程中,而没有用子进程来初始化创建的子进程,因此它并不能执行新的目标程序,而这一点又是程序设计所必须的。为此UNIX系统提供了通过exec系统调用,以便用指定目标程序更换进程的执行图象。系统中的绝大多数命令都是通过exec来执行的。不但shell进程所创建的子进程使用它来执行用户命令,shell进程本身和它的祖先进程也是用exec来启动执行的。
exec系统调用有多种不同的使用格式,不同之处在于有不同的名字和参数。
exec调用在程序中使子进程能执行自己的代码。 main() {
printf(“==system execl testing ==\n”); execl(“/bin/date”,“/bin/date”,0); printf(“execl failure!\n”); }
其中一个执行结果如下:
如果将execl所在行写成execl(“date”,”date”,0),则会有如下的执行结果: ===system execl testing=== execl failure!
程序的第一、第三行输出了判断信息,当execl调用成功时,因不执行程序中的语句,使第三行语句无法输出,该信息只当execl调用失败时才能输出。因此执行该程序获得上述两个不同的结果。
第二次execl调用失败的原因是execl调用的第一个参数必须是目标文件的完整路径名,而不能只用文件名。


浙公网安备 33010602011771号