《Linux内核分析》第七周学习总结 可执行程序的装载

第七周、可执行程序的装载

一、可执行程序是如何产生的?

(1).c文件gcc汇编形成.s和.asm汇编代码;

(2)汇编代码经过gas变成.o目标文件;

(3)目标文件变成可执行文件;

(4)可执行文件loader之后存储。

预处理:gcc –E –o hello.cpp hello.c –m32

编译:gcc –x cpp-output –S –o hello.s hello.cpp –m32  //编译为汇编代码

      gcc –x assembler –c hello.s –o hello.o –m32  //编译为目标代码

链接:gcc –o hello hello.o –m32

静态链:gcc –o hello.static hello.o –m32 –static

 

二、目标文件格式ELF

  1. 目标文件三种形式

(1)可重定位文件(用来和其他object文件一起创建下面两种文件)——.o文件

(2)可执行文件(指出了应该从哪里开始执行)

(3)共享文件(主要是.so文件,用来被链接编辑器和动态链接器链)

2.ELF格式:

(左半边是ELF格式,右半边是执行时的格式)

三、新的可执行文件是从哪开始执行的?

当execve()系统调用终止且进程重新恢复它在用户态执行时,执行上下文被大幅度改变,要执行的新程序已被

映射到进程空间,从elf头中的程序入口点开始执行新程序。

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

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

四、 为什么execve系统调用返回后新的可执行程序能顺利执行?

execve和fork都是特殊一点的系统调用:一般的都是陷入到内核态再返回到用户态。 fork父进程和一般进程调度一样,子进程返回到一个特定的点ret_from_fork,子进程是从ret_from_fork开始执行然后返回到用户态; execve特殊:执行到可执行程序--陷入内核--构造新的可执行文件--覆盖掉原可执行程序--返回到新的可执行程序,作为起点(也就是main函数) ,需要构造他的执行环境。

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

静态链接:elf_entry指向可执行文件的头部,一般是main函数;

动态链接:elf_entry指向ld的起点。

六、实验过程:

1.更新menu:

2.把init 和 hello 放到了rootfs.img目录下,所以在执行exec命令的时候就相当于自动了加载了hello程序:

3.gdb进行跟踪分析:

4.设置断点后,在MenoOS中输入exec进行调试:

七、总结:Linux内核如何装载和启动一个可执行程序:

1. 创建新进程
2. 新进程调用execve()系统调用执行指定的ELF文件
3. 调用内核的入口函数sys_execve(),sys_execve()服务例程修改当前进程的执行上下文;
当ELF被load_elf_binary()装载完成后,函数返回至do_execve()在返回至sys_execve()。ELF可执行文件的入口点取决于程序的链接方式:
1. 静态链接:elf_entry就是指向可执行文件里边规定的那个头部,即main函数处。
2. 动态链接:可执行文件是需要依赖其它动态链接库,elf_entry就是指向动态链接器的起点。
 多进程、多用户、虚拟存储的操作系统出现以后,可执行文件的装载过程变得非常复杂。引入了进程的虚拟地址空间;然后根据操作系统如何为程序的代码、数据、堆、栈在进程地址空间中分配,它们是如何分布的;最后以页映射的方式将程序映射进程虚拟地址空间。

  

时间: 2024-08-05 07:08:50

《Linux内核分析》第七周学习总结 可执行程序的装载的相关文章

LINUX内核分析第七周学习总结——可执行程序的装载

LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 (一)预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 2.目标文件的格式ELF 3.静态链接的ELF可执行文件和进程的地址空间 (二)可执行程序.共享库和动态加载 1.装载可执行程序之前的工作 2.装载时动态链接和运行时动态链接应用举例 (三)

Linux内核分析——第七周学习笔记20135308

第七周 可执行程序的装载 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么来的 C代码—>预处理—>汇编代码—>目标代码—>可执行文件 .asm汇编代码 .o目标码 a.out可执行文件 预处理负责把include的文件包含进来及宏替换工作. 2.目标文件的格式ELF (1)常见的ELF格式文件: (2)ABI——应用程序二进制接口 在目标文件中,他已经是二进制兼容,即适应二进制指令. (3)ELF中三种目标文件: 一个可重定位(relocatable)文件保存着代码和

LINUX内核分析第七周学习总结:可执行程序的装载

一.得到一个可执行程序 1. 预处理.编译.链接 gcc hello.c -o hello.exegcc编译源代码生成最终可执行的二进制程序,GCC后台隐含执行了四个阶段步骤.预处理 => 编译 => 汇编 => 链接预处理:编译器将C源代码中包含的头文件编译进来和执行宏替换等工作.gcc -E hello.c -o hello.i编译:gcc首先要检查代码的规范性.是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言.gcc –S hello.i –o

LINUX内核分析第六周学习总结——进程的描述和进程的创建

LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 进程的描述 进程描述符task_struct数据结构(一) 进程描述符task_struct数据结构(二) 进程的创建 进程的创建概览及fork一个进程的用户态代码 理解进程创建过程复杂代码的方法 浏览进程创建过程相关的关键代码 创建的新进程是从哪里开始执行的

LINUX内核分析第三周学习总结——构造一个简单的Linux系统MenuOS

LINUX内核分析第三周学习总结——构造一个简单的Linux系统MenuOS 黄韧(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 回顾: [计算机三个法宝] 1)存储程序计算机 2)函数调用堆栈 3)中断 [操作系统两把宝剑] 1)中断上下文的切换:保存现场和恢复现场 2)进程上下文的切换 一.使用gdb跟踪调试内核从start_kernel到init进程启动 使用实验楼的虚拟机打开

LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程

LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程 黄韧(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 Linux中进程调度的基本概念与相关知识 schedule函数如何实现进程调度 Linux进程的执行过程(一般情况与特殊情况) 宏观描述Linux系统执行 二.学习笔记 (一)进程切换的关键代码switch_to分析 进程进度与进程调度的时机分析 1.

《Linux内核分析》第一周学习小结 计算机是如何工作的?

<Linux内核分析>第一周.计算机是如何工作的? 20135204 郝智宇  一.存储程序计算机工作模型 1.      冯诺依曼体系结构: 数字计算机的数制采用二进制:计算机应该按照程序顺序执行. 内存保存指令和数据,CPU负责解释和执行这些指令. 2.    API: 程序员与计算机的接口界面. 3.    EIP: CALL  RET  IMP   二.X86汇编基础 1.      X86CPU的寄存器 E开头32位,R开头64位.   堆栈是计算机中非常基础性的东西. 2.    

20135327郭皓--Linux内核分析第七周 可执行程序的装载

第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.预处理,编译,链接和目标文件格式 1.可执行程序是怎么得来的 c代码->预处理->汇编代码->汇编器->目标代码->链接成可执行文件->加载到内核执行 2.目标文件的格式ELF 符号修饰标准.变量内层布局.函数调用方式等这些跟可执行代码二进制兼容性相关的内容称为ABI

&quot;Linux内核分析&quot;第七周

可执行程序的装载 张文俊+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.预处理.编译.链接和目标文件的格式 可执行程序是怎么得来的? 首先,编译器预处理:1.将头文件加载进来:2.将宏替换 gcc -E -o hello.cpp hello.c (-m32)//c预处理成cpp文件 第二步,将cpp(预处理后的文件)编译成汇编代码 gcc -x cpp-output -S -o h

Linux内核分析第七周作业

Linux内核如何装载和启动一个可执行程序 有了上次的教训,这次直接用vmware完成 (- ̄3 ̄)- 先观察MenuOS新增的函数 1 int Exec(int argc, char *argv[]) 2 { 3 int pid; 4 /* fork another process */ 5 pid = fork(); 6 if (pid < 0) 7 { 8 /* error occurred */ 9 fprintf(stderr,"Fork Failed!"); 10 e