XV6 中的 Fork(),子进程是在内核态还是在用户态执行?

Fork() in XV6, does the process child execute in kernel or user mode?

在XV6中,当一个fork()被调用时,子进程是在内核态还是用户态执行?

这是 XV6 中的分支代码:

// Create a new process copying p as the parent.
// Sets up stack to return as if from system call.
// Caller must set state of returned proc to RUNNABLE.
int fork(void){
  int i, pid;
  struct proc *np;
  struct proc *curproc = myproc();

  // Allocate process.
  if((np = allocproc()) == 0){
    return -1;
  }

  // Copy process state from proc.
  if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){
    kfree(np->kstack);
    np->kstack = 0;
    np->state = UNUSED;
    return -1;
  }
  np->sz = curproc->sz;
  np->parent = curproc;
  *np->tf = *curproc->tf;

  // Clear %eax so that fork returns 0 in the child.
  np->tf->eax = 0;

  for(i = 0; i < NOFILE; i++)
    if(curproc->ofile[i])
      np->ofile[i] = filedup(curproc->ofile[i]);
  np->cwd = idup(curproc->cwd);

  safestrcpy(np->name, curproc->name, sizeof(curproc->name));

  pid = np->pid;

  acquire(&ptable.lock);

  np->state = RUNNABLE;

  release(&ptable.lock);

  return pid;
}

我做了一些研究,但即使从代码中我也无法理解它是如何工作的。了解它在 UNIX 中的工作原理也会有所帮助

除了eax寄存器的值和父进程信息外,它几乎是父进程的精确副本,所以它会执行父进程所在的任何上下文。

这里的fork()函数通过调用allocproc()创建了一个新的进程结构,并用原进程的值填充它并映射相同的页表。

最后,它将进程状态设置为 RUNNABLE,这允许调度程序 运行 新进程与父进程一起。

这意味着实际的 运行ning 是由调度程序执行的,而不是此处的 fork 代码。

Sedat 写的完全正确。分叉进程,或者子进程将 运行 在与其父进程相同的上下文中,即内核或用户。 除此之外,我觉得让你感到困惑的是 alloproc() 所做的调用,如 kalloc() 和属性,如 kstack。这些处理在系统中设置有关页表和内存部分的新进程。