一 程序的装载和运行的基本知识补充

   1 当进程开始执行一个新的程序时,从父进程继承的所有页被释放,以便在新的用户地址空间开始执行新的计算,甚至进程的特权都可能发生改变,但是,进程的PID不会改变。

2 进程的信任状和权能

进程的信任状决定一个进程的权限,也就是能做什么,不能做什么。这对多用户系统,系统的稳定性很重要。

进程被创建时,总是继承父进程的信任状。

权能是引入进程信任状的另一种模式。他表示是否允许进程执行一个特定的操作或一组特定的操作。

3 目标文件不能被执行,因为它不含源代码文件所用的全局外部符号名的线性地址,这些地址的分配是由链接程序完成的。链接程序还分析程序所用的库函数。

4 静态链接生成的可执行文件不仅包含原程序的代码,还包含程序所引用的库函数的代码。缺点是占用大量的磁盘空间。

动态链接程序把一个共享库链接到进程时,不拷贝目标代码,仅执行一个内存映射,把库文件的相关部分映射到进程的地址空间中,缺点是程序的启动时间较长。

二 跟踪分析执行程序的系统调用execve()

2.1在以前的代码基础上添加

    

main()添加:

利用qemu查看调试结果(相关的基本设置可以参考前面博客)

设置断点:

执行,停在第一个断点处:

继续执行,停在do_open_exec:

继续执行:

输入exec:

发现程序停在:

执行:

接着执行:

分析:新的可执行程序是从哪里开始执行的?

我们知道只有pc能代表程序的执行流, 父进程fork创造椅子进程,子进程执行新的可执行程序,当子进程“获得”pc时,才是子进程(可执行程序)开始执行的地方。通过GDB跟踪以及阅读源码,

void start_thread(struct pt_regs *regs, unsigned long new_pc,
unsigned long new_sp)
{
regs->pr = 0;
regs->sr = SR_FD;
regs->pc = new_pc;
regs->regs[15] = new_sp; free_thread_xstate(current);
}

  可以看到在函数load_elf_binary()的最后调用了函数start_thread(regself_entrybprm->p),所以elf_entry是可执行程序开始执行的地方。

为什么execve系统调用返回后新的可执行程序能顺利执行?

因为在系统调用过程中,父进程的大部分资源被抛弃,堆栈被清空,新的可执行程序根据传递的参数和环境变量配置了一个新的堆栈。所以返回时能够正常执行。

对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同?

在函数load_elf_binary中可以看到如下的一段代码:

887	if (elf_interpreter) {
888 unsigned long interp_map_addr = 0;
889
890 elf_entry = load_elf_interp(&loc->interp_elf_ex,
891 interpreter,
892 &interp_map_addr,
893 load_bias);
894 if (!IS_ERR((void *)elf_entry)) {
895 /*
896 * load_elf_interp() returns relocation
897 * adjustment
898 */
899 interp_load_addr = elf_entry;
900 elf_entry += loc->interp_elf_ex.e_entry;
901 }
902 if (BAD_ADDR(elf_entry)) {
903 retval = IS_ERR((void *)elf_entry) ?
904 (int)elf_entry : -EINVAL;
905 goto out_free_dentry;
906 }
907 reloc_func_desc = interp_load_addr;
908
909 allow_write_access(interpreter);
910 fput(interpreter);
911 kfree(elf_interpreter);
912 } else {
913 elf_entry = loc->elf_ex.e_entry;
914 if (BAD_ADDR(elf_entry)) {
915 retval = -EINVAL;
916 goto out_free_dentry;
917 }

 我们知道 elf_entry是系统调用返回时可执行文件开始执行的地方,由以上代码,通过静态链接返回时,elf_entry代表的是可执行文件规定的头部,而动态链接,elf_entry代表的是动态链接器的起点。

三 总结

自己对“Linux内核装载和启动一个可执行程序”的理解

通过以上的学习,我们知道装载和启动一个可执行程序主要是通过系统调用execve()来实现的,和普通的系统调用不同,execve系统调用返回时不是INT $0x80语句的后面一条语句,而是变成了一个新的进程,按照用户要求(参数和环境变量)创建的可执行程序。

通过一系列函数调用:do_execve()->do_execve_common()->exec_binprm()->search_binary_handler()->list_for_each_entry()->load_binary()->load_elf_binary()->start_thread(),

start_thread(regself_entrybprm->p)中修改了ip,elf_entry是可执行程序开始执行的地方。

by:方龙伟

原创作品 转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

linux内核学习之七 可执行程序的装载和运行的更多相关文章

  1. Linux内核分析之可执行程序的装载和启动

    一.内容分析 1.可执行文件的创建 (1)预处理阶段 预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换,预处理过程还会删除程序中的注释和多余的空白字符.其中预处理指令主 ...

  2. Linux第七周学习总结——可执行程序的装载

    Linux第七周学习总结--可执行程序的装载 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/course/ ...

  3. Linux内核分析——Linux内核学习总结

    马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核学习总结 一 ...

  4. Linux内核学习期末总结(网课)

    标签(空格分隔): 20135321余佳源 余佳源(原创作品转载请注明出处) <Linux内核分析> MOOC课程http://mooc.study.163.com/course/USTC ...

  5. 关于Linux内核学习的一点点总结

    关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...

  6. linux内核学习之二:编译内核

    在linux内核学习系列的第一课中讲述了搭建学习环境的过程(http://www.cnblogs.com/xiongyuanxiong/p/3523306.html),环境搭好后,马上就进入到下一环节 ...

  7. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  8. 20135316王剑桥Linux内核学习笔记

    王剑桥Linux内核学习笔记 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计算机是如何工作的 个人理 ...

  9. Linux 内核学习的经典书籍及途径

    from:http://www.zhihu.com/question/19606660 知乎 Linux 内核学习的经典书籍及途径?修改 修改 写补充说明 举报   添加评论 分享 • 邀请回答   ...

随机推荐

  1. [SQL] SQL 查出一张表中重复的所有记录

    在A表中存在一个字段“AccountId”,而且不同记录之间的“AccountId”值有可能会相同,现在就是需要查询出在该表中的各记录之间,“AccountId”值存在重复的项,这里count记录该字 ...

  2. json_encode 中文乱码

    用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似"\u***"的格式, 还会在一定程度上增加传输的数据量. 而在PHP5.4, 这个问题终 ...

  3. jquery TypeError: $(...).live is not a functio,动态添加class的点击事件处理

    jq版本更新后无live函数的处理.TypeError: $(...).live is not a function jquery live函数语法 jquery版本更新, 发现一个问题: jq自带的 ...

  4. 完美解释if-modified-since/not-modified 文件头的意义

    http://www.cnblogs.com/zh2000g/archive/2010/03/22/1692002.html 很好很强大

  5. Failed: error processing document #281: unexpected EOF,往MongoDB当中插入json文件时出现的错误。

    往MongoDB当中插入json文件时提示的错误(我的操作系统是win10): 当时的执行命令是:mongoimport -d test -c restaurants d://primer-datas ...

  6. linux命令格式及基础命令(一)

    linux命令格式 ~]#COMMAND [选项] [参数] 例如: ~]#ls 不带任何选项和参数 ``` stylus ~]#ls -lh /etc 列出/etc下所有文件和目录,同时要求以格式和 ...

  7. Unity中Time.deltaTime的含义及其应用

    The time in scenes it took to complete the last frame.这是使用此函数的时候给出的提示 一般我们会在设置速度的时候看到这个函数.先写出我对Time. ...

  8. JDBC/PreparedStatement

      JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力     JDBC  AP 是Sun公司提供的I 内容:供程序员调用的接口,集成在Java.sql和javax.sql包中, 如 ...

  9. Asp.net有关访问页面权限的限制和错误页面配置

    一.访问页面权限的限制 一个小项目,涉及到用户登录. 在用户没登录访问内容也时,对页面做一定限制,没登录的则不能访问,直接跳转到登录界面. /// <summary> /// 对没有登录用 ...

  10. 机器学习之KNN算法思想及其实现

    从一个例子来直观感受KNN思想 如下图 , 绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形 ...