do_execve() 和 Linux 中的 execve() 有什么区别?

What is the difference between do_execve() and execve() in Linux?

在下面link我有如下代码:

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

上面写着:

Here we can see that kernel_init -> run_init_process -> do_execve, which is the same with a regular execve syscall, the argument is init binary.

我正在尝试了解 do_execve()execve() 之间的区别。为什么不直接使用 execve()

用户space 使用syscalls 与内核space 通信。 "spaces" - userspace 和 kernelspace - 可以认为是单独的程序,它们使用寄存器和中断相互通信。

execve() 是围绕系统调用的 standard POSIX function exposed by the operating system to C programs. It should be implemented by your standard library implementation, most probably you use glibc. On Linux most POSIX functions match the names of syscalls, so glibc just implements a thin wrapper

当从用户space 程序调用系统调用时,参数保存在寄存器中并触发中断。这会停止执行 userspace 程序并在内核 space.

中继续执行

内核从用户space 寄存器中获取参数并执行一个应该处理系统调用的函数。大多数处理系统调用的函数在内核中只是命名为 do_<syscall>。函数 do_execve() 只是内核用来处理来自用户 space.

execve() 系统调用的函数

Why not to just use execve?

为什么已经在内核中了还要调用系统调用space?只需调用将处理系统调用的函数即可。