首页 > 解决方案 > Linux 中的 do_execve() 和 execve() 有什么区别?

问题描述

在以下链接中,我有以下代码:

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);
}

它说:

在这里我们可以看到,kernel_init -> run_init_process -> do_execve与常规的 execve 系统调用相同,参数是 init binary。

我试图理解 和 之间的do_execve()区别execve()。为什么不直接使用execve()

标签: clinuxlinux-kernelexecve

解决方案


用户空间使用系统调用与内核空间通信。“空间”——用户空间和内核空间——都可以被认为是使用寄存器和中断相互通信的单独程序。

execve()是操作系统向 C 程序公开的标准 POSIX 函数。它应该由您的标准库实现来实现,很可能您使用glibc。在 Linux 上,大多数 POSIX 函数与系统调用的名称相匹配,因此 glibc 只是在系统调用周围实现了一个瘦包装器。

当从用户空间程序调用系统调用时,参数保存在寄存器中并触发中断。这将停止用户空间程序的执行,并在内核空间中继续执行。

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

为什么不只使用 execve?

当你已经在内核空间时为什么要调用系统调用?无论如何,只需调用将处理系统调用的函数。


推荐阅读