《Linux内核分析》 第六节 分析Linux内核创建一个新进程的过程

范闻泽 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、实验过程

1.删除原来的menu,并clone新的menu,用test_fork.c覆盖test.c

2. make rootfs之后新的内核启动,测试fork功能

3.使用-s -S冷冻内核,准备调试

4.设置断点

5.根据断点,进行跟踪,得到结果

1、以下是执行指令

cd LinuxKernel

  • rm menu -rf
  • git clone https://github.com/mengning/menu.git
  • cd menu
  • mv test_fork.c test.c
  • make rootfs

2. gdb上述的fork命令

关闭QEMU窗口,中命令行中输入:

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

再次启动MenuOS,并暂停等待gdb调试。

依次输入以下命令,启动调试:

gdb

file linux-3.18.6/vmlinux

target remote:1234

然后再设置以下断点:

b sys_clone

b do_fork

b dup_task_struct

b copy_process

b copy_thread

b ret_from_fork

继续执行之后,停在了do_fork的位置。然后n单步执行,依次进入copy_process、dup_task_struct。按s进入该函数,可以看到dst =src(也就是复制父进程的struct)

二、实验总结

1、fork系统调用

fork调用创建一个新的进程。新的进程或者说子进程是调用进程的或者说父进程的副本。

1.如果fork执行成功,就向父进程返回子进程的PID,并向子进程返回0。这就一起这即使你只调用fork一次,他也会返回两次。

2.Fork创建的新进程是和父进程(除了PID和PPID)一样的副本,包括真实和有效的UID和GID、进程组合会话ID、环境、资源限制、打开的文件以及共享内存段。

父进程和子进程之间有一点区别。子进程没有继承父进程的超市设置(使用alarm调用)父进程创建的文件锁,或者未决信号。要理解的关键概念是fork创建的新进程是父进程的一个准确副本。

3.一般来说,fork之后父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的调度算法。

本周视频学习内容如下:

一、操作系统内核里有三大功能:进程管理、内存管理、文件系统

二、进程的描述:说到进程的描述,首先要分析一下进程描述符:task_struct

进程控制块PCB——task_struct:

为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。

struct task_struct数据结构很庞大

进程的标示pid

所有进程链表struct list_head tasks;

内核的双向循环链表的实现方法 - 一个更简略的双向循环链表

程序创建的进程具有父子关系,在编程时往往需要引用这样的父子关系。进程描述符中有几个域用来表示这样的关系

Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈

三、进程的创建

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

iret与int 0x80指令对应,一个是弹出寄存器值,一个是压入寄存器的值

如果将系统调用类比于fork();那么就相当于系统调用创建了一个子进程,然后子进程返回之后将在内核态运行,而返回到父进程后仍然在用户态运行

fork一个子进程的代码

#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)
{
/* 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");
}
}

创建新进程的框架

fork,vfork,clone都可以创建新进程,他们都是通过调用do_fork来实现的。

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

分配一个新的内核堆栈(用于存放子进程数据)

内核堆栈的一部分也要从父进程中拷贝

Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架: 复制一个PCB——taskstruct


1

err = arch_dup_task_struct(tsk, orig);

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


1

2

3

ti = alloc_thread_info_node(tsk, node);

tsk->stack = ti;

setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈

从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和taskstruct中thread记录的sp和ip的一致性问题,这是在哪里设定的

copythread in copy_process

时间: 2024-12-06 09:46:41

《Linux内核分析》 第六节 分析Linux内核创建一个新进程的过程的相关文章

第六周分析Linux内核创建一个新进程的过程

潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  unsigned int rt_priority;实时优先级  unsigned int policy;调度策略  struct files

实验六———分析Linux内核创建一个新进程的过程

分析Linux内核创建一个新进程的过程 攥写人:李鹏举  学号:20132201 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ) 本周要求: 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 分析fork函数对应的内核处理过

Linux内核分析-分析Linux内核创建一个新进程的过程

作者:江军 ID:fuchen1994 实验题目:分析Linux内核创建一个新进程的过程 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构: 使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证您对Linux系统创建一个

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

20135311傅冬菁 分析Linux内核创建一个新进程的过程 一.学习内容 进程控制块——PCB  task_struct数据结构 PCB task_struct中包含: 进程状态.进程打开的文件.进程优先级信息 操作系统管理的三个功能: 1.进程管理 2.内存管理 3.文件系统 Linux进程的状态: 进程状态分析: long state是进程的运行状态,-1是未执行,0是执行中,大于0则是暂停: *stack 是建立一个内核堆栈: flags 是定义了每个进程的标识符: list_head

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

进程的描述 操作系统的三大管理功能:进程管理.内存管理.文件系统 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 进程控制块PCB task_struct:进程状态.进程打开的文件.进程优先级信息 task_struct总体数据结构的抽象: tty:控制台 fs:文件系统 files:文件描述符 mm:内存管理 signal:信号描述 进程的状态: 注意:Linux下,中就绪状态和运行状态都是TASK_RUNNING 一.gdb跟踪分析一个fork系统调

实验六:分析Linux内核创建一个新进程的过程

20135108 李泽源 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构: 使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证您对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环境下完成实验. 特别

Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程

陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 登陆实验楼虚拟机http://www.shiyanlou.com/courses/195 打开shell终端,执行以下命令: cd LinuxKernel rm -rf menu git clone https://github.com/mengning/menu.git cd menu mv test_fork.c

Linux内核及分析 第六周 分析Linux内核创建一个新进程的过程

实验过程 1.github上克隆相应的mengning/menu.git 2.测试menuOS,测试fork直接执行结果 3.配置调试系统,进入gdb调试,利用file linux-3.18.6/vmlinux和target remote:1234来配置加载初始调试环境 4.在linux内核进程创建可能用到的点设置断点分别为sys_clone,do_fork,dup_task_struct,copy_thread,copy_process和ret_from_fork. 总结: 1.通过调用do_

linux内核分析第六周-分析Linux内核创建一个新进程的过程

Linux内核对进程管理是操作系统的重要任务之一. 此次实验就是了解内核创建一个新进程的大致过程. 为了简单,使用fork再用户态创建一个进程.代码如下: 下面是准备工作??? cd LinuxKernel rm -rf menu git clone https://github.com/mengning/menu.git cd menu mv test_fork.c test.c make rootfs 打开gdb进行远程调试? 设置断点 b sys_clone b do_fork b dup