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

|这个作业属于哪个课程|<2020-2021-1Linux内核原理与分析)>|
:-: | :-: | :-:
|这个作业要求在哪里|<2020-2021-1Linux内核原理与分析第七周作业>|
|这个作业的目标|<分析Linux内核创建一个新进程的过程>| :-: | :-: | :-:
|作业正文|<2020-2021-1 202029325 《Linux内核原理与分析》第七周作业>|

一、实验过程

1.删除之前的menu,再通过git克隆一份新的,使用mv把test.c覆盖掉,然后执行 make roofts,代码如下:

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

PS:如果menu已经是最新,可以不用执行删除和重新下载的操作
结果如下图:

2.使用水平分割,再开启一个shell窗口,启动gdb,把内核加载进来,连接到target remote 1234,代码如下:

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

在设置接口后,会出现time out的问题,解决方法:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
运行结果如下图:

二、实验收获

在代码运行运行过程中,进程的可分为不同的状态,在linux下,进程分为三种主要状态状态:就绪态、运行态和阻塞状态。每种状态将会依据外部条件不断的切换。 刚开始创建的进程叫做就绪态,叫做task_running 当被调用之后,开始运行叫做运行态,也叫做task_running 这两个状态都用了task_runing同一个标志,可理解为可运行状态,是否运行要看时间片等信息。 如果进程终止后进入僵尸状态,最终被回收。 如果等待某件事情将进入阻塞状态。如果被唤醒重新进入就绪态。

本文主要学习了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,这是子进程的起点,运行,子进程可以执行并显示在终端中。总结来讲,进程的创建过程大致是赋值进程描述符,复制其他进程资源,分配子进程的内核堆栈并对内核堆栈关键信息进行初始化。

posted @ 2020-11-20 20:23  20209325葛耀东  阅读(175)  评论(0编辑  收藏  举报