2022-2023-1 20222821《Linux内核原理与分析》第七周作业

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

实验要求

  • 阅读理解 task_struct 数据结构 linux/sched.h at v3.18-rc6 · torvalds/linux · GitHub
  • 分析 fork 函数对应的内核处理过程 sys_clone,理解创建一个新进程如何创建和修改 task_struct 数据结构;
  • 使用 gdb 跟踪分析一个 fork 系统调用内核处理函数 sys_clone ,验证您对 Linux 系统创建一个新进程的理解,推荐在实验楼 Linux 虚拟机环境下完成实验。 特别关注新进程是从哪里开始执行的?为什么从那里能顺利执行下去?即执行起点与内核堆栈如何保证一致。
  • 根据本周所学知识分析 fork 函数对应的系统调用处理过程,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux 内核分析》MOOC 课程 网易云课堂 - 悄悄变强大”,博客内容的具体要求如下:
    • 题目自拟,内容围绕对 Linux 系统如何创建一个新进程进行;
    • 可以结合实验截图、绘制堆栈状态执行流程图等;
    • 博客内容中需要仔细分析新进程的执行起点及对应的堆栈状态等。
    • 总结部分需要阐明自己对“Linux 系统创建一个新进程”的理解

请提交博客文章 URL 到网易云课堂 MOOC 平台,编辑成一个链接可以直接点击打开。

实验过程

在MenuOS中增加命令fork

cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu 
mv test_fork.c test.c
make rootfs 
  • 首先清空原来的menu文件夹,克隆一个新的menu

  • 然后将test_fork.c文件改为test.c用以测试,再make一下,保证更新过

  • 正常运行,输入help命令,可以使用fork

  • 尝试调用一下fork

跟踪分析进程创建过程

# shell1中启动内核
cd ~/LinuxKernel
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s

# shell2中使用gdb调试
cd ~/LinuxKernel
gdb
file linux-3.18.6/vmlinux
target remote:1234
  • 接下来把刚才的全关掉,再打开一个新的命令行,输入-S -s让MenuOs停下方便调试

  • 再开一个终端,进入gdb,执行例行操作,然后设置六个断点

b sys_clone
b do_fork
b dup_task_struct
b copy_process
b copy_thread
b ret_from_fork

  • 然后用c一个运行调试

do_fork() 函数
在 Linux 内核中,供用户创建进程的系统调用fork()函数的响应函数是 sys_fork()、sys_clone()、sys_vfork()。这三个函数都是通过调用内核函数 do_fork() 来实现的。根据调用时所使用的 clone_flags 参数不同,do_fork() 函数完成的工作也各异。
1、建立进程控制结构并赋初值,使其成为进程映像。
2、必须为新进程的执行设置跟踪进程执行情况的相关内核数据结构。包括 任务数组、自由时间列表 tarray_freelist 以及 pidhash[] 数组。
3、启动调度程序,使子进程获得运行的机会
 

        创建一个进程是复制当前进程的信息,就是fork一个进程,这样就创建了一个新进程。因为父进程和子进程的绝大部分信息是完全一样的,但是有些信息是不能一样的,比如pid的值和内核堆栈。还有将新进程链接到各种链表中,要保存进程执行到哪个位置,有一个thread数据结构记录ip和sp 等信息也不能一样,否则会发生问题。可以想象,父进程创建一个子进程,应该会有个地方复制了父进程的进程描述符task_ struct 结构体变量,并有很多地方来修改复制出来的进程描述符task_ struct 结构体变量。因为父子进程各自都有很多自己独立的个性,子进程应该有很多地方修改内核堆栈里的信息,因为内核堆栈里的很多数据是从父进程复制来的,而fork系统调用在父子进程中分别返回到用户态,父子进程的内核堆栈中可能某些信息也不完全一样。还有thread, 根据子进程复制的父进程的内核堆栈的状况,肯定要设定好EIP和ESP寄存器,即设定好子进程开始执行的位置。需要特别说明的是,fork 一个子进程的过程中,复制父进程的资源时采用了Copy On wite (写时复制)技术,不需要修改进程资源,父子进程是共享内存存储空间的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值