Linux内核如何装载和启动一个可执行程序

1.理解编译链接的过程和ELF可执行文件格式,详细内容参考本周第一节;​

2.编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式,详细内容参考本周第二节;

3.使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve ,验证您对Linux系统加载可执行程序所需处理过程的理解,详细内容参考本周第三节;推荐在实验楼Linux虚拟机环境下完成实验。

4.特别关注新的可执行程序是从哪里开始执行的?为什么execve系统调用返回后新的可执行程序能顺利执行?对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同


一、理解编译链接的过程和ELF可执行文件格式:

1.预处理、编译、链接:

<1>预处理,处理代码中的宏定义和 include 文件,并做语法检查

gcc -E hello_world.c -o hello_world.i

<2>编译,生成汇编代码

gcc -S hello_world.i -o hello_world.s

<3>汇编,生成 ELF 格式的目标代码

gcc -c hello_world.s -o hello_world.o

<4>链接,生成可执行代码

gcc hello_world.o -o hello_world

<5>执行程序

./hello_world hello, world!

2.ELF文件格式:

ELF 格式:可执行和可链接(Executable and Linkable Format) 是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储的标准文件格式。

可重定位文件,如:.o 文件,包含代码和数据,可以被链接成可执行文件或共享目标文件,静态链接库属于这类。

可执行文件,如:/bin/bash 文件,包含可直接执行的程序,没有扩展名。

共享目标文件,如:.so 文件,包含代码和数据,可以跟其他可重定位文件和共享目标文件链接产生新的目标文件,也可以跟可执行文件结合作为进程映像的一部分。

ELF 文件由 ELF header 和文件数据组成,文件数据包括:

Program header table, 程序头:描述段信息

.text, 代码段:保存编译后得到的指令数据

.data, 数据段:保存已经初始化的全局静态变量和局部静态变量

Section header table, 节头表:链接与重定位需要的数据

二、编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式:

链接,是收集和组织程序所需的不同代码和数据的过程,以便程序能被装入内存并被执行。一般分为两步:1.空间与地址分配,2.符号解析与重定位。一般有两种类型,一是静态链接,二是动态链接。

使用静态链接的好处是,依赖的动态链接库较少(这句话有点绕),对动态链接库的版本更新不会很敏感,具有较好的兼容性;不好地方主要是生成的程序比较大,占用资源多。使用动态链接的好处是生成的程序小,占用资源少。动态链接分为可执行程序装载时动态链接和运行时动态链接。

当用户启动一个应用程序时,它们就会调用一个可执行和链接格式映像。Linux 中 ELF 支持两种类型的库:静态库包含在编译时静态绑定到一个程序的函数。动态库则是在加载应用程序时被加载的,而且它与应用程序是在运行时绑定的。


首先更新linux/kernel下的menu,并将test_exec变成test.c

进入内核,查看exec命令是否添加进入内核

退出内核,新建terminal进行gdb调试查看

gdb中与内核建立联系

file linux-3.18.6/vmlinux
target remote:1234

内核中对sys_execve,load_elf_binary,start_thread进行断点调试,c执行,list列出代码,并进行单步调试。

内核运行


分析exec*函数对应的系统调用处理过程:

1.我们通过跟踪以及查看分析代码,执行的流程是:(代码见上面) sys_execve -> do_execve -> do_execve_common -> exec_binprm -> search_binary_handler -> load_binary ->(对于我们这里的ELF,会跳转到)load_elf_binary(也执行了elf_format)-> start_thread

2.我们调用execve的可执行程序时,当执行到exceve时,系统调用exceve陷入内核,这时会创建一个新的用户态堆栈,实际是把命令行参数的内容和环境变量的内容通过指 针的方式传递给系统调用内核处理函数的,然后内核处理函数在创建可执行程序新的用户态堆栈的时候,会把这些拷贝到用户态堆栈初始化新的可执行程序的执行上下文环 境(先函数调用参数传递,再系统调用参数传递)。这时就加载了新的可执行程序。系统调用exceve返回用户态的时候,就变成了被exceve加载的可执行程序。

2019-2020-1 20199325《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. ARDUINO UNO数字引脚端口上电后不稳定状态。

    ARDUINO UNO数字引脚端口上电后不稳定状态. 在使用4*4矩阵键盘时,遇到了输入端的电平无法稳定,一直被识别为高电平. 在发现这一问题后,首先检查程序是否出错.检查后发现程序没有任何问题. 于 ...

  2. 数据库连接JOIN

    1,连接类型及差异 INNER JOIN:结果集只有配对成功的数据,即不包含左表或右表为空的情况: OUTER JOIN: LEFT JOIN:结果包含左表的所有记录,右表不能成功匹配的显示NULL ...

  3. python ——钟表

    1.表盘 from turtle import * from datetime import * def Skip(step):#表盘不连续地画图 penup() forward(step) pend ...

  4. ArrayList源码浅析

    这里只理解主要的常用方法: 1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E ...

  5. 从养孩子谈谈 IO 模型(一)

    同步/异步.阻塞/非阻塞 说的是一回事儿吗? 同步/异步.阻塞/非阻塞 你能通俗易懂的讲清楚吗? Java 中的 BIO.NIO.AIO 你了解吗? Socket 编程你还会吗? Linux 操作系统 ...

  6. VUE CLI3.0安装及配置

    # 安装 npm install -g @vue/cli # 查看已安装版本vue --version 或者 vue -V # 卸载 npm uninstall @vue/cli -g # 新建项目 ...

  7. Golang笔记集

    学习Golang了, 下面分享我的, 还有我收集的Golang的学习资料 我的基础笔记地址: https://github.com/zhuchangwu/go-study-notes 其他参考: Go ...

  8. Spring (五):AOP

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...

  9. Spring(四):使用注解开发

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...

  10. 关于微信小程序的一点经验

    2018年的11月份,自己做微信小程序相关的项目已经有四个月,这四个月自己走过很多弯路,也学到了不少经验,下面就一一总结: 一,微信小程序的radio组件是可以改变按钮样式的(比如大小,颜色等等) 改 ...