Linux内核设计第六周 ——进程的描述和创建
2016-03-29 16:47
459 查看
Linux内核设计第六周
——进程的描述和创建
第一部分 知识点总结
一、进程描述符task_struct数据结构
1、操作系统的三大功能:进程管理、内存管理、文件系统
2、进程的作用:
将信号、进程间通信、内存管理和文件系统联系起来
3、进程控制块PCB——task_struct数据结构
提供了内核需要了解的信息
4、task_struct结构庞大,有400多行代码。包含了进程状态、内核堆栈等相关信息的定义。 可以从下面的图示中,清晰的看出大体的框架。
![](https://images2015.cnblogs.com/blog/744671/201603/744671-20160329163804848-633685989.jpg)
5、Linux的进程和操作系统原理中描述的进程状态(就绪状态、运行状态、阻塞状态)有所不同,实际内核中,就绪和运行状态都用TASK_RUNNING表示。
二、进程的创建概览及fork一个进程的用户态代码
1、进程创建的关键信息:状态、内核堆栈、CPU上下文切换、链接、文件系统、信号、内存等。2、进程的起源
复制进程描述符
修改子进程的PCB信息
4、shell命令如何创建子进程
使用fork函数在用户态创建子进程
fork系统调用在父进程和子进程各返回一次
在子进程中,返回0,在父进程中,返回子进程ID
三、理解进程创建过程复杂代码的方法
理解进程创建过程复杂代码的方法:
先根据对功能的理解,自己预想可以怎样实现;
再从源代码中,找到和预想相似的证据。
1、系统调用复习
从系统内核理解
![](https://images2015.cnblogs.com/blog/744671/201603/744671-20160329164115582-869264414.jpg)
从用户程序理解
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char * argv[]) { int pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */ fprintf(stderr,"Fork Failed!"); exit(-1); } else if (pid == 0) //pid == 0和下面的else都会被执行到(一个是在父进程中即pid ==0的情况,一个是在子进程中,即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"); } }
3、fork、vork、clone都可以创建一个子进程,它们都调用了do_fork()实现进程创建。
四、浏览进程创建过程的关键代码
1、复制PCB——task_structerr = arch_dup_task_struct(tsk, orig);
2、给新进程创建新的内核堆栈
ti = alloc_thread_info_node(tsk, node);//创建新的内核堆栈 tsk->stack = ti; setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈 setup_thread_stack(tsk,orig);
3复制copy_process
即内核堆栈中的thread.sp的内容
4、fork执行过程分析
代码部分为
*childregs = *current_pt_regs(); //复制内核堆栈 childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因! p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶 p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
ret_from_fork就是子函数开始执行的地方,我们查看ret_from_fork在系统文件entry32.h中的定义可以发现,是执行了如下图所示的过程。
第二部分 实验部分
1、更新menu,删除test_fork.c和test.c文件,重新执行make rootfs总结:
子进程是从ret_ from_ fork开始执行的。子进程在进入sys_ call之前与父进程的堆栈状态相同,ret_ from_ fork中跳转到了syscall_ exit,继续执行上周我们分析过的部分,注意:当子进程获得CPU控制权的时候,它的ret_ from_ fork可以把后面堆栈从iret返回到用户态,这里的用户态是子进程的用户态宋宸宁+ 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
相关文章推荐
- ARM Linux 3.x的设备树(Device Tree)
- Linux内核实验作业五
- linux 配置nfs
- Linux群集LVS简介
- Linux kernel suspend resume学习:2.6.35与3.0.35比较【转】
- Galera 10.0.20 on CentOS 6.6
- Galera 10.0.20 on CentOS 6.6
- 《Linux内核设计与实现》读书笔记四
- linux查看内核及CPU等信息
- mysql 和 Linux 的密码修改
- linux中共享库(动态链接库)的延迟载入
- Linux U盘分区格式化 fdisk命令
- linux--文件--/etc/passwd多了一个/etc/passwd-文件
- linux下的串口通信
- 不常用的linux命令
- 报错A Database Error Occurred,linux系统被cc攻击
- # linux读书笔记(3章)
- Linux 防火墙 iptables基本操作
- linux lsof 用法简介
- Linux 性能测试工具