zoukankan      html  css  js  c++  java
  • 2019-2020-1 20199310《Linux内核原理与分析》第七周作业

    1.问题描述

    在前面的文章中,学习了系统调用system_call的处理过程,在MenuOS中运行getpid命令,通过gdb跟踪调用time函数的过程,并分析system_call代码对应的工作过程,本文将对Linux系统如何创建一个新进程进行追踪。

    2.解决过程

    2.1 进程的描述

    操作系统内核实现操作系统的三大管理功能:进程管理,内核管理和文件系统,其中最核心的功能是进程管理。
    在操作系统原理中,我们通过进程控制块PCB描述进程,通常采用一个数据结构struct task_struct来描述进程,其中比较常见的属性如state是进程状态,常见状态有就绪态,运行态和阻塞态,其运行过程如图所示:

    2.2 gdb跟踪调用fork函数的过程

    先对实验楼环境进行修改,删除menu,在github上克隆一份新的,并且把test.c覆盖,在menu下执行make rootfs,编译运行结果如下所示:


    退出menu目录,在LinuxKernel目录下执行

    qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
    

    然后横屏打开另一个终端,进行gdb追踪

    file linux-3.18.6/vmlinux
    target remote:1234
    

    然后对sys_clone,do_fork,dup_task_struct,copy_process,copy_thread和ret_from_fork设置断点:

    在gdb中continue执行到第一个断点SyS_clone处;

    执行至第2个断点do_fork创建新进程:


    单步执行调试,会停留在第4个断点copy_pocess:

    单步执行调试,会停留在第3个断点,在copy_process中调用dup_task_struct:

    继续执行调试,会停留在第5个断点copy_thread和第6个断点ret_from_fork上,父进程显示:

    单步跟踪,选中刚才创建的子进程的PCB,设置的ip进入ret_from_fork函数调度子进程语句,再重置标志寄存器eflags为0x0202,再跳转至syscall_exit退出:


    最终子进程显示结果:

    3.总结

    本文主要学习了Linux内核系统创建新子进程,并通过gdb和代码分析了调用过程。一般情况下,调用系统调用需在当前内核linux-3.18.6/arch/x86/syscalls/syscall_32.tbl中查找调用号,库函数sys_fork是用户态创建子进程的系统调用,此外可能会使用到sys_vfork sys_clone系统调用,但是这三个系统调用都会调用do_fork函数,本文中使用了sys_clone。do_fork会调用copy_process来复制父进程的资源给子进程。在copy_process中有各种函数来进行复制初始化工作。完成各项工作之后会执行ret_from_fork,这是子进程的起点,运行,子进程可以执行并显示在终端中。总结来讲,进程的创建过程大致是赋值进程描述符,复制其他进程资源,分配子进程的内核堆栈并对内核堆栈关键信息进行初始化。

  • 相关阅读:
    min-width和width的区别
    组装电脑
    css背景透明,文字不透明
    三十九、前端基础之HTML
    三十八、事务、mysql索引,视图
    三十七、python操作mysql,和navicat
    三十六、单表与多表查询
    三十五、表与表之间的关系
    三十四、字段类型
    三十三、初识数据库及简单命令
  • 原文地址:https://www.cnblogs.com/louhao-20199310/p/11780129.html
Copyright © 2011-2022 走看看