12

在内核 3.8.x 及更高版本中,run_init_process 的定义发生了变化。

以下是内核 3.8 中 run_init_proces 的新定义。

 static int run_init_process(const char *init_filename) {
         argv_init[0] = init_filename;
        return do_execve(init_filename,
                (const char __user *const __user *)argv_init,
                 (const char __user *const __user *)envp_init); }

与内核 3.7.x 和旧版本中的定义相比。

static int run_init_process(const char *init_filename) {
         argv_init[0] = init_filename;
         return kernel_execve(init_filename, argv_init, envp_init); }

kernel_execve中最关键的部分是它会调用 ret_from_kernel_execve,然后它会切换到用户模式。

在新定义中,kernel_execve消失了。我的问题是第一个用户进程如何切换到用户模式。

4

1 回答 1

1

成功do_execv()设置current运行新程序的进程(例如 via load_elf_binary()),然后返回 0 到run_init_process(),它返回 0 到kernel_init(),它也返回 0,并被调用为:

    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

这就是来自https://lwn.net/Articles/520227/的规则的用武之地:我们fn()在 an 之后返回 0 execve,因此“线程将进入由该 execve 创建的用户空间上下文”。

于 2014-01-19T05:53:57.027 回答