《Linux内核分析》 第六周
《Linux内核分析》 第6周
一、进程的描述
1.进程控制块PCB
2.linux下的进程转化图
TASK_RUNNING可以是就绪态或者执行态,具体取决于系统调用
TASK_ZOMBIE僵尸进程(终止的进程)
3.进程描述符task_struct
- task_struct是一个数据结构,数据结构庞大;
- pid:进程标识值,一个int型数值
- 进程链表struct list_head tasks,数据结构如下:
它是一个双向链表,用来把当前所有进程用链表连起来
- 进程描述符中有几个域表示父子关系
程序创建的进程具有父子关系在编程时经常需要用到这样的父子关系。进程描述符中有几个域用来表示这样的关系。
每个进程都有一个父进程,每一个父进程都有0个或多个子进程
- struct thread_struct thread
与CPU相关
- struct *file表示打开的文件链表
- Linux为每个进程分配一个8k大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈
二、进程的创建
1.复习:“道生一,一生二”
- start_kernel创建了cpu_idle,即0号进程
- 0号进程又创建了两个线程kernel_init和kthreadd
- kernel_init即1号进程,这个进程最终启动了用户态
2.系统调用回顾
- 系统调用
用户态int 0x80指令实现软中断,过程详细如图:
- fork与系统调用相关,如图:
3.创建新进程的过程理解
- 创建一个新进程的框架
dup——thread复制父进程的pcb
copy_process修改复制的pcb以适应子进程的特点,也就是子进程的初始化
分配一个新的内核堆栈(用于存放子进程数据)
- 内核堆栈的一部分也要从父进程中拷贝
- 
- 
- 根据拷贝的内核堆栈情况设置eip,esp寄存器的值
- 一个新进程(子进程)从哪一行代码开始执行?
- 与之前写过的my_kernel相比较,kernel中可以指定新进程开始的位置(通过eip)。fork中也有相似的机制。
- 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; //调度到子进程时的第一条指令地址,也就是说返回的就是子进程的空间了
4.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.}
三、实验 使用gdb跟踪创建新进程的过程
1.在实验楼环境下的操作步骤
更新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)也就是内核堆栈特定的地址找到并初始化
四、总结
本周的课堂主要讲述的是进程的前半部分——关于基本的描述,以及新进程生命周期的开始(进程创建)。
关于进程描述,可以看到的是task_struct是进程描述的关键;其中含有一个进程从创建到终结的全部信息。关于进程创建,这里以fork函数为例进行了讲解;因为调用了fork函数之后就会创建新进程,创建的过程从代码和gdb调试两个方向进行了分析。
《Linux内核分析》 第六周的更多相关文章
- Linux内核及分析 第六周 分析Linux内核创建一个新进程的过程
实验过程 1.github上克隆相应的mengning/menu.git 2.测试menuOS,测试fork直接执行结果 3.配置调试系统,进入gdb调试,利用file linux-3.18.6/vm ...
- 2019-2020-1 20199303 《Linux内核原理分析》 第一周作业
2019-2020-1 20199303 <Linux内核原理分析> 第一周作业 1. 环境准备 在众多的Linux发行版中,Ubuntu,小红帽还有类Unix系统的BSD系统,我选择了目 ...
- Linux内核及分析 第八周 进程的切换和系统的一般执行过程
学习笔记: 一.进程调度与进程调度的时机分析 1.不同类型的进程有不同需求的调度需求: 第一种分类: —I/O-bound:频繁的进行I/O,通常会花费很多时间等待I/O操作的完成 —CPU-boun ...
- Linux内核及分析 第七周 可执行程序的装载
实验步骤 1. 更新menu,用test.c覆盖test_exec.c 2. 把init 和 hello 放到了rootfs.img目录下,执行exec命令的时候自动加载了hello程序 3. 执行e ...
- Linux内核及分析 第五周 扒开系统调用的三层皮(下)
实验内容: 1.执行rm menu -rf命令,强制删除原有的menu 2.使用git命令 git clone https://github.com/mengning/menu.git 克隆新的men ...
- Linux内核及分析 第三周 Linux内核的启动过程
实验过程: 打开shell终端,执行以下命令: cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage-initrd rootf ...
- Linux内核读书笔记第六周
主要内容: 什么是调度 调度实现原理 Linux上调度实现的方法 调度相关的系统调用 什么是调度 现在的操作系统都是多任务的,为了能让更多的任务能同时在系统上更好的运行,需要一个管理程序来管理计算机上 ...
- LINUX内核分析第六周学习总结——进程的描述与创建
LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...
- linux内核分析第六周学习笔记
LINUX内核分析第六周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...
- LINUX内核分析第六周学习总结——进程的描述和进程的创建
LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
随机推荐
- FZU Monthly-201903 获奖名单
FZU Monthly-201903 获奖名单 冠军: 黄海东 S031702647 一等奖: 林闽沪 S131700309 陈华能 S221701416 二等奖: 鲍子涵 S031702646 吴少 ...
- 实例化list
List<String> lists = new ArrayList<String>();list.add("123");
- 加载驱动三种execute
executeQuery executeUpdate executeQueryBatch
- k8s mongodb 集群配置
service.yaml apiVersion: v1 kind: Service metadata: name: mongo labels: name: mongo spec: ports: - p ...
- oracle 创建create user 及授权grant 查看登陆的用户
show user; select sys_context('userenv','session_user') from dual; select user from dual; 查看所有登录的用户必 ...
- mysql中唯一约束用法
以前比较naive,有次同事一定要在表里建唯一约束的时候,我就很纳闷为啥非要在db层面做限制,在自己的业务代码里做啊,就是说入库的时候先查一遍有没有,没有记录的情况再准许入库. 后来发现如果只是自己处 ...
- 微服务 Rpc和Rest协议
原文:https://blog.csdn.net/king866/article/details/54174665 接口调用通常包含两个部分,序列化和通信协议.常见的序列化协议包括json.xml.h ...
- Android应用安全之WEB接口安全
Android应用安全不仅包括客户端的安全,也包括web接口的安全.移动App中的Web接口安全主要分为以下几块: 1.SQL注入漏洞 这是一个不能再常见的漏洞类型了,由于App的特性,开发人员认为使 ...
- 20155232《网络对抗》 Exp1 PC平台逆向破解(5)M
20155232<网络对抗> Exp1 PC平台逆向破解(5)M 实验内容 (1).掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(1分) (2)掌握反汇编与十六进制编程 ...
- 20155302 Exp2 后门原理与实践
20155302<网络对抗>后门原理与实践 实验要求 1.使用netcat获取主机操作Shell,cron启动 (0.5分) 2.使用socat获取主机操作Shell, 任务计划启动 (0 ...