• 分析system_call中断处理过程


    一、实验过程

    新版 MenuOS 中添加了 fork 功能。

    接下来用 gdb 跟踪调试了 fork 等工作过程。

    二、实验分析

    1. 预备知识

    首先我们分析下 task_struct 结构,其中主要有:

    1. 进程状态( 记录进程等待、运行或死锁三种状态 )
    2. 调度信息
    3. 标识符
    4. 进程间的通讯情况
    5. 进程链接信息( 进程链表的插入等操作信息 )
    6. 时间和定时器信息
    7. 文件系统信息
    8. 页面管理信息
    9. 和处理器相关的环境( 上下文 )信息等

    具体代码参见:http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235

    2. 进程创建分析

    fork 函数对应着内核处理过程中的 sys_clone。

    首先看下 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!
    ");
    19     } 
    20     else
    21     {  
    22         /* parent process  */
    23         printf("This is Parent Process!
    ");
    24         /* parent will wait for the child to complete*/
    25         wait(NULL);
    26         printf("Child Complete!
    ");
    27     }
    28 }

    通过调用 fork() 来创建一个新的进程,创建的进程有父子关系。通过复制现有进程来实现新创建一个新的进程。fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。

    复制过程为先负值一个 PCB—task_struct

    1 err = arch_dup_task_struct(tsk, orig);

    再给新的进程分配一个内核堆栈

    1 ti = alloc_thread_info_node(tsk, node);
    2 tsk->stack = ti;
    3 setup_thread_stack(tsk, orig); // 这里只是复制thread_info,而非复制内核堆栈

    此次复制并非把进程原封不动的复制过来,其中 pid、进程链表等数据都需要修改,这部分需要参见 copy_process 内部。

    新进程的创建是从 return_from_fork 开始执行的,复制时至复制了 int 指令和 save_all 等部分内容。之后新的参数,系统调用号等压入栈中。

    copy_process 函数被 do_fork 函数调用,主要完成进程数据结构的创建,资源的初始化。初始化的方式可以通过重新分配进行初始化,也可以和父进程共享同一组页表,最终初始化的方式由传入 clone 的参数来确定。

    三、总结

    总的来说,新的进程的创建是通过 do_fork 函数来实现的。新进程的创建过程是从return_from_fork开始,大体上就是先复制 PCB,再给新的进程分配要给新的内核堆栈,并修改复制过来的进程数据。

     

    参考资料

    1. http://www.oss.org.cn/kernel-book/ch04/4.3.htm

     

    李若森

    原创作品转载请注明出处

    《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

  • 相关阅读:
    Yii2——MYSQL操作
    Git之路——Git的使用
    python之路——爬虫实例
    PHP之路——验证码实现
    PHP之路——PHPExcel使用
    PHP之路——Apache启动失败查看日志
    pycharm——常用快捷键操作
    python_常用断言assert
    python通过一句话判断闰年的代码
    通过Python实现mysql查询数据库实例
  • 原文地址:https://www.cnblogs.com/Hitman_47/p/4419871.html
Copyright © 2020-2023  润新知