可执行程序的工作原理

(一)ELF目标文件

(1)什么是ELF?

这里先提一个常见的名词“目标文件”,是指编译器生成的文件。ELF(Executable and Linkable Format),即可执行的和可链接的格式,是一个目标文件格式的标准,这种格式的文件用于存储Linux程序。

(2)ELF文件的3种类型

  • 可重定位文件

  • 可执行文件

  • 共享目标文件

(3)ELF文件的作用

  • 如果用于编译和链接,则编译器和链结器将把ELF文件看作节的集合,所有节由节头表描述,程序头表可选

  • 如果用于加载执行(可执行文件),则加载器将把ELF文件看作程序头表描述的段的集合,一个段可能包含又多个节和节头表可选

  • 如果是共享文件,则两者都含有

(二)程序编译

程序从源代码到可执行文件的步骤:预处理、编译、汇编、链接。

  • 预处理

gcc -E hello.c -o hello.i

  • 编译

gcc -S hello.i -o hello.s -m32

  • 汇编

gcc -c hello.s -o hello.o -m32

  • 链接

gcc hello.o -o hello -m32

(三)Linux系统构架与执行过程

(1)从内存角度看Linux系统的执行

(2)fork和execve的区别与联系

  • fork两次返回,第一次返回到父进程继续向下执行,第二次是子进程返回到ret_from_fork后正常返回用户态

  • execve在执行时陷入内核态,用execve中加载的程序把当前正在执行的进程覆盖掉,当系统调用返回时也就返回到新的可执行程序起点,即返回的已经不是原来的那个可执行程序了

(3)跟踪分析execve系统调用内核处理函数

1)将menu目录删除,利用git命令克隆一个新的menu目录,用test_exec.c将test.c覆盖

2)重新编译rootfs,查看代码发现增加了exec函数,执行exec指令,发现比fork指令多输出了一行“hello,Yizihan”,实际上是新加载了一个可执行程序来输出一行语句





3)启动内核到调试的状态,加载符号表并设置端口,启动新的终端窗口开始gdb调试,设置断点到“sys_exec” “load_elf_binary” “start_thread”







4)查看hello的elf的头部,查看定义的入口地址

5)实验中test.c中增加的代码如下:

int Exec(int argc, char *argv[])
{
int pid;
/* fork another process */
pid = fork();
if (pid < 0)
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-1);
}
else if (pid == 0)
{
/* child process */
printf("This is Child Process!\n");
execlp("/hello","hello",NULL);
}
else
{
/* parent process */
printf("This is Parent Process!\n");
/* parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete!\n");
}
} int main()
{
PrintMenuOS();
SetPrompt("MenuOS>>");
MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
MenuConfig("quit","Quit from MenuOS",Quit);
MenuConfig("time","Show System Time",Time);
MenuConfig("time-asm","Show System Time(asm)",TimeAsm);
MenuConfig("fork","Fork a new process",Fork);
MenuConfig("exec","Execute a program",Exec);
ExecuteMenu();
}

(四)总结

execve()的系统调用实质试运行的内核态的函数,大致处理过程总结如下:

(1)sys_execve中的do_execve()读取128个字节的文件头部,以此判断可执行文件的类型

(2)调用search_binary_handle()去搜索和匹配合适的可执行文件转载处理过程

(3)ELF文件由load_elf_binary()函数负责装载,它调用了sart_thread函数,创建新进程的堆栈,修改了终端现场中保存的ELP寄存器,这里分静态链接和动态链接两种:

  • 静态链接:elf_entry指向可执行文件的头部,一般是main函数,是新程序执行的起点,,新的可执行程序的起点的一般地址为0x8048xxx的位置,由编译器设定,可能是由于安全上的考虑并不严格固定

  • 动态链接:elf_entry指向ld(动态链接器)的起点load_elf_interrp

2019-2020-1 20199305《Linux内核原理与分析》第八周作业的更多相关文章

  1. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  3. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  4. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  5. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  6. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. 基于USB3.0的双目相机测试小结之CC1605配合CS5642 双目 500w摄像头

    基于USB3.0的双目相机测试小结之CC1605配合CS5642  双目 500w摄像头 CC1605双目相机评估板可以配合使用柴草电子绝大多数摄像头应用 如:OV5640.OV5642.MT9P03 ...

  2. 2.成产出现 max(vachar2)取值问题

    uat 测试结果正确max(9)>max(8),结果生产出现 max(9)>max(12) 原因:字符类型,默认比较第一个字符的ASCII码. 解决方式: max(to_number(va ...

  3. Java_编写99乘法表

    public class Work100{ public static void main(String[] args){ // 积 int mu = 0; for(int i=1;i<10;i ...

  4. Django之视图层与模板层

    目录 视图层 小白必会三板斧 HttpResponse render redirect JsonResponse 前后端分离 FBV CBV 给CBV加装饰器 模板层 模板语法 模板传值 过滤器 语法 ...

  5. 《Java知识应用》Java Json说明和使用(fastjson)

    工具包下载:链接: https://pan.baidu.com/s/1dn5uNwiJ1ICkbPknlMmkHQ 提取码: ayzn 复制这段内容后打开百度网盘手机App,操作更方便哦 1.JSON ...

  6. 这几种JavaScript语法不要轻易使用,容易出事

    文章目录 12种不宜使用的JavaScript语法 1. == 2. with 3. eval 4. continue 5. switch 贯穿 6. 单行的块结构 7. ++和-- 8. 位运算符 ...

  7. 使用saltstack自动部署K8S

    使用saltstack自动部署K8S 一.环境准备 1.1 规划 1. 操作系统 CentOS-7.x-x86_64. 2. 关闭 iptables 和 SELinux. 3. 所有节点的主机名和 I ...

  8. 【Web前端开发】---自学转行roadmap

    [Web前端开发] 自学转行roadmap: ● html/css ● 京东项目实操 ● javascript 基础 ● webapi ● javascrip高级 ● jquery基础 ● Ajax ...

  9. Cortex-A7 MPCore 简介与处理器运行模型

    Cortex-A7 MPcore 处理器支持 1~4 核,通常是和 Cortex-A15 组成 big.LITTLE 架构的,Cortex-A15 作为大核负责高性能运算,比如玩游戏啥的,Cortex ...

  10. C语言搬书学习第一记 —— 认识一个简单程序的细节

    #include<stdio.h> /*告诉编译器把stdio.h 中的内容包含在当前程序中,stdio.h是C编译器软件包的标准部分,它提供键盘输入和 屏幕输入的支持studio.h文件 ...