系统调用是从用户态与 Linux 内核交互的唯一方法吗?

系统调用是从用户态与 Linux 内核交互的唯一方法吗?

还有其他接口吗,例如 /proc 文件系统?

答案1

Linux 内核系统调用 API 是主要 API(尽管隐藏在 libc 下,并且很少被程序员直接使用),并且大多数标准 IPC 机制都严重偏向于一切都是文件方法,这在这里消除了它们,因为它们最终需要读/写(以及更多)调用。

然而,在大多数平台上(如果您排除所有系统调用来到达那里)有一种方法:VDSO。这是一种机制,内核将一个(或多个)稍微神奇的页面映射到每个进程(通常以 ELF .so 的形式)。您可以将其视为linux-vdso.so或与ldd或类似/proc/PID/maps。这是内核和用户进程之间有效的内存映射 IPC(尽管在当前实现中是单向的)。

它通常用于加速系统调用,最初是实现的(linux-gate.so)来解决 x86 性能问题,但它也可能包含内核数据和访问函数。像这样的调用可以使用这些getcpu()gettimeofday()不是进行实际的系统调用和内核上下文切换。这些优化调用的可用性由 glibc 启动代码检测并启用(取决于平台可用性)。当前的实现包含共享内核变量的(只读)页面,称为“VVAR”页面,可以直接读取。

您可以通过检查命令的输出来检查这一点,strace -e trace=clock_gettime date看看您的date命令是否进行任何clock_gettime()系统调用,而使用工作的 VDSO 则不会(时间将由 VDSO 页面中的函数从 VVARS 页面读取,请参阅arch/x86/vdso/vclock_gettime.c)。

这里有一个有用的技术摘要:http://blog.tinola.com/?e=5更详细的教程:http://www.linuxjournal.com/content/creating-vdso-colonels-other-chicken,以及手册页:http://man7.org/linux/man-pages/man7/vdso.7.html

答案2

不。

简单的计数器示例,这将与内核交互:

int main() {
    volatile char *silly = 0;
    *silly = 'a';
}

这将调用内核的页面错误处理程序,最终导致您的进程得到一个SIGSEGV(假设编译器不会“优化”该代码以执行明显的操作之外的操作,因为这是 C 标准未定义的行为,请确保编译和-O0

相关内容