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

一、ELF可执行文件格式

  • ELF格式分类:
  可重定位文件:用来和其他object文件一起创建可执行文件和共享文件

  可执行文件:指出应该从哪里开始执行

  共享文件:主要是.so文件,用来被链接编辑器和动态链接器链接
  (1)对ELF头的描述告诉系统如何创建一个进程的内存映像,section头表包含了描述文件sections的信息。当创建或增加一个进程映像时,理论上它会把

程序段拷贝到虚拟内存中某个段

  (2)ELF文件的头部规定了许多与二进制兼容性相关的信息。所以在加载ELF文件的时候,必须先加载头部,分析ELF的具体信息

  (3)entry代表刚加载过新的可执行文件之后的程序的入口地址,头部后是代码和数据,进程的地址空间是4G,上面的1G是内核用,下面的3G是程序使用。

默认的ELF头加载地址是0x8048000
  • 静态链接的ELF可执行文件和进程的地址空间:

1.可执行文件加载到内存

   加载效果:将代码段数据加载到内存中,再把数据加载到内存,默认从0x8048000地址开始加载

   启动一个刚加载过可执行文件的进程时,可执行文件加载到内存之后执行的第一条代码地址

   一般静态链接会将所有代码放在一个代码段,而动态链接的进程会有多个代码段

2.流程

  (1) 分析头部

  (2) 查看是否需要动态链接。如果是静态链接的ELF文件,那么直接加载文件即可。如果是动态链接的可执行文件,那么需要加载的是动态链接器

  (3) 装载文件,为其准备进程映像

  (4) 为新的代码段设定寄存器以及堆栈信息

二、实验内容

更新menu后用test.c覆盖test_exec.c,然后打开test.c(shitf+G 直接到文件尾的快捷键)

可以看到添加了exec命令,执行一个程序的功能。

其函数内容为

int Exec(int argc, char * argv[])
{
int pid;
/* fork another process */
pid = fork();
if (pid<0)
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-1);
}
else if (pid==0)
{
/* child process */
execlp("/bin/ls","ls",NULL);
}
else
{
/* parent process */
/* parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete!");
exit(0);
}
}

由于在Makefile中做了修改。编译的时候执行了hello.c

并把init 和 hello 放到了rootfs.img目录下,所以在执行exec命令的时候就相当于自动了加载了hello这个程序

下面是通过gdb进行跟踪分析

设置b sys_execve ,b load_elf_binary 断点

可以先停在sys_execve然后设置其他断点

new_ip是返回到用户态的第一条指令的地址

此时可以通过po new_ip和新窗口的 readelf -h helloc查看入口地址是否一致



可以看到hello的入口地址和new_ip的值都是0x8048d0a 。说明对hello程序链接到了执行程序中。

三、总结

在创建一个新的用户态堆栈的时候,实际上是把命令行参数的内容和环境变量的内容通过指针的方式传递到系统调用的内核处理函数的,内核处理函数在创建一个新的可执行堆栈的时候会将

命令行参数的内容和环境变量的内容拷贝到用户态堆栈里面来初始化新的可执行程序执行的上下文环境,先函数调用参数传递,在系统调用参数传递

shell程序 -> execve -> sys_execve
  • sys_execve的内部处理过程 ( 装载和启动一个可执行程序依次调用以下函数):
sys_execve() -> do_execve() -> do_execve_common() -> exec_binprm() -> search_binary_handler() -> load_elf_binary() -> start_thread()

Linux内核原理第八次作业的更多相关文章

  1. 2018-2019-1 20189221 《Linux内核原理与分析》第八周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第八周作业 实验七 编译链接过程 gcc –e –o hello.cpp hello.c / gcc -x cpp-o ...

  2. 2017-2018-1 20179205《Linux内核原理与设计》第八周作业

    <Linux内核原理与设计>第八周作业 视频学习及操作分析 预处理.编译.链接和目标文件的格式 可执行程序是怎么来的? 以C语言为例,经过编译器预处理.编译成汇编代码.汇编器编译成目标代码 ...

  3. 2019-2020-1 20199329《Linux内核原理与分析》第八周作业

    <Linux内核原理与分析>第八周作业 一.本周内容概述: 理解编译链接的过程和ELF可执行文件格式 编程练习动态链接库的两种使用方式 使用gdb跟踪分析一个execve系统调用内核处理函 ...

  4. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  5. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  6. 20169207《Linux内核原理及分析》第十三周作业

    第一周作业::对Linux的基本知识进行了了解,并对基本操作进行熟悉和应用. 第二周作业::了解了冯诺依曼体系结构.各种寄存器的功能和汇编指令的作用和功能. 第三周作业::这周主要了解了Linux系统 ...

  7. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  8. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  9. 2018-2019-1 20189221 《Linux内核原理与分析》第七周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第七周作业 实验六 分析Linux内核创建一个新进程的过程 代码分析 task_struct: struct task ...

随机推荐

  1. [原][译]JSBSim官方源码文档翻译(google翻译)

    /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS DOCUMENTATION ...

  2. ES6标准之基础

    let和const命令 ES6新增let命令,用于声明变量,是块级作用域. let声明的变量不会像var声明的变量发生“变量提升”现象,所以,变量一定要在声明后使用,不然就会报错. 暂时性死区:只要块 ...

  3. Confluence 6 示例 - https://confluence.atlassian.com/

    这里是有关存储空间和内存使用的情况,数据更新于 2013年04月: 数据库大小 2827 MB Home 目录占用空间大小 116 GB 平均内存消耗 1.9 GB 选择实例的数据库表格 数据(Dat ...

  4. redis的发布订阅、持久化存储、redis的主从复制

    redis的发布订阅 1. 创建redis配置文件 vim /opt/redis_conf/reids-6379.conf mkdir /data/6379 redis-server  redis-6 ...

  5. js中的object

    JavaScript is an object-based language based on prototypes, rather than being class-based. this引用对象 ...

  6. PAT 1054 The Dominant Color

    1054 The Dominant Color (20 分)   Behind the scenes in the computer's memory, color is always talked ...

  7. 通用Mapper环境下,mapper接口无法注入问题

    写了一个mapper接口 package com.nyist.mapper; import com.nyist.entity.User; import tk.mybatis.mapper.common ...

  8. 第一份offer

    11月6日参加的面试,今天签完三方,回头想想,感慨万千. (很多过程没有详细写,只保留了基本的客观事实,避免自吹嫌疑.....) 6号面试,当时来了能有100-200人,以川大和电子科大研究生为主,主 ...

  9. vue项目目录结构

    VUE项目目录结构 如上图所示,我们的目录结构就是这样的了. 目录/文件 说明 build 这个是我们最终发布的时候会把代码发布在这里,在开发阶段,我们基本不用管. config 配置目录,默认配置没 ...

  10. mysql 在 win 安装 最全攻略(附转载的乱码终极解决方案)以及解决data too long for column 'name' at row 1, 一种可能就是因为编码一致性问题.

    [博客园cnblogs笔者m-yb原创,转载请加链接,公众号aandb7, github.com/mayangbo666,QQ群927113708] https://www.cnblogs.com/m ...