zoukankan      html  css  js  c++  java
  • 201920201 20199320《Linux内核原理与分析》第七周作业

    一、进程的描述

    1. 操作系统内核实现操作系统的三大管理功能:进程管理,内核管理和文件系统,其中最核心的功能是进程管理。

    2. 在操作系统原理中,我们通过进程控制块PCB描述进程,通常采用一个数据结构struct task_struct来描述进程,该结构体大致分为以下几个部分:

      • 进程状态(State)

      • 进程调度信息(Scheduling Information)

      • 各种标识符(Identifiers)

      • 进程通信有关信息(IPC:Inter_Process Communication)

      • 时间和定时器信息(Times and Timers)

      • 进程链接信息(Links)

      • 文件系统信息(File System)

      • 虚拟内存信息(Virtual Memory)

      • 页面管理信息(page)

      • 对称多处理器(SMP)信息

      • 和处理器相关的环境(上下文)信息(Processor Specific Context)

        下面分析一下其中的进程状态:

        Linux内核管理的进程状态转换如下图所示:

    二、实验内容:分析Linux内核创建一个新进程的过程

    1. 在MenuOS中增加fork命令,具体命令和实现效果截图如下图所示:

    2. 打开另一个终端,进行gdb跟踪, 对sys_clone,do_fork,dup_task_struct,copy_process,copy_thread和ret_from_fork设置断点 ,实现效果如图所示:

      • 运行后首先停在sys_clone处 :

      • 然后是do_fork,之后是copy_process:

      • 进入copy_thread:

      • 在copy_thread中,我们可以查看p的值 :

      • 但是回到copy_process后再查看,将得到一个value optimized out的提示,这是因为Linux内核打开gcc的-O2选项优化导致.如果想要关掉,可以参考:这里

      • ret_from_fork按照之前的分析被调用,跟踪到syscall_exit后无法继续.如果想在本机调试system call,那么当你进入system call时,系统已经在挂起状态了。如果想要跟踪调试system_call,可以使用kgdb等

    新进程是从哪里开始执行的

    之前谈到的copy_process中的copy_thread()函数,正是这个函数决定了子进程从系统调用中返回后的执行.

    int copy_thread(unsigned long clone_flags, unsigned long sp,
          unsigned long arg, struct task_struct *p)
          {
              ...
              
              *childregs = *current_pt_regs();
              childregs->ax = 0;
              if (sp)
                  childregs->sp = sp;
              
              p->thread.ip = (unsigned long) ret_from_fork;
              
              ...
    }
    

    子进程执行ret_from_fork

    ENTRY(ret_from_fork)
              CFI_STARTPROC
              pushl_cfi %eax
              call schedule_tail
              GET_THREAD_INFO(%ebp)
              popl_cfi %eax
              pushl_cfi $0x0202       # Reset kernel eflags
              popfl_cfi
              jmp syscall_exit
              CFI_ENDPROC
    END(ret_from_fork)
    

    执行起点与内核堆栈如何保证一致?

    • 在ret_from_fork之前,也就是在copy_thread()函数中childregs = current_pt_regs();该句将父进程的regs参数赋值到子进程的内核堆栈,

    • *childregs的类型为pt_regs,里面存放了SAVE ALL中压入栈的参数

    • 故在之后的RESTORE ALL中能顺利执行下去.

    三、总结

    • Linux通过复制父进程来创建一个新进程,通过调用do_fork来实现

    • Linux为每个新创建的进程动态地分配一个task_struct结构.

    • 为了把内核中的所有进程组织起来,Linux提供了几种组织方式,其中哈希表和双向循环链表方式是针对系统中的所有进程(包括内核线程),而运行队列和等待队列是把处于同一状态的进程组织起来

    • fork()函数被调用一次,但返回两次.

  • 相关阅读:
    《C++ Primer(中文版)(第5版)》斯坦利·李普曼 (Stanley B. Lippman) (作者), 约瑟·拉乔伊 (Josee Lajoie) (作者), 芭芭拉·默 (Barbara E. Moo) (作者) azw3
    《O’Reilly精品图书系列共21册》azw3
    《跟老齐学Python:从入门到精通》齐伟(编著)epub+mobi+azw3
    《C Primer Plus(第6版)(中文版)》普拉达(作者)epub+mobi+azw3
    《算法图解》[美] Aditya Bhargava(作者)epub+mobi
    《程序之美系列(套装共6册)》[美]斯宾耐立思 等 (作者) epub+mobi+azw3
    《算法技术手册》George T. Heineman(作者)epub+mobi+azw3
    收藏夹
    笔记
    Unity3D物理引擎Rigidbody,Collider,PhysicMaterial的整理 [转]
  • 原文地址:https://www.cnblogs.com/liangxu111/p/11789611.html
Copyright © 2011-2022 走看看