【刘蔚然 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

WEEK SIX(3.28——4.3)进程的创建与描述

SECTION 1 进程描述

1.进程控制块——PCB

2.进程描述符——struct task_struct

1. pid_t pid又叫进程标识符,唯一地标识进程
2. 第1295行,list_head tasks即 进程链表
- 双向循环链表链接起了所有的进程,也表示了父子、兄弟等进程关系
3. struct mm_struct 指的是进程地址空间,涉及到内存管理(对于X86而言,一共有4G的地址空间)
4. thread_struct thread 与CPU相关的状态结构体
5. struct *file表示打开的文件链表
6. Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈

3.进程状态转换图

- TASK_RUNNING具体是就绪还是执行,要看系统当前的资源分配情况;
- TASK_ZOMBIE也叫僵尸进程

SECTION 2 进程的创建

1.进程的创建概览及fork一个进程的源代码

  1. 回顾:start_kernel创建了cpu_idle,也就是0号进程。而0号进程又创建了两个线程,一个是kernel_init,也就是1号进程,这个进程最终启动了用户态;另一个是kthreadd。这就是“道生一,一生二”。0号进程是固定的代码;1号进程是通过复制0号进程PCB之后在此基础上做修改得到的。

  2. 回顾:系统调用的进程创建过程

    • iret与int 0x80指令对应,一个是弹出寄存器值,一个是压入寄存器的值

    • 如果将系统调用类比于fork();那么就相当于系统调用创建了一个子进程,然后子进程返回之后将在内核态运行,而返回到父进程后仍然在用户态运行

  3. 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) //pid == 0和下面的else都会被执行到(一个是在父进程中即pid ==0的情况,一个是在子进程中,即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.}
  4. 创建新进程的框架

    fork,vfork,clone都可以创建新进程,他们都是通过调用do_fork来实现的。

    • dup_thread复制父进程的PCB

    • copy_process修改复制的PCB以适应子进程的特点,也就是子进程的初始化

    • 分配一个新的内核堆栈(用于存放子进程数据)

      • 内核堆栈的一部分也要从父进程中拷贝



      • -

      • 根据拷贝的内核堆栈情况设置eip,esp寄存器的值

  5. 一个新创建的子进程,(当它获得CPU之后)是从哪一行代码进程执行的?

    • 与之前写过的my_kernel相比较,kernel中是可以指定新进程开始的位置(也就是通过eip寄存器指定代码行)。fork中也有相似的机制

    • 这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process

       1.*childregs = *current_pt_regs(); //复制内核堆栈,并不是全部,只是regs结构体(内核堆栈栈底的程序)
      2.childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
      3.
      4.p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
      5.p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址,也就是说返回的就是子进程的空间了

2.使用gdb跟踪创建新进程的过程

  1. 更新menu内核,然后删除test_fork.c以及test.c(以减少对之后实验的影响)

  2. 编译内核,可以看到fork命令

  3. 启动gdb调试,并对主要的函数设置断点

  4. 在MenuOS中执行fork,就会发现fork函数停在了父进程中

  5. 继续执行之后,停在了do_fork的位置。然后n单步执行,依次进入copy_process、dup_task_struct。按s进入该函数,可以看到*dst = *src(也就是复制父进程的struct)

  6. 在copy_thread中,可以看到把task_pg_regs(p)也就是内核堆栈特定的地址找到并初始化

  7. 到了159、160行的代码就是把压入的代码再放到子进程中:

     *children = *current_pt_regs();
    childregs->ax = 0;
  8. 164行,是确定返回地址

     p->thread.ip = (unsigned long) ret_from_fork;

此后,可以输入finish使得进程运行完。

总结与补充

我在上周的实验中尝试用实验楼(链接个人热点)进行实验,发现报错(地址无法解析)。然而在本周的实验中,连接广域网之后,实验楼的环境可以正常进行menu的联网更新。我认为应该是连接的网络决定了实验楼的实验环境能否与外界网络发生交互。

《Linux内核分析》第六周 进程的描述与创建的更多相关文章

  1. Linux内核设计第六周 ——进程的描述和创建

    Linux内核设计第六周 ——进程的描述和创建 第一部分 知识点总结 一.进程描述符task_struct数据结构 1.操作系统的三大功能: 进程管理.内存管理.文件系统 2.进程的作用: 将信号.进 ...

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

    进程的描述和进程的创建 一.进程的描述 操作系统三大功能: 进程管理 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰 ...

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

    LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...

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

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  5. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  6. linux内核分析第六周学习笔记

    LINUX内核分析第六周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...

  7. Linux分析第六周——进程的描述和进程的创建

    Linux分析第六周--进程的描述和进程的创建 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...

  8. Linux内核分析第八周——进程的切换和系统的一般执行过程

    Linux内核分析第八周--进程的切换和系统的一般执行过程 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...

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

    第六周 进程的描述和进程的创建 一.进程描述符task_struct数据结构 1.操作系统三大功能 进程管理 内存管理 文件系统 2.进程控制块PCB——task_struct 也叫进程描述符,为了管 ...

随机推荐

  1. oracle视图

    视图 SELECT -- int.rowner "rgroup owner", -- int.rname "refresh group", mv.owner a ...

  2. 01_Swift2基础之Swift简介+创建

    1.Swift 1> Swift初影响 Swift 是新一代的 iOS.OS X 和 watchOS 和 tvOS 的app开发编程语言. 中文名"雨燕",寓意为敏捷.灵巧而 ...

  3. 20145304 Java第四周学习报告

    20145304<Java程序设计>第四周学习总结 教材学习内容总结 1.继承共同行为: 继承基本上就是避免多个类间重复定义共同行为,关键词为extends. 代码如下: //继承共同行为 ...

  4. 【BZOJ】1975: [Sdoi2010]魔法猪学院

    题意 \(n(2 \le n \le 5000)\)个点,找尽量多的不同\(1\)到\(n\)的路径,每一次的花费就是路径的全值和,要求在费用不超过\(E\)的情况下路径最多. 分析 裸的最段路. 题 ...

  5. SDL1.2学习

    http://wenku.baidu.com/view/c953c0878762caaedd33d4d8.html 一.安装: sudo apt-get install libsdl1.2-dev l ...

  6. 关于多条id相同,只取其中一条记录的sql语句

    需要使用:分区函数用法(partition by 字段) select *,row_number() over(partition by item order by date  ) as index ...

  7. Hightcharts设置Y轴最大最小值

    有两种方法: 1:是在控件初始化时预设, yAxis: [{ max:}] 2:在程序运行中动态更新设置 thChart.yAxis[].update({ min: , max: });

  8. html CSS 学习总结

    HTML文件格式 <!DOCTYPE HTML> <html lang="en"> <head> <meta charset=" ...

  9. js 进度条,可实现结束和重新开始

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  10. CSS3初学篇章_5(背景样式/列表样式/过渡动画)

    背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...