学号: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内核分析---进程的创建,执行与切换相关推荐

  1. 《Linux内核分析》(二)——从一个简单Linux内核分析进程切换原理

    转载:https://blog.csdn.net/FIELDOFFIER/article/details/44280717 <Linux内核分析>MOOC课程http://mooc.stu ...

  2. Linux内核分析——进程的描述和进程的创建

    进程的描述和进程的创建 一. 进程的描述 (一)进程控制块PCB--task_struct 1.操作系统的三大管理功能包括: (1)进程管理 (2)内存管理 (3)文件系统 2.PCB task_st ...

  3. 【Linux 内核】进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )

    文章目录 一.进程状态 二.进程创建 三.进程终止 ( 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 ) 一.进程状态 Linux 进 ...

  4. linux 如何创建内核进程,Linux内核的进程创建和执行.pdf

    Linux内核的进程创建和执行 !"#$% 内核的进程创建和执行 徐 炜 摘 要 详细阐述了!"#$% 内核34 54 2 的进程创建和执行过程,分析了相应的算法.数据 结构和关键 ...

  5. 《Linux内核分析》 第六节 进程的描述和进程的创建

    <Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...

  6. 《Linux内核分析》 第八节 进程的切换和一般的执行过程

    张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第八 ...

  7. linux swi 内核sp,Linux内核分析课程8_进程调度与进程切换过程

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Linux内核课第八周作业.本文在云课堂中实验楼完成. 原创作品转载请注明出处 <Linux内核分析>MOO ...

  8. 分析Linux内核中进程的调度(时间片轮转)-《Linux内核分析》Week2作业

    1.环境的搭建: 这个可以参考孟宁老师的github:mykernel,这里不再进行赘述.主要是就是下载Linux3.9的代码,然后安装孟宁老师编写的patch,最后进行编译. 2.代码的解读 课上的 ...

  9. 【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )

    文章目录 一.内核线程概念 二.内核线程.普通进程.用户线程 三.内核线程.普通进程区别 四.内核线程主要用途 五.内核线程创建函数 kernel_thread 源码 一.内核线程概念 直接 由 Li ...

最新文章

  1. 我的世界java版背景图更换_《我的世界手机版》如何修改界面背景 界面背景修改攻略图文教程...
  2. linux sd卡只读模式如何消除,SD内存卡写保护怎么去掉-奇迹可解决方案
  3. 父子对等组之间的关系
  4. yum 更新_CentOS7 - 使用yum-cron自动更新软件
  5. tomcat的安装和部署项目
  6. C# win10系统调用不了系统自带的软键盘osk.exe
  7. 计算机及网络的概念,网络的概念是什么意思,以及计算机网络概念的引入
  8. Javascript中数组去重的六种方法
  9. @FeignClient注解 中属性 contextId使用
  10. Spark类型不匹配导致无法读取到数据
  11. 毕设开题报告重要内容
  12. 企业IT管理员IE11升级指南【4】—— IE企业模式介绍
  13. ireport java 变量_iReport —— 使用 JavaBean 作为数据源
  14. 做项目的一些心得体会
  15. win10锁屏界面无法更新
  16. 今日头条测试开发实习生面试
  17. 软件推荐:强力卸载软件HIBIT
  18. 自动化测试常见面试问题
  19. IPv6报头与IPv4报头的区别
  20. matlab典型环节性能仿真,实验一典型环节的matlab仿真

热门文章

  1. Apache ZooKeeper - ZooKeeper 数据模型回顾
  2. 高并发编程-Wait Set 多线程的“休息室”
  3. 白话Elasticsearch43-深入聚合数据分析之案例实战__排序:按每种颜色的平均销售额升序排序
  4. Shell printf 命令
  5. js php 中文乱码怎么解决_探讨PHP JSON中文乱码的解决方法详解
  6. html限制最多字符串,css – 设置字符串换行中允许的最大换行量
  7. 学习笔记Hadoop(十四)—— MapReduce开发入门(2)—— MapReduce API介绍、MapReduce实例
  8. h5 socket.io java,从HTML5 WebSocket到Socket.io
  9. antd 给input设置值_Antd 中 Input 组件默认值的显示
  10. mysql删除端口配置文件,linux中的Mysql的安装、重置安装密码、修改权限详解