Linux进程的创建,执行与切换

linux进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换 进程创建、可执行文件的加载和进程执行进程切换进程进程描述符 task_structdo_fork过程合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图... 阅读详情

林弋力
224
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/

实验目的

理解Linux进程创建、可执行文件的加载和进程执行进程切换
重点理解分析fork、execve和进程切换

实验步骤

进程创建

在http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235中可以看到有如下代码段:
在这里插入图片描述
进程管理是操作系统提供的最基本的功能之一
为了描述进程,用进程控制块PCB来唯一地定义一个进程
tast_struct中定义了进程的标识、进程的状态、进程的调度策略等。如:状态state用-1、0、>0表示三种状态。其中,各部分依次是:进程的底层信息、指向内存区域描述符的指针、进程相关的tty设备、当前目录、指向文件描述符的指针、接收到的信号

Fort、vfort、clone都可以用来创建一个新的进程,他们都是调用了do_fork函数实现的

在代码中do_fork调用了copy_process来创建进程,总结起来有如下几个步骤:
1.复制当前的tast_struct
2.初始化进程,并将状态设为TASK_RUNNING
3.复制父进程的所有信息
4.调用copy_thread初始化子进程的内核栈
5.为新的进程分配设置新的pid

可执行文件的加载

Linux环境下,fork系统调用将会创建一个与当前task完全一样的新task,直到应用程序调用exec*系列的Glibc库函数最终调用execve系统调用之后,Linux内核才开始真正装载ELF可执行文件(映像文件)。execve内核入口为sys_execve,随之调用do_execve将查找这个可执行文件,如果找到则读取ELF可执行文件的前128个字节,然后调用search_binary_handle通过ELF文件头中的e_ident得到可执行文件的Magic Number,判断出这是一个什么类型的可执行文件,并调用不同可执行文件的装载处理程序,对于ELF可执行文件而言,其装载处理程序为load_elf_binary,这个函数将会把execve系统调用的返回地址修改为ELF可执行文件的入口点,对于静态链接得到的ELF文件即文件头中定义的e_entry,对于动态链接得到的ELF可执行文件则是动态链接器。一步一步返回到sys_execve之后,因为返回地址已经被修改为了ELF程序入口地址了,所以系统调用返回到用户态之后,EIP指令寄存器将直接跳转到ELF程序入口地址,程序开始执行,装载完成。
即:fork-- execve() – sys_execve() – do_execve()

ELF头以一个16字节的序列开始,描述了生成该文件的系统的字的大小和字节顺序。ELF头剩下的部分包含帮助连接器语法分析和解释目标文件的信息。其中包括ELF头的大小、目标文件的类型(如可重定位、可执行、共享的)、机器类型(如x86-64)、节头部表的文件偏移,以及节头部表中条目的大小和数量。
编译是指编译器读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码。
源文件的编译过程包含两个主要阶段:
第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。
第二个阶段编译、优化阶段,编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。

静态链接(编译时)

链接器将函数的代码从其所在地(目标文件或静态链接库中)拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。
为创建可执行文件,链接器必须要完成的主要任务:
符号解析:把目标文件中符号的定义和引用联系起来;
重定位:把符号定义和内存地址对应起来,然后修改所有对符号的引用。

动态链接(加载、运行时)

在此种方式下,函数的定义在动态链接库或共享对象的目标文件中。在编译的链接阶段,动态链接库只提供符号表和其他少量信息用于保证所有符号引用都有定义,保证编译顺利通过。动态链接器(ld-linux.so)链接程序在运行过程中根据记录的共享对象的符号定义来动态加载共享库,然后完成重定位。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。

进程的调度

调用地方:
中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule()
内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度
用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度

分析switch_to中的汇编代码

调用关系:
schedule() --> context_switch() --> switch_to --> __switch_to()
汇编代码分析:

asm volatile("pushfl\n\t"      /* 保存当前进程的标志位 */   
         "pushl %%ebp\n\t"        /* 保存当前进程的堆栈基址EBP   */ 
         "movl %%esp,%[prev_sp]\n\t"  /* 保存当前栈顶ESP   */ 
         "movl %[next_sp],%%esp\n\t"  /* 把下一个进程的栈顶放到esp寄存器中,完成了内核堆栈的切换,从此往下压栈都是在next进程的内核堆栈中。   */ 
       

		 "movl $1f,%[prev_ip]\n\t"    /* 保存当前进程的EIP   */ 
         "pushl %[next_ip]\n\t"   /* 把下一个进程的起点EIP压入堆栈   */    
         __switch_canary                   
         "jmp __switch_to\n"  /* 因为是函数所以是jmp,通过寄存器传递参数,寄存器是prev-a,next-d,当函数执行结束ret时因为没有压栈当前eip,所以需要使用之前压栈的eip,就是pop出next_ip。  */ 


		 "1:\t"               /* 认为next进程开始执行。 */         
		 "popl %%ebp\n\t"     /* restore EBP   */    
		 "popfl\n"         /* restore flags */  
                                    
		 /* output parameters 因为处于中断上下文,在内核中
		 prev_sp是内核堆栈栈顶
		 prev_ip是当前进程的eip */                
		 : [prev_sp] "=m" (prev->thread.sp),     
		 [prev_ip] "=m" (prev->thread.ip),  //[prev_ip]是标号        
		 "=a" (last),                 
                                    
		/* clobbered output registers: */     
		 "=b" (ebx), "=c" (ecx), "=d" (edx),      
		 "=S" (esi), "=D" (edi)             
                                       
		 __switch_canary_oparam                
                                    
		 /* input parameters: 
		 next_sp下一个进程的内核堆栈的栈顶
		 next_ip下一个进程执行的起点,一般是$1f,对于新创建的子进程是ret_from_fork*/                
		 : [next_sp]  "m" (next->thread.sp),        
		 [next_ip]  "m" (next->thread.ip),       
                                        
	     /* regparm parameters for __switch_to(): */  
		 [prev]     "a" (prev),              
		 [next]     "d" (next)               
                                    
		 __switch_canary_iparam                
                                    
		 : /* reloaded segment registers */           
		 "memory");                  
} while (0)

switch_to实现了进程之间的真正切换:

1.首先在当前进程prev的内核栈中保存esi,edi及ebp寄存器的内容。
2.然后将prev的内核堆栈指针ebp存入prev->thread.esp中。
3.把将要运行进程next的内核栈指针next->thread.esp置入esp寄存器中
4.将popl指令所在的地址保存在prev->thread.eip中,这个地址就是prev下一次被调度
5.通过jmp指令(而不是call指令)转入一个函数__switch_to()
6.恢复next上次被调离时推进堆栈的内容。从现在开始,next进程就成为当前进程而真正开始执行

实验总结

1.内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度。
2.schedule()函数实现进程调度,context_ switch完成进程上下文切换,switch_ to完成寄存器的切换。
3.用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度

Linux系统编程(二)进程 本文介绍了进程的基本概念和特点。进程是程序的执行实例,包含代码、数据和系统资源。进程地址空间划分为栈、堆、全局区、文本常量区和代码段。进程具有独立性、资源拥有和状态切换的特点。创建进程有fork和vfork两种方式:fork会复制父进程地址空间,父子进程独立运行;vfork共享地址空间,且父进程需等待子进程退出。进程退出可使用exit(0)或_exit(0)两种方式。文章通过代码示例直观展示了不同创建方式下进程的运行机制和差异。 阅读详情

相关推荐

PaddleOCR SVTRv2中文识别模型训练全流程:从数据准备到推理部署

本文详细介绍了基于PaddleOCR的SVTRv2中文识别模型从数据准备、模型训练到推理部署的全流程实战。SVTRv2凭借其单视觉Transformer架构和分层混合机制,在中文文字识别任务上实现了高精度与效率的平衡。文章重点解析了数据工程、训练调优技巧及部署优化方案,帮助开发者构建定制化的OCR解决方案。

weixin_29194817的博客 287

Linux进程替换详解

详细讲解进程替换的函数使用

qq_61642164的博客 798

3D Slicer:从入门到精通(二)——入门指南

本篇文章包含开始使用3D Slicer所需的信息,包括如何安装和快速开始使用基本功能,以及在哪里找到更多信息。

walt3433的博客 2万+

【Linux 内核】进程管理 ( Linux 内核中的进程状态 | TASK_RUNNING | TASK_INTERRUPTIBLE | __TASK_STOPPED | EXIT_ZOMBIE )

一、Linux 内核中的进程状态、 二、TASK_RUNNING 状态、 三、TASK_RUNNING 状态、 四、TASK_UNINTERRUPTIBLE 状态、 五、__TASK_STOPPED 状态、 六、EXIT_ZOMBIE 状态、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 2945

FFT中的精度博弈:定点数缩放、块浮点与溢出处理在Vivado IP核中的实践权衡

本文探讨了在Vivado FFT IP核中实现高精度快速傅里叶变换的关键技术,包括定点数缩放策略、块浮点模式及溢出处理机制。通过分析不同精度控制方案的资源开销与性能权衡,为工程师在医疗成像、雷达信号处理等高动态范围应用中优化FFT实现提供实践指导。

melon的博客 1097

UVM概述及uvm_component和uvm_object(一)

UVM:Universal Verification Methodology(通用验证方法学) UVM:是建立在systemverilog平台上的一个库,提供了一系列的接口,让我们能够更方便的进行验证。验证平台组成: Driver:用来把不同的激励施加给DUT; Monitor:用来检测DUT的输出; Scoreboard:专门用来比较期望值与monitor检测到的DUT输出; Refer

南国之邱 1万+

Linux系统编程:进程的管理和创建

本文讲解了Linux下进程管理和创建的方法

weixin_43908419的博客 1991

OPTI Toolbox v2.28 安装与 3 个求解器补全:SCIP、SeDuMi、MOSEK 配置详解

本文详细介绍了OPTI Toolbox v2.28在MATLAB环境下的完整安装指南,包括SCIP、SeDuMi和MOSEK三个关键求解器的配置与优化技巧。通过分步指导和实战案例,帮助用户高效搭建强大的优化工具包,提升混合整数规划、二次约束二次规划等复杂问题的求解效率。

weixin_29039773的博客 350

Linux进程是如何创建出来的?

大家好,我是飞哥!在 Linux 中,进程是我们非常熟悉的东东了,哪怕是只写过一天代码的人也都用过它。但是你确定它不是你最熟悉的陌生人?我们今天通过深度剖析进程的创建过程,帮助你提高对进程的理解深度。在这篇文章中,我会用 Nginx 创建 worker 进程的例子作为引入,然后带大家了解一些进程的数据结构 task_struct,最后再带大家看一下 fork 执行的过程。学习完本文,你将深度理解进...

zhangyanfei01的专栏 2726

Vivado FFT IP核配置与实战:FPGA信号处理硬件加速指南

快速傅里叶变换(FFT)是数字信号处理(DSP)中的核心算法,用于将时域信号转换到频域进行分析。其原理基于离散傅里叶变换(DFT),通过蝶形运算的分解与复用,大幅降低了计算复杂度。在工程实践中,软件实现的FFT难以满足高速实时处理的需求,因此硬件加速方案至关重要。FPGA凭借其并行架构和可定制性,成为实现高性能FFT的理想平台。通过集成专用的FFT IP核,如Vivado中的Pipelined Streaming I/O架构,可以构建流水线化的计算引擎,实现极低延迟和高吞吐量的连续数据流处理。这种硬件方案特

weixin_42536863的博客 647

使用Microsoft Print to PDF进行编程:创建PDF文件的简单方法

Microsoft Print to PDF是一种内置于Windows操作系统中的功能,它允许我们通过打印操作将任何可打印的内容保存为PDF文件。然后,我们使用Microsoft Print to PDF打印机进行打印操作,并将输出文件保存为指定的PDF文件。使用Microsoft Print to PDF功能是一种方便且简单的方法来创建PDF文件,无论是在个人使用还是在企业开发中,它都可以提供良好的支持和灵活性。请注意,如果你使用的是其他编程语言,你可以根据相应的打印机接口或库来实现类似的功能。

TechSavant的博客 1635

Linux内核—理解进程创建、可执行文件的加载、以及进程执行、进程切换,重点理解分析fork、execve和进程切换

实验要求 实验:从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换 进程创建 进程的描述 操作系统内核实现操作系统的三大管理功能,即进程管理、内存管理和文件系统,对应操作系统原理课程中最重要的三个抽象进程是进程、虚拟内存和文件。 进程是怎样描述的?进程的描述有提纲挈领的作用,他可以把内存管理、文件系统、信号、进程间通信等概念和内容串起来。L...

ThereIsNoCode 497

VS2019项目使用CGAL6.1配置教程详细步骤

在VS2019项目中使用CGAL详细步骤

插件开发 331

Linux系统进程创建、可执行文件的加载和进程执行进程切换

328 原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ 一.实验要求 1.阅读理解task_struct数据结构; 2.分析fork函数对应的内核处理过程do_fork,使用gdb跟踪分析一个fork系统调用内核处理,函数do_fork; 3.理解编译链接的过程和ELF可执行文件格式; 4.使用gdb跟踪分析一个execve系统调用内核...

sunxxy的博客 796

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Linux实验:从整体上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换

学号后三位:288 原创作品转载请注明出处 +https://github.com/mengning/linuxkernel/ 1. 实验要求 阅读理解task_struct数据结构,代码链接:http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235; 分析fork函数对应的内核处理过程do_fo...

pjz000的博客 700

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Linux内核分析--进程创建,执行,切换

学号:351原创作品转载请注明出处本实验来源https://github.com/mengning/linuxkernel/ 实验要求 从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换: 实验内容 阅读理解task_struct数据结构 task_struct: 操作系统使用数据结构来代表处理不同的实体,这个数据结构就是通常所...

weixin_30673715的博客 114

Linux实验——从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换

Linux实验——从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换 学号后三位为342 原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ 实验工具 代码链接 VMware Workstation Pro Ubuntu 18.04 实验目的 从整理上理解进程创建、可执行文件的加载...

A22B9S的博客 400

linux参考文献_Linux进程创建、可执行文件的加载和进程执行进程切换

383 + 原创作品转载请注明出处 + 中科大孟宁老师的linux操作系统分析:https://github.com/mengning/linuxkernel/实验:从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换实验内容:1、阅读理解task_struct数据结构2、分析fork函数对应的内核处理过程do_fork,理解创建一个新进程如何创建...

weixin_39564853的博客 360

build 之前执行task_Linux进程创建、可执行文件的加载和进程执行进程切换

383 + 原创作品转载请注明出处 + 中科大孟宁老师的linux操作系统分析:https://github.com/mengning/linuxkernel/实验:从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换实验内容:1、阅读理解task_struct数据结构2、分析fork函数对应的内核处理过程do_fork,理解创建一个新进程如何创建...

weixin_42525582的博客 297

Linux内核分析——进程创建、执行、切换

517 原创作品转载请注明出处 本实验来源https://github.com/mengning/linuxkernel/ 一、实验要求 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235; 分析fork函数对应的内核处理过程do_fork,理解创建一个新进程如何...

weixin_42128195的博客 218

linux进程创建与同步,理解进程创建、可执行文件的加载和进程执行进程切换

一:阅读理解task_struct数据结构为了管理进程,操作系统必须对每个进程所做的事情进行清楚的描述,为此,操作系统使用数据结构来代表处理不同的实体,这个数据结构就是通常所说的进程描述符或进程控制块,在Linux中,task_struct其实就是通常所说的PCB。进程在TASK_RUNNING下是可运行的,但它有没有运行取决于它有没有获得cpu的控制权,即这个进程有没有在cpu上实际的执行进程的...

weixin_31211821的博客 195

linux重新挂载进程,Linux进程创建、可执行文件的加载和进程执行进程切换

学号023作品实验环境Parallels DesktopUbuntu 16.04进程创建进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。1、描述进程的数据结构在操作系统中,进程也需要一个数据结构来保存内核对进程状态等信息,此数据结构我们一般将其称作进程控制块(Process Control Block)。PCB在lin...

weixin_33318791的博客 369

Linux内核分析---进程的创建,执行与切换

学号:210 “原创作品转载请注明出处 +https://github.com/mengning/linuxkernel/” 一.实验要求 从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换。 二.实验内容 1.理解task_struct数据结构 为了管理进程,内核必须对每个进程进行清晰的描述。每个进程在内核中都有一个进程控制块(...

weixin_34087301的博客 125
上一篇: Linux系统调用跟踪分析
夜刃 
博客等级 码龄8年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值