Linux内核分析第七周———可执行程序的装载
Linux内核分析第七周———可执行程序的装载
李雪琦+原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、知识要点:
Linux中,可以从c源代码生产一个可执行程序,这其中要经过预处理、编译和链接的过程。可以参考以下图来理解这个过程:

其中,目标文件中至少有编译后的机器指令代码、数据,也还包括了链接时所须要的一些信息,比如符号表、调试信息、字符串等。这Linux中,可执行文件的格式现在主要是ELF格式(对应于Windows中PE格式)。ELF的格式如下:

链接,是收集、组织程序所需的不同代码和数据的过程,以便程序能被装入内存并被执行。
链接过程分为两步:
- 1.空间与地址分配
- 2.符号解析与重定位
在Linux中,一个程序的执行是做为一个新的进程,使用execve系统调用完成的。execve对应的系统调用是sys_execve,在其内部会解析可执行文件格式。对应的内核代码,就是,在search_binary_handler中寻找符合文件格式对应的解析模块,关键代码如下:

对于ELF文件,retval = fmt->load_binary(bprm)实际上执行的就是load_elf_binary,其内部就是按照ELF文件格式来加载ELF文件的。这里,我们也可以看到Linux是可以支持多种可执行文件格式的,所有的格式处里信息用一个结构体存储在一个链表中,其中的load_binary是一个函数指针,对应于该中格式的可执行文件的加载方式;要想支持一种新的可执行文件,只需要向链表中注册一个新的format结构体就可以了,此种设计类似观察者模式,具有很好的扩展性。
二、实验过程:
打开实验楼中的虚拟机,在shell中依次运行以下命令,获取本次实验的代码,并编译运行
cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
效果如下:

关闭QEMU窗口,在shell窗口中,cd LinuxKernel回退到LinuxKernel目录,使用下面的命令启动内核并在CPU运行代码前停下以便调试:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
接下来,我们就可以水平分割一个新的shell窗口出来,依次使用下面的命令启动gdb调试
gdb
(gdb) file linux-3.18.6/vmlinux
(gdb) target remote:1234
并在系统调用sys_execve的入口处设置断点
(gdb) b sys_execve
继续运行程序,在QEMU窗口中输入exec,系统就会停在上面设置的断点处,如图:

接下来我们可以单步跟踪sys_execve的内核代码,也可以通过设置以下断点
b load_elf_binary
b start_thread
来完整地跟踪进程的创建和启动代码。
三、总结:
Linux系统可以通过execve API启动一个新进程,该API又呼叫sys_execve系统调用,负责将新的程序代码和数据替换到新的进程中,打开可执行 文件,载入依赖的库文件,申请新的内存空间,最后执行 start_thread(regs, elf_entry, bprm->p) ,设置 new_ip, new_sp ,完成新进程的代码和数据替换,然后返回,接下来就是执行新的进程代码了。
Linux内核分析第七周———可执行程序的装载的更多相关文章
- Linux内核分析 第七周 可执行程序的装载
张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第七 ...
- 20135327郭皓--Linux内核分析第七周 可执行程序的装载
第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 ...
- LINUX内核分析第七周——可执行程序的装载
一.得到一个可执行程序 1. 预处理.编译.链接 gcc hello.c -o hello.exe gcc编译源代码生成最终可执行的二进制程序,GCC后台隐含执行了四个阶段步骤. 预处理 => ...
- Linux内核设计第七周 ——可执行程序的装载
Linux内核设计第七周 ——可执行程序的装载 第一部分 知识点总结 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 编译链接的过程 预处理阶段 gcc -E -o XX.cpp ...
- linux内核设计第七周——可执行程序的装载
- LINUX内核分析第七周学习总结:可执行程序的装载
LINUX内核分析第七周学习总结:可执行程序的装载 韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
- LINUX内核分析第七周学习总结
LINUX内核分析第七周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...
- LINUX内核分析第七周学习总结——可执行程序的装载
LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
随机推荐
- TPO 02 - Desert Formation
TPO 02 - Desert Formation NOTE: 主要意思(大概就是主谓宾)用粗体标出:重要的其它用斜体: []中的是大致意思,可能与原文有关也可能无关,但不会离题 目的为训练句子/段落 ...
- HashMap 和 HashTable 到底哪不同 ?
HashMap 和 HashTable 到底哪不同 ? 2017/05/29 | 分类: 基础技术 | 1 条评论 | 标签: HASHMAP, HASHTABLE 分享到: 原文出处: 程序员赵鑫 ...
- day02——作业讲解
# 设定⼀个理想数字⽐如:66,让⽤户输⼊数字,如果⽐66⼤,则显示猜测# 的结果⼤了:如果⽐66⼩,则显示猜测的结果⼩了;只有等于66,显示猜测结果# 正确,然后退出循环 #升级版# 可以帮我们生成 ...
- Catch That Cow:BFS:加标记数组:不加标记数组
Catch That Cow Problem Description Farmer John has been informed of the location of a fugitive cow a ...
- Dev C++支持ISOC++11标准
报错如下: [Error] #error This file requires compiler and library support for the ISO C++ 2011 standard. ...
- Python多重赋值
可以将变量名视对象的一个链接 >>>foo1 = foo2 = 4.3 >>>foo1 is foo2 True >>>foo1 = 4.3 &g ...
- jQuery 判断浏览器
jQuery 浏览器判断,jQuery提供了一个 jQuery.browser 方法 来判断浏览器 可用值: safari opera msie mozilla 例如:if($.brows ...
- python序列成员资格
可以用做登录操作,判断用户名密码是否正确! 代码示例: database = [ ['], ['], ['], ['] ] username = input("UserName: " ...
- java-HttpGetPost-图片字节流上传
在java程序开发中经常用到与服务端的交互工作,主要的就是传递相应的参数请求从而获取到对应的结果加以处理 可以使用Get请求与Post请求,注意!这里的Get请求不是通过浏览器界面而是在程序代码中设置 ...
- Beta周王者荣耀交流协会第六次会议
1.立会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:袁玥 2. 时间跨度 2017年11月15日 19:00 — 19:10 ,总计10分钟. 3. 地点 一食堂 ...