2015108 李泽源

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

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

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

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

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

  5. 根据本周所学知识分析exec*函数对应的系统调用处理过程,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”,博客内容的具体要求如下:

    1. 题目自拟,内容围绕对Linux内核如何装载和启动一个可执行程序;

    2. 可以结合实验截图、ELF可执行文件格式、用户态的相关代码等;

    3. 博客内容中需要仔细分析新可执行程序的执行起点及对应的堆栈状态等。

    4. 总结部分需要阐明自己对“Linux内核装载和启动一个可执行程序”的理解

实验目的:

使用gdb跟踪sys_execve内核函数的处理过程,分析exec*函数对应的系统调用处理过程,理解Linux内核如何装载和启动一个可执行程序。

实验过程:

登陆实验楼虚拟机http://www.shiyanlou.com/courses/195

打开shell终端,执行以下命令:

cd LinuxKernel

rm -rf menu

git clone https://github.com/mengning/menu.git

cd menu

mv test_exec.c test.c

make rootfs

1

可以看到启动后的MenuOS已经包含了exec命令。

可以通过增加-s -S启动参数打开调试模式

qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img -s -S

打开gdb进行远程调试

gdb

file ../linux-3.18.6/vmlinux

target remote:1234

3

设置断点

b sys_execve

b do_execve

b do_execve_common

b exec_binprm

b search_binary_handler

b load_elf_binary

b start_thread

实验分析:

通过查看源码可以看出执行exec命令是通过调用execlp函数实现的,属于库函数exec*都是execve的封装例程。

4

装载和启动一个可执行程序依次调用以下函数:

sys_execve() -> do_execve() -> do_execve_common() -> exec_binprm() -> search_binary_handler() -> load_elf_binary() -> start_thread()

实验总结:

当linux内核或程序(例如shell)用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。

当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。

因为调用exec并不创建新进程,所以前后的进程ID并未改变。

exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。

参考资料:《UNIX环境高级编程第二版》

学习笔记:

程序编译链接过程

预处理:(.c -> .cpp)

gcc -E -o hello.cpp hello.c -m32

编译:(.cpp -> .s 汇编)

gcc -x cpp-output -S -o hello.s hello.cpp -m32

编译:(.s -> .o 二进制目标代码)

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

链接:(.o -> a.out)共享库

gcc -o hello hello.o -m32

静态编译:

gcc -o hello.static hello.o -m32 -static

c语言main函数格式:

int main(int argc, char *argv[])

int main(int argc, char *argv[], char *envp[])

库函数exec*都是execve的封装例程

execve函数格式:

int execve(const char * filename,char * const argv[ ],char * const envp[ ])

sys_execve -> do_execve -> do_execve_common ->  exec_binprm

说是exec系统调用,实际上在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是:

int execl(const char *path, const char *arg, ...);

int execv(const char *path, char *const argv[]);

int execle(const char *path, const char *arg, ..., char * const envp[]);

int execve(const char *path, char *const argv[], char *const envp[]);

int execlp(const char *file, const char *arg, ...);

int execvp(const char *file, char *const argv[]);

其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。

区别一:前4个取路径名作为参数,后2个取文件名作为参数;

区别二:参数表的传递(l表示list,v表示vector);

区别三:向新程序传递环境表。

动态链接:

装载时动态链接

gcc -shared shlibexample.c -o libshlibexample.so -m32

运行时动态链接

gcc -shared dllibexample.c -o libdllibexample.so -m32

主调程序

gcc main.c -o main -L /path/to/your/dir-l shlibexample -ldl -m32

aapu原创作品转载请注明出处《Linux内核分析》MOOC课

转载于:https://www.cnblogs.com/jorilee/p/5373125.html

Linux内核如何装载和启动一个可执行程序-----实验7相关推荐

  1. 通过分析exevc系统调用处理过程来理解Linux内核如何装载和启动一个可执行程序...

    前言说明 本篇为网易云课堂Linux内核分析课程的第七周作业,本次作业我们将具体来分析exec*函数对应的系统调用处理过程,来分析Linux内核如何来执行一个可执行程序,由于有一个在网易云课堂共同学习 ...

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

    李洋  原创作品转载请注明出处 <Linux内核分析>MOOC课程 首先简单介绍一下相关背景:ELF(Executable and Linking Format)是一种对象文件的格式,用于 ...

  3. linux 带ifdef运行程序_Linux内核如何装载和启动一个可执行程序

    郑斌+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验要求: 理解编译 ...

  4. linux 单步启动_Linux内核如何装载和启动一个可执行程序

    实验步骤: 1.先把menu删掉,在克隆一个,用test_exec.c覆盖掉test.c. 2.打开test.c.发现增加了一句MenuConfig. 3.打开Makefile,首先静态编译了hell ...

  5. 第七周 linux加载和启动一个可执行程序

    1. 前言 这里主要分析linux系统如何加载和启动一个可执行程序.一个源文件要想形成可执行文件,需要经过编译和链接才可以.也就是说源文件先要通过编译器编译成目标文件,然后利用链接器链接成可运行文件. ...

  6. 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响(一)

    从 2.4 到 2.6:Linux 内核可装载模 块机制的改变对设备驱动的影响 <?xml:namespace prefix = o ns = "urn:schemas-microso ...

  7. Linux入职基础-4.10_系统启动过程(3):Linux内核(vmlinuz)启动

    Linux系统启动过程(3):Linux内核(vmlinuz)启动 上节回顾:详解见上一篇<内核的引导程序>,内核模块在获取控制权后开始工作,内核(vmlinuz-2.6.18-238.e ...

  8. 【技术分享篇】Linux内核——手把手带你实现一个Linux内核文件系统丨Linux内核源码分析

    手把手带你实现一个Linux内核文件系统 1. 内核文件系统架构分析 2. 行行珠玑,代码实现 [技术分享篇]Linux内核--手把手带你实现一个Linux内核文件系统丨Linux内核源码分析 更多L ...

  9. linux 内核可装载模块 版本检查机制

    为保持 Linux 内核的稳定与可持续发展,内核在发展过程中引进了可装载模块这一特性.内核可装载模块就是可在内核运行时加载到内核的一组代码.通常 , 我们会在两个版本不同的内核上装载同一模块失败,即使 ...

最新文章

  1. trie树- 转自 维基百科
  2. c++ int自动转换成无符号变量产生的问题
  3. 鸿蒙os系统作用,华为再发新版鸿蒙OS系统!新增超级终端功能:可媲美iOS系统...
  4. 为什么现在年轻人都在寻找副业、兼职?难道只有物价生活成本上涨?
  5. JAVA后端开发浅谈
  6. linux安装i3wm桌面环境,ArchLinux基本安装后安装i3wm基本环境
  7. Liang-Barsky裁剪算法
  8. 累积你的All Blue-使用集成库-PCB系列教程1-4
  9. SolidWorks如何提取stp格式装配体中的零件图
  10. 我的世界刷猪人塔java版_我的世界猪人塔怎么做 5款猪人塔详解教程
  11. 计算机桌面所有的图标突然不见了怎么办,桌面上图标都不见了怎么办
  12. Matlab plot画图 坐标字体、字号、范围、间隔等的设置
  13. 更新again:微机原理与汇编语言-练习题
  14. CSS3中steps()动画的详解
  15. 超融合网络常见问题及解决思路
  16. http请求从浏览器到tomcat过程
  17. MyEclipse 快捷键大全(@Hcy)
  18. 面向对象三大特征之继承
  19. 区块链笔记:技术栈、对等网络、密码技术、账户模型、网络共识、脚本系统、扩展技术
  20. 【做一下1】python 监听数据库变化

热门文章

  1. t5810做虚拟服务器,戴尔Precision T5810工作站选用CPU的问题 | 小迪的生产力工具室...
  2. SATA协议固态硬盘的S.M.A.R.T详解
  3. 在ARM处理器架构下部署kettle etl工具注意事项
  4. windows下内存检测工具
  5. python画蜡烛致敬烈士_Matplotlib 蜡烛图教程
  6. python画蜡烛图_Python量化交易-绘制蜡烛图 !这个图不像你的钱哦!
  7. BatchNorm1d
  8. [LeetCode]Medium - Cutting Ribbons - python
  9. D2550运行Linux,也发一个128*128的相框lcd4linux的conf
  10. 乳腺仿体breast phantom的MATLAB实现及探讨