20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建

进程的描述和进程的创建

一、进程的描述

操作系统三大功能:

  • 进程管理
  • 内存管理
  • 文件系统

进程描述符task_struct数据结构

  • task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。
  • 进程的状态:Linux进程的状态(就绪态、运行态、阻塞态)
  • 进程的标示pid:用来标示进程

进程描述符task_struct数据结构(重要部分):

 1 struct task_struct {
 2 volatile long state;    /* 进程的运行状态-1 unrunnable, 0 runnable, >0 stopped */
 3 void *stack;    /*指定了进程的内核堆栈*/
 4 atomic_t usage;
 5 unsigned int flags; /* 每一个进程的标识符 */
 6
 7 int on_rq;  /*运行队列*/
 8
 9 pid_t pid; /*进程标识符*/
10
11 struck list_head task;  /*进程链表*/
12
13 /*父子进程*/
14 struct task_struct __rcu *real_parent; /* real parent process */
15 struct task_struct __rcu *parent;
16
17 struct list_head children;    /* list of my children */

二、进程的创建

start _ kernel代码中的rest _ init创建两个内核线程,kernel _ init和kthreadd。

kernel _ init将用户态进程init启动,是所有用户态进程的祖先。

kthreadd是所有内核线程的祖先。

0号进程是所有线程的祖先。(0号进程时手工写的)

fork一个子进程的代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 int main(int argc, char * argv[])
 5 {
 6     int pid;
 7     /* fork another process */
 8     pid = fork();
 9     if (pid < 0)
10     {
11         /* error occurred */
12         fprintf(stderr,"Fork Failed!");
13         exit(-1);
14     }
15     else if (pid == 0)
16     {
17         /* child process */
18         printf("This is Child Process!\n");
19     }
20     else
21     {
22         /* parent process  */
23         printf("This is Parent Process!\n");
24         /* parent will wait for the child to complete*/
25         wait(NULL);
26         printf("Child Complete!\n");
27     }
28 }

这里特别说明一下:else if和if两个模块的代码都会被执行,子进程和父进程都会返回,子进程返回0,父进程返回子进程pid。

实验:

1. 删除menu,克隆新的menu。

2.查看help

3.gdb调试

4.设置断点

5.单步追踪

总结:

新的进程从哪里开始?

1 *childregs = *current_pt_regs(); //复制内核堆栈
2 childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
3
4 p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
5 p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

Linux通过复制父进程来创建一个新进程:复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈。

修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread。

设置sp调度到子进程时的内核栈顶,ip转到子进程时的第一条指令地址

之后,当子进程获得CPU的控制权开始运行的时候,ret _ form _ fork可以将后面的堆栈出栈,从iret返回到用户态,从而切换到子进程的用户空间,完成新进程的创建。

时间: 2024-11-15 12:29:07

20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建的相关文章

20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS

Linux内核分析第三周  构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 进程上下文的切换 第一讲  Linux内核源代码介绍 arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录.PC机一般都基于此目录. init目录包含核心的初始化代码(不是系统的引导代

20135327郭皓--Linux内核分析第七周 可执行程序的装载

第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.预处理,编译,链接和目标文件格式 1.可执行程序是怎么得来的 c代码->预处理->汇编代码->汇编器->目标代码->链接成可执行文件->加载到内核执行 2.目标文件的格式ELF 符号修饰标准.变量内层布局.函数调用方式等这些跟可执行代码二进制兼容性相关的内容称为ABI

20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)

Linux内核分析第四周 扒开系统调用的三层皮(上) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断 用户态:当进程在执行用户自己的代码时,则称其处于用户态,即此时处理器在特权级最低的(3级)用户代码中运行. 内核态:当一个进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核态,此时处理器处于特权级最高的(0级)内核代码中执行. PS:CPU指令

20135327郭皓——Linux内核分析第二周 操作系统是如何工作的

操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: enter pushl %ebp movl %esp,%ebp leave movl %ebp,%esp popl %ebp 函数参数传递机制和局部变量存储 中断,多道程序操作系统的基点,没有中断机制程序只能

20135327郭皓--Linux内核分析第九周 期中总结

Linux内核分析第九周 期中总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工作的 函数调用堆栈 模拟存储程序计算机工作模型和时钟中断 在mykernel基础构建一个简单的操作系统 3.构造一个简单的Linux系统 Linux内核源代码 构造一个简单的Linux系统 跟踪调试Linux内核的启动过程 4. 系统调用 用户态.内核态和中断 系统调用概述 使用库函数API和C代码

LINUX内核分析第六周学习总结——进程的描述和进程的创建

LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 进程的描述 进程描述符task_struct数据结构(一) 进程描述符task_struct数据结构(二) 进程的创建 进程的创建概览及fork一个进程的用户态代码 理解进程创建过程复杂代码的方法 浏览进程创建过程相关的关键代码 创建的新进程是从哪里开始执行的

Linux内核分析第六周作业

分析Linux内核创建一个新进程的过程 首先更新MenuOS的代码,加入调用fork的命令.吐槽一句,实验楼免费用户无法连网.还好只要去github复制一段代码即可 先观察一下fork命令的实现 1 int Fork(int argc, char *argv[]) 2 { 3 int pid; 4 /* fork another process */ 5 pid = fork(); 6 if (pid<0) 7 { 8 /* error occurred */ 9 fprintf(stderr,

Linux内核分析——第六周学习笔记20135308

第五周 进程的描述和进程的创建 一.进程描述符task_struct数据结构 1.操作系统三大功能 进程管理 内存管理 文件系统 2.进程控制块PCB——task_struct 也叫进程描述符,为了管理进程,内核需要对每个进程进行描述,它就提供了内核所需了解的进程信息. struct task_struct数据结构很庞大,1235行~1644行 3.Linux进程状态 Linux进程的状态与操作系统原理中的描述的进程状态有所不同 操作系统状态: 就绪态 运行态 阻塞态 linux进程状态: 4.

Linux内核分析——第六周学习笔记

进程的描述和进程的创建 前言:以下笔记除了一些讲解视频中的概念记录,图示.图示中的补充文字.总结.分析.小结部分均是个人理解.如有错误观点,请多指教! PS.实验操作会在提交到MOOC网站的博客中写.