fork 的第一件大事:复制结构

image.png

dup_task_struct 主要做了下面几件事情:

  • 调用 alloc_task_struct_node 分配一个 task_struct 结构;
  • 调用 alloc_thread_stack_node 来创建内核栈,这里面调用 __vmalloc_node_range 分配一个连续的 THREAD_SIZE 的内存空间,赋值给 task_struct 的 void *stack 成员变量;
  • 调用 arch_dup_task_struct(struct task_struct dst, struct task_struct src),将 task_struct 进行复制,其实就是调用 memcpy;
  • 调用 setup_thread_stack 设置 thread_info。

轮到权限相关了,copy_creds 主要做了下面几件事情:

  • 调用 prepare_creds,准备一个新的 struct cred *new。如何准备呢?其实还是从内存中分配一个新的 struct cred 结构,然后调用 memcpy 复制一份父进程的 cred;
  • 接着 p->cred = p->real_cred = get_cred(new),将新进程的“我能操作谁”和“谁能操作我”两个权限都指向新的 cred。

接下来,copy_process 开始设置调度相关的变量。

sched_fork

fork 的第二件大事:唤醒新进程

首先,我们需要将进程的状态设置为 TASK_RUNNING。

image.png