Linux内核分析---进程的创建,执行与切换
学号:210
“原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ ”
一.实验要求
从整理上理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换。
二.实验内容
1.理解task_struct数据结构
为了管理进程,内核必须对每个进程进行清晰的描述。每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。进程描述符提供了内核所需了解的进程信息:基本信息,管理信息,控制信息等。
task_struct是Linux内核的一种数据结构,每个进程都把它的信息放在 task_struct 这个数据结构体,task_struct 包含了这些内容:
(1)标示符 : 描述本进程的唯一标识符,用来区别其他进程。
(2)状态 :任务状态,退出代码,退出信号等。
(3)优先级 :相对于其他进程的优先级。
(4)程序计数器:程序中即将被执行的下一条指令的地址。
(5)内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
(6)上下文数据:进程执行时处理器的寄存器中的数据。
(7) I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
(8) 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
2.分析fork函数对应的内核处理过程do_fork,理解创建一个新进程如何创建和修改task_struct数据结构
Linux系统中,除第一个进程是被捏造出来的,其他进程都是通过do_fork()复制出来的。
函数原型:int do_fork(unsigned long clone_flags, unsigned long stack_start,struct pt_regs *regs, unsigned long stack_size)
1.创建子进程task_struct结构体
首先需要申请进程最基本的单位task_struct结构,然后需要将父进程task_struct结构中的各种参数复制到子进程task_struct中。
2.获取一个空闲的pid。
3.复制各种资源:copy_files(clone_flags, p)父进程中可能打开了一系列文件,因此要复制给子进程。copy_fs(clone_flags, p),复制父进程当前目录环境,如当前文件系统。复制父进程的用户空间。copy_thread()等。
3.使用gdb跟踪分析一个fork系统调用内核处理函数do_fork
1.启动Menu OS
cd LinuxKernel rm menu -rf git clone https://github.com/mengning/menu.git cd menu mv test_fork.c test.cmake rootfs 2.进入gdb调试模式gdbfile linux-3.18.6/vmlinux在这几个地方设置断点b sys_cloneb do_fork b dup_task_struct b copy_process b copy_thread b ret_from_for 首先在sys_clone处 do_fork处 copy_process处 进入copy_thread 查看p值
4.理解编译链接的过程和ELF可执行文件格式
1.链接过程
预处理:主要是做一些代码文本的替换工作。(该替换是一个递归逐层展开的过程。)
(1)将所有的#define删除,并展开所有的宏定义(2)处理所有的条件预编译指令,如:#if #ifdef #elif #else #endif(3)处理#include预编译指令,将被包含的文件插进到该指令的位置,这个过程是递归的(4)删除所有的注释//与/* */(5)添加行号与文件名标识,以便产生调试用的行号信息以及编译错误或警告时能够显示行号(6)保留所有的#pragma编译器指令,因为编译器需要使用它们
编译:把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成汇编代码,这个过程是程序构建的核心部分。
汇编:将汇编代码转成机器指令。
链接:此时的链接,严格说应该叫静态链接。将多个目标文件、库拼合成最终的可执行文件。
5.使用exec*库函数加载一个可执行文件
exec()族函数功能是将当前的进程替换成一个新的进程,执行到exec()函数时当前进程就会结束新进程则开始执行。
process.c代码
运行结果:
6.理解Linux系统中进程调度的时机
1.中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
2.内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
3.用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
7.特别关注并仔细分析switch_to中的汇编代码,理解进程上下文的切换机制,以及与中断上下文切换的关系
1.关键函数的调用关系:
schedule() --> context_switch() --> switch_to --> __switch_to()
2.代码分析
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.进程切换, 即esp的切换, 由于从esp可以找到进程的描述符
2.硬件上下文切换, 设置ip寄存器的值, 并jmp到__switch_to函数
3.堆栈的切换, 即ebp的切换, ebp是栈底指针, 它确定了当前用户空间属于哪个进程
通过系统调用,用户空间的应用程序就会进入内核空间,由内核代表该进程运行于内核空间,这就涉及到上下文的切换,用户空间和内核空间具有不同的地址映射,通用或专用的寄存器组,而用户空间的进程要传递很多变量、参数给内核,内核也要保存用户进程的一些寄存器、变量等,以便系统调用结束后回到用户空间继续执行,所谓的进程上下文,就是一个进程在执行的时候,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容,当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。
转载于:https://www.cnblogs.com/lizhenhuaxxx/p/10603897.html
Linux内核分析---进程的创建,执行与切换相关推荐
- 《Linux内核分析》(二)——从一个简单Linux内核分析进程切换原理
转载:https://blog.csdn.net/FIELDOFFIER/article/details/44280717 <Linux内核分析>MOOC课程http://mooc.stu ...
- Linux内核分析——进程的描述和进程的创建
进程的描述和进程的创建 一. 进程的描述 (一)进程控制块PCB--task_struct 1.操作系统的三大管理功能包括: (1)进程管理 (2)内存管理 (3)文件系统 2.PCB task_st ...
- 【Linux 内核】进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )
文章目录 一.进程状态 二.进程创建 三.进程终止 ( 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 ) 一.进程状态 Linux 进 ...
- linux 如何创建内核进程,Linux内核的进程创建和执行.pdf
Linux内核的进程创建和执行 !"#$% 内核的进程创建和执行 徐 炜 摘 要 详细阐述了!"#$% 内核34 54 2 的进程创建和执行过程,分析了相应的算法.数据 结构和关键 ...
- 《Linux内核分析》 第六节 进程的描述和进程的创建
<Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...
- 《Linux内核分析》 第八节 进程的切换和一般的执行过程
张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第八 ...
- linux swi 内核sp,Linux内核分析课程8_进程调度与进程切换过程
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Linux内核课第八周作业.本文在云课堂中实验楼完成. 原创作品转载请注明出处 <Linux内核分析>MOO ...
- 分析Linux内核中进程的调度(时间片轮转)-《Linux内核分析》Week2作业
1.环境的搭建: 这个可以参考孟宁老师的github:mykernel,这里不再进行赘述.主要是就是下载Linux3.9的代码,然后安装孟宁老师编写的patch,最后进行编译. 2.代码的解读 课上的 ...
- 【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )
文章目录 一.内核线程概念 二.内核线程.普通进程.用户线程 三.内核线程.普通进程区别 四.内核线程主要用途 五.内核线程创建函数 kernel_thread 源码 一.内核线程概念 直接 由 Li ...
最新文章
- 我的世界java版背景图更换_《我的世界手机版》如何修改界面背景 界面背景修改攻略图文教程...
- linux sd卡只读模式如何消除,SD内存卡写保护怎么去掉-奇迹可解决方案
- 父子对等组之间的关系
- yum 更新_CentOS7 - 使用yum-cron自动更新软件
- tomcat的安装和部署项目
- C# win10系统调用不了系统自带的软键盘osk.exe
- 计算机及网络的概念,网络的概念是什么意思,以及计算机网络概念的引入
- Javascript中数组去重的六种方法
- @FeignClient注解 中属性 contextId使用
- Spark类型不匹配导致无法读取到数据
- 毕设开题报告重要内容
- 企业IT管理员IE11升级指南【4】—— IE企业模式介绍
- ireport java 变量_iReport —— 使用 JavaBean 作为数据源
- 做项目的一些心得体会
- win10锁屏界面无法更新
- 今日头条测试开发实习生面试
- 软件推荐:强力卸载软件HIBIT
- 自动化测试常见面试问题
- IPv6报头与IPv4报头的区别
- matlab典型环节性能仿真,实验一典型环节的matlab仿真
热门文章
- Apache ZooKeeper - ZooKeeper 数据模型回顾
- 高并发编程-Wait Set 多线程的“休息室”
- 白话Elasticsearch43-深入聚合数据分析之案例实战__排序:按每种颜色的平均销售额升序排序
- Shell printf 命令
- js php 中文乱码怎么解决_探讨PHP JSON中文乱码的解决方法详解
- html限制最多字符串,css – 设置字符串换行中允许的最大换行量
- 学习笔记Hadoop(十四)—— MapReduce开发入门(2)—— MapReduce API介绍、MapReduce实例
- h5 socket.io java,从HTML5 WebSocket到Socket.io
- antd 给input设置值_Antd 中 Input 组件默认值的显示
- mysql删除端口配置文件,linux中的Mysql的安装、重置安装密码、修改权限详解