zoukankan      html  css  js  c++  java
  • 作业6:进程的描述和进程的创建 20135115臧文君

    进程的描述和进程的创建

    注:作者:臧文君,原创作品转载请注明出处,《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

    一、进程的描述

    操作系统的三大功能:进程管理,内存管理和文件系统。

    1、进程描述符task_struct数据结构

    (1)进程控制块PCB---task_struct

    (2)进程描述符提供了内核所需了解的进程信息。

    task_struct中包含:进程状态,进程打开的文件,进程优先级信息。

    tty_struct控制台

    fs_struct文件系统

    files_struct打开的文件描述符

    mm_struct内存管理

    signal_struct通讯信号的描述

    (3)struct task_struct的数据结构很庞大

    (4)Linux进程的状态与操作系统原理中的描述的进程状态似乎有所不同,比如:就绪状态和运行状态都是TASK_RUNNING。

    进程调用do_exit()终止执行,TASK_ZOMBIE(进程被终止)。

    阻塞态:TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE(等待中)。

     

    2、进程的标识pid

     

    3、task_struct数据结构分析

     

    (1)运行状态state:-1 unrunnable,0 runnable,>0 stopped。

    进程的内核堆栈stack。

    ifdef CONFIG SMP条件编译,多处理器时用到。

    进程链表list_head tasks

     

    4G的进程地址空间

    (2)进程的父子关系

     

     

    P0有三个儿子P1,P2,P3;P1有两个兄弟P2,P3;P3有一个儿子P4。

    (3)CPU相关的状态:thread_struct

    文件系统:fs_struct

    二、进程的创建

    1、进程的创建概览及fork一个进程的用户态代码

     

    fork()是用户态用于创建一个子进程的系统调用。

     

    fork()系统调用在父进程和子进程各返回一次,在子进程中,pid的返回值为0,执行else的代码,在父进程中,pid的返回值为子进程的ID,执行else if的代码。

    2、系统调用再回顾

     

     

     

    3、一个新创建的子进程从哪里开始执行?

    创建新进程是通过复制当前进程来实现的。

     

    系统调用内核处理函数sys_fork、sys_clone、sys_vfork

    4、do fork中的copy process就是创建一个进程的主要代码。

    dup task struct复制整个PCB。

    拷贝内核堆栈数据和指定新进程的第一条指令地址:*childregs = *current_pt_regs();

     

    5、创建的新进程是从哪里开始执行的?

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

     

    当子进程获得CPU控制权时,它的return from fork可以把后面堆栈中的iret返回到用户态。

    三、使用gdb跟踪创建新进程的过程

    1、先删除menu,再克隆一个新的menu。

    2、用test_fork.c覆盖test.c:

    cd menu

    mv test_fork.c test.c

    make rootfs//编译

    3、调试:

    qemu-system-x86_64 -kernel bzImage -initrd /home/YL/menu/rootfs.img -s -S

    gdb /usr/src/linux-source-4.4/vmlinux

    set arch i386:x86-64

    target remote:1234

     

    4、设置断点:b sys_clone

    b do_fork

    b dup_task_struct

    b copy_process

    b copy_thread

    b ret_from_fork

     

    5、按c继续执行,但会报错显示超时,此时重启一遍gdb即可。

     

     

    6、按n单步执行,按s进入某个函数中去单步执行。

     

     

    当前进程的内核堆栈中压的寄存器复制到进程中:

     

    设置子进程被调度的IP,是子进程的起点ret_from_fork:

     

    总结:

         本次课程学习的是进程的结构分析以及进程的创建。Linux系统创建一个新进程主要依靠fork(),fork()是用户态用于创建一个子进程的系统调用,再由fork()调用do_fork来实现进程的创建。

         先复制一个PCB——task_struct,再给新进程分配一个新的内核堆栈,并且修改复制过来的进程数据,比如pid、进程链表等等。通过以上步骤,就可以创建一个新进程。

         新进程的起点是ret_from_fork,通过*childregs = *current_pt_regs()语句复制内核堆栈。

         在实验的过程中,会遇到gdb的问题,显示连接超时,此时需要重启gdb即可。另外,调试内核时还需要注意路径的问题。若没有给出路径,则是在当前目录下查找文件。

  • 相关阅读:
    SVN服务器搭建和使用(三)
    SVN服务器搭建和使用(二)
    SVN服务器搭建和使用(一)
    mysql和oracle分页
    Windows许可证 即将过期
    Java 设计模式学习笔记1——策略模式(Duck例子)
    java 抽象类与接口
    java servlet练习测试
    windows 添加开始菜单
    visio连接线设置
  • 原文地址:https://www.cnblogs.com/CatherineZang/p/5343121.html
Copyright © 2011-2022 走看看