2020-2021-1 20209312《Linux内核原理与分析》第七周作业

作业信息

这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)>
这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第七周作业>
这个作业的目标 分析Linux内核创建一个新进程的过程
作业正文 https://www.cnblogs.com/ZHANGwg11/p/14007689.html

1.给MenuOS添加一个fork命令,该命令调用了linux内核中的fork系统调用
代码如下:(在LinuxKernel文件里面进行如下操作)

cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu 
mv test_fork.c test.c
make rootfs


检查fork是否存在:

2.启动gdb,并在各个接口添加断点

file linux-3.18.6/vmlinux
target remote:1234
//设置断点
b sys_clone
b do_fork
b dup_task_struct//未定义
b copy_process//未定义
b copy_thread
b ret_from_fork

这里有一些小插曲
我们只需改变上面的一行代码即可:

make rootfs//改变前
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s//改变后


改变后的代码调试



3.总结
Linux中创建进程一的三个函数:

  fork,创建子进程。
  clone,主要用于创建线程。
  vfork,与fork类似,但是父子进程共享地址空间,而且子进程先于父进程运行。

操作系统内核实现操作系统的三大管理功能,即进程管理、内存管理和文件系统,对应操作系统原理课程中最重要的3个抽象概念是进程、虚报内存和文件。其中,我作系统内核中最核心的功能是进程管理。谈到进程管理就要涉及一个问题:进程是怎样描述的? 进程的描述有提纲挈领的作用,它可以把内存管理、文件系统、信号、 进程间通信等概念 和内容串起来。Linux 内核中的进程是非常复杂的,在操作系统原理中,我们通过进程控制块PCB描述进程。为了管理进程,内核要描述进程的结构,我们也称其为进程描述符,进程描述符提供了进程相关的所有信息。

可以把整个进程描述抽象为如下图的示意图。操作系统中的进程有就绪态、运行态、阻塞态这三种基本状态,实际的Linux内核管理的进程状态与这3个状态很不一样。

当使用fork()系统调用来创建一个新进程时,新进程的状态是TASK_RUNNING (就绪态,但是没有在运行)。当调度器选择这个新创建的进程运行时,新创建的进程就切换到运行态,它也是TASK_RUNNING。为什么操作系统原理中就绪态和运行态两个状态在 Linux内核中都是相同的TASK_RUNNING状态呢?也就是说,在Linux内核中,当进程是TASK_RUNNING状态时,它是可运行的,也就是就绪态,是否在运行取决于它有没有获得CPU的控制权,也就是说这个进程有没有在CPU中实际执行。如果在CPU中执行了,进程状态就是运行态;如果被内核调度出去了,在等待队列里就是就绪态。
对于一个正在运行的进程, 调用用户态库函数exit()会陷入内核执行该内核函数do_exit,(也就是终止进程,那么会进入TASK_ZOMBIE状态,即进程的终止状态,TASK_ZOMBIE状态的进程一般叫作僵尸进程,Linux内核会在适当的时候把僵尸进程给处理掉,处理掉之后进程描述符被释放了,该进程才从Linux系统里消失。
一个正在运行的进程在等待特定的事件或资源时会进入阻塞态。阻塞态也有两种,TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE。TASK_INTERRUPTIBLE状态是可以被信号和wake_ up()唤醒的,当信号到来时,进程会被设置为TASK_RUNNING(就绪态,但是没有在运行),而TASK_UNINTERRUPTIBLE只能被wake_up()唤醒。如果事件发生或者资源可用,进程被唤醒并被放到运行队列上(操作系统原理的说法应该是就绪队列)。如果阻塞的条件没有了,就进入就绪态,调度器选择到它时就进入运行态。这和操作系统原理中本质上是一样的。

原文地址:https://www.cnblogs.com/ZHANGwg11/p/14007689.html