2022-2023-1 20222808《Linux内核原理与分析》第七周作业

实验六 分析Linux内核创建一个新进程的过程

一、实验内容

分析Linux内核创建一个新进程的过程

1、阅读理解task_struct数据结构 链接

2、分析 fork 函数对应的内核处理过程 sys_clone,理解创建一个新进程如何创建和修改 task_struct 数据结构;

3、使用 gdb 跟踪分析一个 fork 系统调用内核处理函数 sys_clone ,验证您对 Linux 系统创建一个新进程的理解,推荐在实验楼 Linux 虚拟机环境下完成实验。 特别关注新进程是从哪里开始执行的?为什么从那里能顺利执行下去?即执行起点与内核堆栈如何保证一致;

二、实验过程

1、task_struct数据结构

在 linux 中每一个进程都由 task_struct 数据结构来定义。 task_struct 就是 PCB。是对进程控制的唯一手段也是最有效的手段。当我们调用 fork() 时, 系统会为我们产生一个 task_struct 结构,然后从父进程那里继承一些数据, 并把新的进程插入到进程树中, 以待进行进程管理。

2、分析 fork 函数对应的内核处理过程 sys_clone,理解创建一个新进程如何创建和修改 task_struct 数据结构

系统调用服务例程sys_clone, sys_fork, sys_vfork三者最终都是调用do_fork函数完成。
do_fork函数原型位于linux-3.18.6/kernel/fork.c。fork函数可以创建进程,创建一个进程是复制当前进程的信息,被复制的进程成为父进程,被创建的新进程成为子进程。父进程和子进程的绝大部分信息是完全一样的,但是有些信息不能一样,比如pid的值和内核堆栈。还有将新进程链接到各种链表中,要保存进程执行到哪个位置,有一个thread数据结构记录ip和sp等信息也不能一样。所以,父进程创建子进程时,会有一个地方复制父进程的进程描述符task_struct结构体变量,并有很多地方来修改复制的进程描述符task_struct结构体变量。

3、使用 gdb 跟踪分析一个 fork 系统调用内核处理函数 sys_clone

在MenuOS中添加fork函数,函数如下:

#include <unistd.h> 
int Fork(int argc, char *argv[]) 
{
	int pid;
	pid = fork();                                 
	if (pid<0) 
	{ 
		fprintf(stderr,"Fork Failed!");
		exit(-1);
	} 
	else if (pid==0)                              
	{
		printf("This is Child Process!\n");
	} 
	else 
	{   
		printf("This is Parent Process!\n");          
		wait(NULL);
		printf("Child Complete!\n");
	}
}

并在主函数中添加如下代码

MenuConfig("fork","Fork a new process",Fork);

在终端中输入以下指令

cd ~/LinuxKernel
cd menu
make rootfs

在这里插入图片描述
接着输入以下指令

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

进行gdb跟踪调试,在sys_clone、do_fork、dup_task_struct、copy_process、copy_thread、ret_from_fork等处各设置断点(断点2设置错误),执行过程如下图所示:
在这里插入图片描述
输入c开始执行,停留在sys_clone。
在这里插入图片描述
继续执行,停留在copy_process。
在这里插入图片描述
输入c继续执行,停在dup_task_struct函数,进入dup_task_struct内部,将当前进程内核压栈,将压得那一部分寄存器复制到子进程中,并赋值子进程的起点。
在这里插入图片描述

三、实验总结

1、操作系统内核三大功能是进程管理,内存管理,文件系统,最核心的是进程管理。
2、fork系统调用会创建一个当前进程的子进程。C语言库函数中的fork()在父进程中的返回值为子进程的pid,在子进程中的返回值为0。我们可以根据返回值的不同令父进程和子进程分别执行各自的任务。
3、fork系统调用与其它系统调用相似,都要利用int 0x80指令产生中断,然后由操作系统进行关闭中断和保护现场的工作,通过查询系统调用表找到fork系统调用的入口地址。这个入口一直一般为sys_clone, sys_fork, sys_vfork中的一个,这三个入口最终都会调用do_fork()函数。C库函数中的fork()函数会调用sys_clone。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值