Linux内核分析 笔记六 进程的描述和进程的创建 ——by王玥
一、知识点总结
(一)进程的描述
1.操作系统内核里有三大功能:
- 进程管理
- 内存管理
- 文件系统
2.进程描述符:task_struct
2.进程描述符——struct task_struct
1. pid_t pid又叫进程标识符,唯一地标识进程
2.双向循环链表链接起了所有的进程,也表示了父子、兄弟等进程关系 3. struct mm_struct 指的是进程地址空间,涉及到内存管理(对于X86而言,一共有4G的地址空间) 4. thread_struct thread 与CPU相关的状态结构体 5. struct *file表示打开的文件链表 6. Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈
3.进程状态转换图
数据结构分析:
struct task_struct { 1236 volatile longstate; //运行状态 1237 void *stack; //进程的内核堆栈 1238 atomic_tusage; 1239 unsigned intflags;//每个进程的标识符 1240 unsigned int
#ifdef CONFIG_SMP //这部分是条件编译 1243 struct llist_nodewake_entry; 1244 inton_cpu; 1245 struct task_struct *last_wakee; 1246 unsigned longwakee_flips; 1247 unsigned longwakee_flip_decay_ts;.....
struct list_headtasks; //这部分很关键,是进程的列表 1296#ifdef CONFIG_SMP 1297 struct plist_nodepushable_tasks; 1298 struct rb_nodepushable_dl_tasks; 1299#endif 1300 1301 struct mm_struct *mm, *active_mm;//和地址的内存空间,内存管理有关的,每个地址有独立的地址空间。 1302#ifdef CONFIG_COMPAT_BRK 1303 unsignedbrk_randomized:1; 1304#endif 1305 /* per-thread vma caching */ 1306 u32vmacache_seqnum; 1307 struct vm_area_struct *vmacache[VMACACHE_SIZE]; 1308#if defined(SPLIT_RSS_COUNTING) 1309 struct task_rss_statrss_stat; 1310#endif链表的数据结构如下: 它是一个双向链表,参见include/linux/list.h
1330 pid_tpid;//进程的pid,来标识某一个进程 1331 pid_ttgid;....
/* 1338 * pointers to (original) parent process, youngest child, younger sibling,//进程的父子关系 1339 * older sibling, respectively. (p->father can be replaced with 1340 * p->real_parent->pid) 1341 */ 1342 struct task_struct __rcu *real_parent; /* real parent process */ 1343 struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */ 1344 /* 1345 * children/sibling forms the list of my natural children 1346 */ 1347 struct list_headchildren; /* list of my children */ 1348 struct list_headsibling; /* linkage in my parent's children list */ 1349 struct task_struct *group_leader; /* threadgroup leader */ 1350
...1411/* CPU-specific state of this task */
1412 struct thread_struct thread;//当前CPU相关的状态,在进程切换时起关键作用。
(二)进程的创建
- 1.进程的状态以及fork一个进程的用户态代码
- 2.fork系统调用在父进程和子进程各返回一次
- 3.TASK_RUNNING具体是就绪还是执行,要看系统当前的资源分配情况
- 4. TASK_ZOMBIE也叫僵尸进程
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.}
- iret与int 0x80指令对应,一个是弹出寄存器值,一个是压入寄存器的值
- 如果将系统调用类比于fork();那么就相当于系统调用创建了一个子进程,然后子进程返回之后将在内核态运行,而返回到父进程后仍然在用户态运行
- 回顾:系统调用的进程创建过程
创建一个新进程在内核中的执行过程
1.一个新创建的子进程,(当它获得CPU之后)是从哪一行代码进程执行的?
- 与之前写过的my_kernel相比较,kernel中是可以指定新进程开始的位置(也就是通过eip寄存器指定代码行)。fork中也有相似的机制
这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
- fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;
- Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:
复制一个PCB——task_struct
- err = arch_dup_task_struct(tsk, orig);
要给新进程分配一个新的内核堆栈
- ti = alloc_thread_info_node(tsk, node);
- tsk->stack = ti;
- setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈
要修改复制过来的进程数据,比如pid、进程链表等等都要改改吧,见copy_process内部。
从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
- *childregs = *current_pt_regs(); //复制内核堆栈
- childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
- p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
- p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
- dup_thread复制父进程的PCB
- copy_process修改复制的PCB以适应子进程的特点,也就是子进程的初始化
分配一个新的内核堆栈(用于存放子进程数据)
- 内核堆栈的一部分也要从父进程中拷贝
-根据拷贝的内核堆栈情况设置eip,esp寄存器的值
使用gdb跟踪创建新进程的过程
- 更新menu内核,然后删除test_fork.c以及test.c(以减少对之后实验的影响)
- 编译内核,可以看到fork命令
- 启动gdb调试,并对主要的函数设置断点
- 在MenuOS中执行fork,就会发现fork函数停在了父进程中
- 继续执行之后,停在了do_fork的位置。然后n单步执行,依次进入copy_process、dup_task_struct。按s进入该函数,可以看到dst =src(也就是复制父进程的struct)
3.在copy_thread中,可以看到把task_pg_regs(p)也就是内核堆栈特定的地址找到并初始化
4.到了159、160行的代码就是把压入的代码再放到子进程中:
*children = *current_pt_regs(); childregs->ax = 0;
164行,是确定返回地址
p->thread.ip = (unsigned long) ret_from_fork;
最后
,可以输入finish使得进程运行完。
转载于:https://www.cnblogs.com/disturbia/p/5332980.html
Linux内核分析 笔记六 进程的描述和进程的创建 ——by王玥相关推荐
- Linux内核分析 笔记二 操作系统是如何工作的 ——by王玥
一.知识要点 1.计算机是如何工作的?(总结)--三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算 ...
- Linux内核分析 笔记七 可执行程序的装载 ——by王玥
一.预处理.编译.链接和目标文件的格式 (一)可执行程序是怎么得来的? 1. 2.可执行文件的创建--预处理.编译和链接 shiyanlou:~/ $ cd Code ...
- 庖丁解牛linux内核 百度云,庖丁解牛Linux内核分析笔记-1
2019-5-3 主要内容摘自 孟宁<庖丁解牛Linux内核分析> 天下大事必作于细,天下难事必作于易 1.计算机三大法宝 存储程序计算机 函数调用堆栈 中断 2.虚拟一个x86的CPU硬 ...
- 庖丁解牛山linux内核的析,# 庖丁解牛Linux内核分析笔记-1
2019-5-3 主要内容摘自 孟宁<庖丁解牛Linux内核分析> 天下大事必作于细,天下难事必作于易 1.计算机三大法宝 存储程序计算机 函数调用堆栈 中断 2.虚拟一个x86的CPU硬 ...
- Linux内核分析 - 网络[六]:网桥
看完了路由表,重新回到netif_receive_skb ()函数,在提交给上层协议处理前,会执行下面一句,这就是网桥的相关操作,也是这篇要讲解的内容. [cpp] view plaincopy sk ...
- Linux内核分析期末总结
<Linux内核分析>期末总结 20135313吴子怡.北京电子科技学院 Chapter1 往期博客传送门 (1)计算机是如何工作的:Linux内核分析--第一周学习笔记 (2)操作系统是 ...
- [网易云课堂]Linux内核分析(九)—— 课程总结
付何山+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000; 导读:本文分为两个部分 ...
- 《Linux内核分析》 第六节 进程的描述和进程的创建
<Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...
- Linux内核分析——进程的描述和进程的创建
进程的描述和进程的创建 一. 进程的描述 (一)进程控制块PCB--task_struct 1.操作系统的三大管理功能包括: (1)进程管理 (2)内存管理 (3)文件系统 2.PCB task_st ...
最新文章
- antd 表单提交,文件和表单内容一起提交,表单校验
- gpupdate /force 遇报错解决过程
- SpringBootController控制层接收参数的几种常用方式
- BZOJ2199: [Usaco2011 Jan]奶牛议会
- SAP Spartacus component-wrapper自定义指令的实现
- dom4j读取XML文件内容
- 观察者模式Observer
- 设置android 触摸灵敏,3D Press触屏灵敏度设置教程 魅族PRO 6 3D Press触控力度怎么调...
- Unix下oracle备份,Linux下Oracle备份与数据迁移
- dcdc升压计算器excel_两款低压DC-DC升压转换器应用电路
- 百度冰桶算法2.0简介
- antd vue表单验证_解决antd 表单设置默认值initialValue后验证失效的问题
- vue keep-alive用法
- 万豪环保系列之《紫外线消毒器》
- 解决谷歌浏览器跨域以及cookie保存失效重复登录
- 生鲜电商运营框架的对比和分析
- css tabindex
- 内网渗透攻击技术的利用
- Just A Triangle
- Java基础03运算符
热门文章
- java-12:spring MVC - 控制反转IOC,依赖注入DI
- 基于wifi面向android的远程视频监控客户端开发,基于Wifi面向Android的远程视频监控客户端开发...
- 2.57亿美元:纸币打破了ICO资金的全部记录
- Jumpserver安装和测试连接
- “云”中智控 IT管理新境界
- 苹果称只保证直营店iPad补差价 近1周投诉急增
- 关于单片机对三极管B值的测量
- boj489. 小妹妹去划船
- C++程序员学习用C#写网站(四)
- 向凡客提议:建立ERP 深挖服装市场价值