linux创建新进程的内核实现,Linux内核创建一个新进程的实验

Linux内核对进程管理是操作系统的重要任务之一。此次实验就是了解内核创建一个新进程的大致过程。为了简单,使用fork再用户态创建一个进程。代码如下:#include 

#include 

#include 

int main(int argc, char * argv[])

{

int pid;

/* fork another process */

pid = fork();

if (pid 

{

/* error occurred */

fprintf(stderr,"Fork Failed!");

exit(-1);

}

else if (pid == 0)

{

/* child process */

printf("This is Child Process!\n");

}

else

{

/* parent process  */

printf("This is Parent Process!\n");

/* parent will wait for the child to complete*/

wait(NULL);

printf("Child Complete!\n");

}

}

在虚拟机环境中运行情况如下图:

481538e880bbdd0f4a4f84c38f9fcef4.png

681f952ce2d5508bc7f511317bfc865c.png

以下使用gdb调试一下,在进程创建过程中的几个关键函数出设置断点。

fbad56ea77d9454766f76f8b574ff7b6.png

在系统启动过程走了些弯路,设置断点的这几个函数都是系统创建进程所必须的关键部分,所以启动过程中do_fork,copy_process,copy_thread不断的多次出现,我只好暂时使断点失效,才让menuos顺利启动到命令提示符。disable breakpoints 1 2 3 4 5 6.

执行fork命令,停在了断点SyS_clone处,单步执行,定在了断点do_fork处。经过几行代码,

p = copy_process(clone_flags, stack_start,stack_size,chile_tidptr, NULL,trace);

停在断点copy_process.在执行几行代码,如下:

p = dup_task_struct(current);

继续执行,断点arch_dup_task_struct停住。

连续n命令后可以看到子进程的初始化过程:

66d72fdb11971c363ec2fea882962eaf.png

程序执行断在copy_thread后如下:

c85fc02d052ff1e0a2a74e1b20eb8731.png

执行finish,及continue命令,进入了子进程执行的起点ret_from_fork.

0ae9b15704b0dd6280a34961f70521e6.png

执行c命令,主要过程基本结束。

总结,创建一个新进程在内核中的执行过程大致如下

1.使用系统调用SyS_clone(或fork,vfork)系统调用创建一个新进程,而且都是通过调用do_fork来实现进程的创建;

2.Linux通过复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈;

3.要修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread

4.p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶

p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值