《Linux内核分析》第六周 进程的描述与创建
【刘蔚然 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000】
WEEK SIX(3.28——4.3)进程的创建与描述
SECTION 1 进程描述
1.进程控制块——PCB
2.进程描述符——struct task_struct
1. pid_t pid又叫进程标识符,唯一地标识进程
2. 第1295行,list_head tasks即 进程链表
- 双向循环链表链接起了所有的进程,也表示了父子、兄弟等进程关系
3. struct mm_struct 指的是进程地址空间,涉及到内存管理(对于X86而言,一共有4G的地址空间)
4. thread_struct thread 与CPU相关的状态结构体
5. struct *file表示打开的文件链表
6. Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈
3.进程状态转换图

- TASK_RUNNING具体是就绪还是执行,要看系统当前的资源分配情况;
- TASK_ZOMBIE也叫僵尸进程
SECTION 2 进程的创建
1.进程的创建概览及fork一个进程的源代码
回顾:start_kernel创建了cpu_idle,也就是0号进程。而0号进程又创建了两个线程,一个是kernel_init,也就是1号进程,这个进程最终启动了用户态;另一个是kthreadd。这就是“道生一,一生二”。0号进程是固定的代码;1号进程是通过复制0号进程PCB之后在此基础上做修改得到的。
回顾:系统调用的进程创建过程



iret与int 0x80指令对应,一个是弹出寄存器值,一个是压入寄存器的值
如果将系统调用类比于fork();那么就相当于系统调用创建了一个子进程,然后子进程返回之后将在内核态运行,而返回到父进程后仍然在用户态运行
fork代码
1.#include <stdio.h>
2.#include <stdlib.h>
3.#include <unistd.h>
4.int main(int argc, char * argv[])
5.{
6.int pid;
7./* fork another process */
8.pid = fork();
9.if (pid < 0)
10.{
11./* error occurred */
12.fprintf(stderr,"Fork Failed!");
13.exit(-1);
14.}
15.else if (pid == 0) //pid == 0和下面的else都会被执行到(一个是在父进程中即pid ==0的情况,一个是在子进程中,即pid不等于0)
16.{
17./* child process */
18.printf("This is Child Process!\n");
19.}
20.else
21.{
22./* parent process */
23.printf("This is Parent Process!\n");
24./* parent will wait for the child to complete*/
25.wait(NULL);
26.printf("Child Complete!\n");
27.}
28.}
创建新进程的框架
fork,vfork,clone都可以创建新进程,他们都是通过调用do_fork来实现的。dup_thread复制父进程的PCB

copy_process修改复制的PCB以适应子进程的特点,也就是子进程的初始化

分配一个新的内核堆栈(用于存放子进程数据)
内核堆栈的一部分也要从父进程中拷贝

-
根据拷贝的内核堆栈情况设置eip,esp寄存器的值
一个新创建的子进程,(当它获得CPU之后)是从哪一行代码进程执行的?
与之前写过的my_kernel相比较,kernel中是可以指定新进程开始的位置(也就是通过eip寄存器指定代码行)。fork中也有相似的机制
这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
1.*childregs = *current_pt_regs(); //复制内核堆栈,并不是全部,只是regs结构体(内核堆栈栈底的程序)
2.childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
3.
4.p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
5.p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址,也就是说返回的就是子进程的空间了
2.使用gdb跟踪创建新进程的过程
更新menu内核,然后删除test_fork.c以及test.c(以减少对之后实验的影响)
编译内核,可以看到fork命令
启动gdb调试,并对主要的函数设置断点
在MenuOS中执行fork,就会发现fork函数停在了父进程中
继续执行之后,停在了do_fork的位置。然后n单步执行,依次进入copy_process、dup_task_struct。按s进入该函数,可以看到*dst = *src(也就是复制父进程的struct)
在copy_thread中,可以看到把task_pg_regs(p)也就是内核堆栈特定的地址找到并初始化
到了159、160行的代码就是把压入的代码再放到子进程中:
*children = *current_pt_regs();
childregs->ax = 0;
164行,是确定返回地址
p->thread.ip = (unsigned long) ret_from_fork;
此后,可以输入finish使得进程运行完。
总结与补充
我在上周的实验中尝试用实验楼(链接个人热点)进行实验,发现报错(地址无法解析)。然而在本周的实验中,连接广域网之后,实验楼的环境可以正常进行menu的联网更新。我认为应该是连接的网络决定了实验楼的实验环境能否与外界网络发生交互。
《Linux内核分析》第六周 进程的描述与创建的更多相关文章
- Linux内核设计第六周 ——进程的描述和创建
Linux内核设计第六周 ——进程的描述和创建 第一部分 知识点总结 一.进程描述符task_struct数据结构 1.操作系统的三大功能: 进程管理.内存管理.文件系统 2.进程的作用: 将信号.进 ...
- 20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建
进程的描述和进程的创建 一.进程的描述 操作系统三大功能: 进程管理 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰 ...
- LINUX内核分析第六周学习总结——进程的描述与创建
LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...
- LINUX内核分析第六周学习总结——进程的描述和进程的创建
LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
- Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程
Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
- linux内核分析第六周学习笔记
LINUX内核分析第六周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...
- Linux分析第六周——进程的描述和进程的创建
Linux分析第六周--进程的描述和进程的创建 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...
- Linux内核分析第八周——进程的切换和系统的一般执行过程
Linux内核分析第八周--进程的切换和系统的一般执行过程 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...
- Linux内核分析——第六周学习笔记20135308
第六周 进程的描述和进程的创建 一.进程描述符task_struct数据结构 1.操作系统三大功能 进程管理 内存管理 文件系统 2.进程控制块PCB——task_struct 也叫进程描述符,为了管 ...
随机推荐
- oracle去重
oracle去重 create table tmp_table3 as (SELECT seqno FROM (SELECT t.seqno,ROWID, ROW_NUMBER() OVER(PART ...
- 如何处理js的跨域问题
在bill.mail.10086.cn域内访问smsrebuild1.mail.10086.cn下的接口出现“阻止跨域源请求” 例如: URL 说明 是否允许通信 http://www.a.com/a ...
- 编程之路 - 写给打算进入IT行业的新人们
IT=挨踢,这是IT人的自嘲,进入IT行业是有四五年了,也算得上是一个“老人”了吧,见了不少新人,面试了不少新人,也带了一些新人,多多少少还是有点发言权的. 关于书本 新人们常常会说我看了多少多少的书 ...
- HDU3068最长回文 题解
题目大意: 求字符串的最长回文子串的长度. 思路: Manacher板题,Hash可能会T.要学习Manacher,可参考https://www.felix021.com/blog/read.php? ...
- Android 通信 EventBus
参考: Android 框架炼成 教你如何写组件间通信框架EventBus Android EventBus源码解析 带你深入理解EventBus Android EventBus实战 没听过你就ou ...
- 数论初步(费马小定理) - Happy 2004
Description Consider a positive integer X,and let S be the sum of all positive integer divisors of 2 ...
- 【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS
Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...
- 【Eclipse】 Alt+/ 代码提示问题解决方案
一般情况下alt+/有代码提示作用,还有代码提示的快捷代码也不是alt+/,因此要恢复代码提示用alt+/.需要做两件事. 在 Window - Preferences - General - Key ...
- C#读取文本播放相应语音【转】
第一种方案: 利用微软text to speech引擎(TTS),读取文本 (1)添加Microsoft Speech Object Library的项目引用 (2)引入using SpeechLib ...
- 用css3实现一个带缺口的圆圈(图)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...






