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

陈涛 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、实验

首先,进入实验楼环境,进入LinueKernel文件。
这里写图片描述
然后,删除menu,clone一份新的,再将test.c覆盖为fork.c,make rootfs。
这里写图片描述
进入menuOS,实现fork函数功能。
这里写图片描述
请来大小S,进行设置断点:sys_clone, do_fork, dup_task_struct, copy_process, copy_thread进行调试。
这里写图片描述
这里写图片描述
跟踪分析一个fork系统调用内核处理函数sys_clone,结束实验。

二、进程分析

一、task_struct数据结构

1.task_struct结构:
struct task_struct{
volatile long state; 进程状态
void stack; 堆栈*
pid_t pid; 进程标识符
unsigned int rt_priority; 实时优先级
unsigned int policy; 调度策略
struct files_struct files; 系统打开文件*

}

二、进程的创建

在Linux应用程序的开发中,可以通过fork、vfork和clone等API来创建一个子进程,它们在Linux内核中对应的系统调用分别为sys_fork、sys_vfork和sys_clone函数,而这些函数最终都会调用do_fork完成子进程的创建。do_fork主要是复制了父进程的task_struct,然后修改必要的信息,从而得到子进程的task_struct。主要修改了以下信息:
(1)pid,进程链表等
(2)系统调用内核处理函数:sys_fork、sys_clone、sys_vfork
(3)do_fork()中包含的copy process创建一个进程内容的主要代码
(4)arch dup_task_struct复制整个PCB(dst=src数据结构的值复制给dst)
(5)thread_info内核堆栈,创建一个页面,比较大(分配内核堆栈空间)
(6)p指向子进程的描述符
(7)copy_thread从子进程的pid找到了栈底的地址,把sp赋值过去,对父进程的栈底进行拷贝,包括栈顶数据,thread ip的内容。
这里写图片描述

三、子进程运行

ret_from_fork决定了新进程的第一条指令地址。p->thread.ip = (unsigned long) ret_from_fork;将子进程的ip设置为ret_from_fork的首地址。从用户态代码来看,fork()函数返回了两次,即在父子进程中各返回一次!但是子进程的返回值是0,从返回值我们就可以判断出返回后接下来要执行的代码是中父进程还是子进程中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值