那前面呢我们可以看到
我们通过这个执行相应的
do_execve这个函数呢
能够创建出一个进程
那么创建了一个鸡
那么鸡怎么下蛋呢
那我们可以看
这个父进程是如何复制子进程的
这是我们这一次讲的
内容就是进程复制
鸡怎么生蛋
那么在原理课可以看到
这里面讲到了有一个父进程
通过一个fork就完成了
把这个所有代码段 数据段 堆栈等等
复制到另一个区域里面去
产生一个子进程
它们的PID不一样
这是原理课大致的讲的内容
我们可以看看
如果说对应到我们Lab5实验
这个原理上的内容
怎么来具体的实现
那这个函数呢叫do_fork
一个内核函数
它里面带了三个参数
memory相关一个参数跟
stack相关的有两个参数
那么这个参数呢
决定了就是说我们怎么去完成
内存空间管理的一个拷贝
这两块跟用户堆栈相关
跟我们这个它的trapframe相关
那也是一样
就是通过这两个信息
我们的子进程需要
用到父进程的相关信息
要复制一部分内容还要做一并修改
所以这是三个重要的参数
来完成了对这个do_fork一个调用
我们看它怎么具体一步步实现的
首先我们说父进程要创建子进程
子进程和父进程是两个不同的进程
所以说它有自己的进程控制块
那创建了这个进程控制块之后呢
我们子进程就有了自己的身份了
也有它一个壳
但光这个还不够
我们还需要进一步去初始化
很多其它新的一些必须需要具备的内容
比如说第一个是kernel stack
它在内核里面要能够执行
它需要自己的栈
这个kernel stack通过分配它相应的空间
通过alloc_ pages得到一些空间
然后通过这个proc->kstack
来得到它这个内核里面这个虚地址
从而可以把这个kernel stack给建立好
这是完成建立功能
还没有具体去执行
再接下来呢我们需要干什么呢
复制父进程的内存
当我们创建个新的kernel stack之后呢
我们的代码段 数据段希望能够
复制父进程的同样的内容
这我们说父进程创建子进程
需要完成重要一个功能
这里面用什么呢
copy_mm和copy_range
这两个来完成相应的功能
那么copy_mm呢
是为新进程创建一个新的VMA
这是新进程创建好的
第二个呢copy_range
是把实际的这个代码段和数据段
搬到新的子进程里面去
同时再设置好相应的这个
虚实映射关系就是把
这个页表里面内容重新设置
使得我们的子进程
具有自己的内存管理一个架构
mm_struct以及对应自己一个新的页表
内容是复制了一份
好 当我们把这个父进程的内存空间
拷贝到子进程里面去之后呢
再接下来我们需要
让这个子进程能够正确的执行
也意味着它要正确设置好trapframe和context
这个context在我们讲kernel thread的时候呢
给大家提到过trapframe之前也讲过
这trapframe为什么要设置新的值呢
可以看到
因为当我们这个父进程和子进程
都要做返回到用户态去执行的时候
它们的状态是不一样的
这里面可以看到它这里面干什么事情
第一个要拷贝父进程的trapframe
拷贝完之后还要做一定改动
它的eax esp eip和copy_thread
要做相应一些重新设置
来完成这个拷贝和更新的工作
大家可以去看一下
这里面怎么来完成的
假设做完这个之后
我们还需要把我们新创建好
这个子进程放到我们的
进程队列里面去
我们说有一个进程队列来管理了
所有在操作系统里面存在的进程
这里面有一个proc list
然后呢一旦挂到这个队列里面去之后呢
我们就可以用
我们的进程管理的这个子系统呢
来对这里面的进程做调度管理
当然调度我们在Lab6中
会做进一步的深入讲解
一旦能够把这部分事情做完之后
也意味着我们子进程
已经创建完毕且可以去执行了
可以去到running态
然后跳到我们内容空间去执行
好 那它们执行有什么区别呢
我们前面讲到 说
我们的父进程创建完子进程之后
它子进程的返回值和
父进程的返回值是不一样的
do_fork的返回
父进程返回是子进程的PID
而子进程返回是零
那在这里面怎么体现
其实在最后这一步
还会有一个把这个return做一个修改
如果是父进程的话它会returnbPID回去
所以说你可以看着父进程它的调用返回值
正好是那个子进程的PID
同时呢子进程他做的事不一样
子进程它把它那个返回值就eax
设成是零
寄存器设置值是零
那使得这个子进程的do_fork
系统调用执行完毕之后
它返回是零
和我们父进程do_fork返回值是不一样的
但是它们的控制点都是在
do_fork返回这一点去执行的
大家再回顾一下我们原理课讲的内容
执行完do_fork之后
我们父进程会得到一个子进程的PID
而我们子进程呢
会得到一个零继续执行
它们就已经成了
两条控制流去执行去了
那大家对这个执行过程
有深入理解之后呢
对照执行代码就可以
更好完成我们练习二的内容