作业七:Linux内核如何装载和启动一个可执行程序
作业七:Linux内核如何装载和启动一个可执行程序
一、编译链接的过程和ELF可执行文件格式
可执行文件的创建——预处理、编译和链接 在object文件中有三种主要的类型。
一个可重定位(relocatable)文件保存着代码和适当的数据,用来和其他的object文件一起来创建一个可执行文件或者是一个共享文件。
一个可执行(executable)文件保存着一个用来执行的程序;该文件指出了exec(BA_OS)如何来创建程序进程映象。
一个共享object文件保存着代码和合适的数据,用来被下面的两个链接器链接:
-第一个是连接编辑器[请参看ld(SD_CMD)],可以和其他的可重定位和共享object文件来创建其他的object。
-第二个是动态链接器,联合一个可执行文件和其他的共享object文件来创建一个进程映象。 一个object文件被汇编器和联接器创建, 想要在处理机上直接运行的object文件都是以二进制来存放的。
那些需要抽象机制的程序,比如shell脚本,是不被接受的。
Object文件格式
Linking 视角 Execution 视角
============ ==============
ELF header ELF header
Program header table (optional) Program header table
Section 1 Segment 1
... Segment 2
Section n ...
Section header table Section header table (optional)
一个ELF头在文件的开始,保存了路线图(road map),描述了该文件的组织情况。
sections保存着object 文件的信息,从连接角度看:包括指令,数据,符号表,重定位信息等。特别sections的描述会出项在以后的第一部分。
第二部分讨论了段和从程序的执行角度看文件。
假如一个程序头表(program header table)存在,那么它告诉系统如何来创建一
个进程的内存映象。被用来建立进程映象(执行一个程序)的文件必须要有一个程
序头表(program header table);可重定位文件不需要这个头表。一个
section头表(section header table)包含了描述文件sections的信息。每个
section在这个表中有一个入口;每个入口给出了该section的名字,大小,
等等信息。在联接过程中的文件必须有一个section头表;其他object文件可要
可不要这个section头表。
注意: 虽然图显示出程序头表立刻出现在一个ELF头后,section头表跟着其他
section部分出现,事实是的文件是可以不同的。此外,sections和段(segments)
没有特别的顺序。只有ELF头(elf header)是在文件的固定位置。
数据表示
object文件格式支持8位、32位不同的处理器。不过,它试图努力的在更大
或更小的体系上运行。因此,object文件描绘一些控制数据需要用与机器
无关的格式,使它尽可能的用一般的方法甄别object文件和描述他们的内容。
在object文件中剩余的数据使用目标处理器的编码方式,不管文件是在哪台
机子上创建的。


二、动态链接分为可执行程序装载时动态链接和运行时动态链接
三、使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve




实验楼环境图



四、特别关注:
1.新的可执行程序是从哪里开始执行的? 2.为什么execve系统调用返回后新的可执行程序能顺利执行? 3.对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同?
.ELF可执行文件会被默认映射到0x804800地址
execve内核态,可执行文件覆盖了原来的,返回时是新的可执行程序,也就是main函数发生的起点,加载新的可执行可执行环境。
需要动态链接的可执行文件先加载链接器ld
命令行参数和环境串都放在用户态堆栈中。
将CPU控制权交给LD来加载依赖库并完成动态链接。然后在初始化新程序堆栈时,拷贝进去,先函数调用参数传递,在系统调用参数传递
shell程序——>execve ——>sys_execve
do_execve----> do_execve_common----->exec_vinprm------>search_binary_handler
execve系统调用返回到用户态
栈底pt_regs start_thread(...,elf_entry,....)
通过修改内核堆栈中EIP的值作为新程序的起点。new ip, new sp.
elf_entry是新的可执行程序的起点。
静态链接:程序开始是从0x8048300或0x8048400,也就是main开始的位置
动态链接:动态链接器的起点。
五、总结部分:对“Linux内核装载和启动一个可执行程序”的理解
.ELF可执行文件会被默认映射到0x804800地址 execve内核态,可执行文件覆盖了原来的,返回时是新的可执行程序,也就是main函数发生的起点,加载新的可执行可执行环境。
shell程序——>execve ——>sys_execve
do_execve----> do_execve_common----->exec_vinprm------>search_binary_handler 栈底pt_regs start_thread(...,elf_entry,....)
通过修改内核堆栈中EIP的值作为新程序的起点。new ip, new sp.
elf_entry是新的可执行程序的起点。
静态链接:程序开始是从0x8048300或0x8048400,也就是main开始的位置
动态链接:需要动态链接的可执行文件先加载链接器ld,先从动态链接器开始,链接完成后,然后才返回到main函数起点。 将CPU控制权交给LD来加载依赖库并完成动态链接。然后在初始化新程序堆栈时,拷贝进去,先函数调用参数传递,在系统调用参数传递
**注明“郑伟 +
参考资料:
【1】http://www.xfocus.net/articles/200105/174.html
【2】http://mooc.study.163.com/learn/USTC-1000029000?tid=2001214000#/learn/hw?id=2001372010
- 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”**
可以结合实验截图、ELF可执行文件格式、用户态的相关代码等; 博客内容中需要仔细分析新可执行程序的执行起点及对应的堆栈状态等。
作业七:Linux内核如何装载和启动一个可执行程序的更多相关文章
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
- 实验七:Linux内核如何装载和启动一个可执行程序
原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 题目自拟,内容围绕对Linu ...
- linux内核分析 第七周 Linux内核如何装载和启动一个可执行程序
一.编译链接的过程和ELF可执行文件格式 vi hello.c gcc -E -o hello.cpp hello.c -m32 //预处理.c文件,预处理包括把include的文件包含进来以及宏替换 ...
- Linux内核设计第七周学习总结 Linux内核如何装载和启动一个可执行程序
陈巧然原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 实验目的 使用gdb跟踪s ...
- Linux内核如何装载和启动一个可执行程序(转)
原文:http://www.cnblogs.com/petede/p/5351696.html 实验七:Linux内核如何装载和启动一个可执行程序 姓名:李冬辉 学号:20133201 注: 原创作品 ...
- 20135202闫佳歆--week 7 Linux内核如何装载和启动一个可执行程序--实验及总结
week 7 实验:Linux内核如何装载和启动一个可执行程序 1.环境搭建: rm menu -rf git clone https://github.com/megnning/menu.git c ...
- 20135323符运锦----第七周:Linux内核如何装载和启动一个可执行程序
可执行程序的装载 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 ①编译器预处理 gcc -E -o XX.cpp XX.c (-m32)// 注:把include的文件包含进来, ...
- Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序
1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...
- 第七周——Linux内核如何装载和启动一个可执行程序
万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 part1 实验 ...
随机推荐
- 08 LaTeX学习系列之---Latex 的中文操作
目录 目录: (一)方法一:导入 ctex 宏包 1.说明: 2.源代码: 3.效果展示: (二)使用ctex的文档类 1.说明: 2.源代码: 3.显示效果: (三)查看帮助 1.Ctex的使用手册 ...
- 怎样将本地web数据库项目部署到腾讯云服务器上?
怎样将本地web数据库项目 部署到腾讯云服务器上? 1.本地计算机的工作: 1.1用eclipse或者myeclipse做好一个web项目,可以只做一个数据库的增删改查,本地部署到Tomcat服务器, ...
- Postgresql 截取字符串
截取字符串一般用 substring 就够用了.对于有些长度不定的就没法用这个函数了,但还是有规律的,可以某个字符分割. 如:(这是一个url,截取最后一部分.现在要取 - 后面部分内容) 8a59e ...
- mysql 存儲emjoy表情是報錯Incorrect string value:
解决方法: [mysqld] character-set-client-handshake=FALSE character-set-server=utf8mb4 collation-server=ut ...
- [转]Qt中定时器使用的两种方法
Qt中定时器的使用有两种方法,一种是使用QObject类提供的定时器,还有一种就是使用QTimer类. 其精确度一般依赖于操作系统和硬件,但一般支持20ms.下面将分别介绍两种方法来使用定时器. 方法 ...
- python基础学习第二天
读文件 r 要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符 写文件 w 写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符’w’或者’w ...
- ubuntu RPLIDAR A2的使用
RPLIDAR是由RoboPeak Team,SlamTec公司开发的低成本2D LIDAR解决方案.它可以扫描6度半径内的360°环境. RPLIDAR的输出非常适合构建地图,做slam或构建3D模 ...
- Android ExpandableListView和ScrollView联用的一些注意事项
之前有整理过ScrollView嵌套ListView的例子,讲的是计算listview的每一项的高度.已达到目标效果.同样的ExpandableListView嵌套ScrollView也是这么个思路, ...
- Omi框架学习之旅 - 组件通讯(data通讯) 及原理说明
接着上一篇的data-*通讯,这篇写data通讯. data通讯主要为了复杂的数据通讯. 老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明. class Hello exten ...
- vbox虚拟机和vm虚拟机 虚拟机网络不通的解决方法
vm网络不通的情况: 第一步 :打开物理机, 选中“计算机”*(,右键—管理—服务,找到以VM开头的服务,选中后,右键—启动,就可以了.如图: 第二步: 这样基本就可以了,如果还不行 如果重启失效了, ...