对do_fork的源码进行了分析,看了好多遍,昨晚又看了一遍,现在能够自己顺下来大致执行过程,比之前理解更深刻。
先解释一下ptr_err,这在下面会用到。因为在内核中,有些函数,比如kmalloc是返回指针的,kmalloc是分配内存的,如果分配不到,就返回null指针。有些函数错误时,我们在知道它错了的基础上还要获得错误码,在用户空间,提供了error变量,获得错误码,在内核中就相应的有ptr_err,很明显,也是用来获得错误码的。在do_fork中,copy_process错误时,错误码保存在pid中。
do_fork函数的主要作用就是复制原来的进程使其成为一个新的进程,它完成了整个进程创建中的大部分工作。
Fork、vfork和clone三个系统调用所对应的系统调用服务例程都调用了do_fork()。只是所传递的参数不同,导致父进程和子进程在共享资源的程度上不同。fork是全部复制父进程,传给子进程,所以fork不带参数。而clone复制部分父进程资源,也就是说复制是有选择的。vfork准确来说,它创建的是线程而不是进程。并且vfork创建的子进程先于父进程执行。只有子进程执行结束或退出,父进程才被唤醒。
接下来分析do_fork()。
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
首先解释以上几个参数,
clone_flags: 通过clone标志可以有选择的对父进程的资源进行复制;fork,vfork和clone就是因为flag标志不同才加以区分的。
statck_start:子进程用户态堆栈的地址;
regs:指向pt_regs结构体的指针。当系统发生系统