码迷,mamicode.com
首页 > 系统相关 > 详细

作业6:进程的描述和进程的创建 20135115臧文君

时间:2016-03-31 23:12:26      阅读:351      评论:0      收藏:0      [点我收藏+]

标签:

进程的描述和进程的创建

 

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

 

一、进程的描述

操作系统的三大功能:进程管理,内存管理和文件系统。

1、进程描述符task_struct数据结构

(1)进程控制块PCB---task_struct

(2)进程描述符提供了内核所需了解的进程信息。

task_struct中包含:进程状态,进程打开的文件,进程优先级信息。

技术分享

技术分享

技术分享

tty_struct控制台

fs_struct文件系统

files_struct打开的文件描述符

mm_struct内存管理

signal_struct通讯信号的描述

(3)struct task_struct的数据结构很庞大

(4)Linux进程的状态与操作系统原理中的描述的进程状态似乎有所不同,比如:就绪状态和运行状态都是TASK_RUNNING。

进程调用do_exit()终止执行,TASK_ZOMBIE(进程被终止)。

阻塞态:TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE(等待中)。

技术分享 

2、进程的标识pid

 技术分享

3、task_struct数据结构分析

 技术分享

(1)运行状态state:-1 unrunnable,0 runnable,>0 stopped。

进程的内核堆栈stack。

ifdef CONFIG SMP条件编译,多处理器时用到。

进程链表list_head tasks

 技术分享

4G的进程地址空间

(2)进程的父子关系

 技术分享

 技术分享

P0有三个儿子P1,P2,P3;P1有两个兄弟P2,P3;P3有一个儿子P4。

(3)CPU相关的状态:thread_struct

文件系统:fs_struct

 

二、进程的创建

1、进程的创建概览及fork一个进程的用户态代码

 技术分享

fork()是用户态用于创建一个子进程的系统调用。

 技术分享

fork()系统调用在父进程和子进程各返回一次,在子进程中,pid的返回值为0,执行else的代码,在父进程中,pid的返回值为子进程的ID,执行else if的代码。

2、系统调用再回顾

 技术分享

 技术分享

 技术分享

3、一个新创建的子进程从哪里开始执行?

创建新进程是通过复制当前进程来实现的。

 技术分享

系统调用内核处理函数sys_fork、sys_clone、sys_vfork

4、do fork中的copy process就是创建一个进程的主要代码。

dup task struct复制整个PCB。

拷贝内核堆栈数据和指定新进程的第一条指令地址:*childregs = *current_pt_regs();

 技术分享

5、创建的新进程是从哪里开始执行的?

p->thread.ip = (unsigned long) ret_from_fork;

 技术分享

当子进程获得CPU控制权时,它的return from fork可以把后面堆栈中的iret返回到用户态。

 

三、使用gdb跟踪创建新进程的过程

1、先删除menu,再克隆一个新的menu。

2、用test_fork.c覆盖test.c:

cd menu

mv test_fork.c test.c

make rootfs//编译

3、调试:

qemu-system-x86_64 -kernel bzImage -initrd /home/YL/menu/rootfs.img -s -S

技术分享

gdb /usr/src/linux-source-4.4/vmlinux

set arch i386:x86-64

target remote:1234

 技术分享

4、设置断点:b sys_clone

b do_fork

b dup_task_struct

b copy_process

b copy_thread

b ret_from_fork

 技术分享

5、按c继续执行,但会报错显示超时,此时重启一遍gdb即可。

 技术分享

 技术分享

6、按n单步执行,按s进入某个函数中去单步执行。

 技术分享

 技术分享

技术分享

当前进程的内核堆栈中压的寄存器复制到进程中:

技术分享 

设置子进程被调度的IP,是子进程的起点ret_from_fork:

 技术分享

 

总结:

     本次课程学习的是进程的结构分析以及进程的创建。Linux系统创建一个新进程主要依靠fork(),fork()是用户态用于创建一个子进程的系统调用,再由fork()调用do_fork来实现进程的创建。

     先复制一个PCB——task_struct,再给新进程分配一个新的内核堆栈,并且修改复制过来的进程数据,比如pid、进程链表等等。通过以上步骤,就可以创建一个新进程。

     新进程的起点是ret_from_fork,通过*childregs = *current_pt_regs()语句复制内核堆栈。

     在实验的过程中,会遇到gdb的问题,显示连接超时,此时需要重启gdb即可。另外,调试内核时还需要注意路径的问题。若没有给出路径,则是在当前目录下查找文件。

作业6:进程的描述和进程的创建 20135115臧文君

标签:

原文地址:http://www.cnblogs.com/CatherineZang/p/5343121.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!