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

进程的描述和进程的创建——第六周(20135304刘世鹏)

时间:2016-04-03 22:08:45      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

进程的描述和进程的创建

 作者:刘世鹏20135304                                                                                      

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

一、进程的描述

1、1进程描述符task_struck数据结构(一)

(1)操作系统的三大功能:进程管理、内存管理、文件系统。

(2)

技术分享

进程控制块PCB——task_struck

tty_struck控制台

fs_struck文件系统的描述

files_struck打开的文件描述符

mm_struck内存的描述

signal_struck信号的描述

(3)操作系统原理中的状态:就绪态、运行态、阻塞态

(4)

技术分享

内核管理中的进程状态:

TASK_TUNNING(可运行)获得cpu控制权正在运行,被调度出去就是就绪态。

TASK_ZOMBIE(进程被终止)

TASK_interruotibie(阻塞态)

TASK_uninterruotibie(阻塞态)

(5)进程的标示符:pid(用来标识进程)

1、2进程描述符task_struck数据结构(二)

(1)state运行状态(指定进程状态)

(2)SMP条件编译(多处理器时会用到)

(3)

技术分享   技术分享

struct list_head tasks进程的链表,双向循环链表连接,链表可独立进行操作

(4)每个进程有自己独立的地址空间,32位x86有4G进程地址空间。

(5)pid_t pid标识一个进程

(6)

技术分享

进程的父子关系:兄弟父子之间的关系通过双向链表连接起来。

(7)CPU相关的状态:thread_struct(sp、ip)进程上下文切换时期关键作用

(8)struct files_struct*files打开文件列表

(9)struck signal_struct *signal信号处理相关工作

二、进程的创建过程

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

(1)(文件系统、信号、内存)进程描述符中有相应的指针指向其内容,进行研究。

(2)

技术分享

进程是怎么创建的:复制一份进程描述符,0号进程用代码写死,1号进程复制0号进程pcb,根据1号进程需要修改pid,最后加一个init可执行程序。

(3)

技术分享

子进程从哪里开始执行:shell命令行怎么创建子进程的?

fork()用户态进行创建子进程

fork系统调用在父进程和子进程各返回一次

(4)fork在子进程中返回值是父进程的ID

2、2理解进程创建过程复杂代码的方法

(1)系统调用再回顾:

技术分享 技术分享

Int0x80是中断指令,把用户态堆栈转化到内核态堆栈,把CPU最关键的现场eip、esp保存到内核堆栈中去。

(2)

技术分享  技术分享

    子进程从哪里开始执行:fork()出的子进程在内核中开始返回。创建一个进程的框架:复制一份进程描述符,0号进程用代码写死,1号进程复制0号进程pcb,根据1号进程需要修改pid,最后加一个init可执行程序。

(3)创建进程过程中要做哪些事情:修改pcb,建立链表,修改分配内核堆栈,保存进程执行到哪个位置,保存sp、ip(避免发生混乱),需要有thread设定eip和esp位置。

2、3浏览进程的创建过程相关的关键方法

(1)

技术分享

创建新进程在内核中执行的过程:

复制一个PCB——task_struct

给新进程分配一个新的内核堆栈

更改复制过来的进程数据,比如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的内容。

2、4创建的新进程是从哪里开始执行的

(1)子进程从哪里开始执行的:ret_from_fork

(2)

技术分享

Int指令和SAVE_ALL压到内核栈的内容。

(3)ret_from_fork 中的syscall_exit内核堆栈可正常返回到用户态(子进程的进程空间)。

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

自己实验截图:

(1)把menu删除,克隆一份新的,把test_fork.c覆盖掉,编译内核,可以看到fork命令

技术分享

技术分享

(2)设置断点sys_clone,设置断点do_fork,设置断点dup_task_struck,设置断点copy_process,设置断点copy_thread,设置断点ret_from_fork

技术分享

(3)在MenuOS中执行fork,就会发现fork函数停在了父进程中 

技术分享

(4)继续执行之后,停在了do_fork的位置

技术分享

(5)按s进入该函数,可以看到dst = src(也就是复制父进程的struct)

技术分享

(6)按n继续追踪

技术分享

(7)在copy_thread中,可以看到把task_pg_regs(p)也就是内核堆栈特定的地址找到并初始化

技术分享

进程的描述和进程的创建——第六周(20135304刘世鹏)

标签:

原文地址:http://www.cnblogs.com/L20135304/p/5350527.html

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