我了解系统调用如何在 C 和 Linux 中工作。我想知道每种编程语言是否都有自己独立的系统库来与内核通信。
如果是的话,每种编程语言都应该有自己的系统库来与内核一起工作吗?
如果否,那么另一种编程语言的系统调用如何在 linux 中工作?
我了解系统调用如何在 C 和 Linux 中工作。我想知道每种编程语言是否都有自己独立的系统库来与内核通信。
如果是的话,每种编程语言都应该有自己的系统库来与内核一起工作吗?
如果否,那么另一种编程语言的系统调用如何在 linux 中工作?
在 AMD64 Linux 上,系统调用是通过加载适当的寄存器并执行syscall
函数来完成的。在其他架构上,这当然是不同的。
C 以外的语言必须要么对进行系统调用的 C 函数进行外部调用(这通常更容易,因此也很常见),或者像 C 一样使用适当的处理器指令进行系统调用。
系统调用是一种从用户空间执行内核驻留函数的机制。
大局观是系统调用被包装在用户空间函数调用中,它接受来自用户的某些参数。这些参数与指示要执行哪个内核驻留函数的代码一起打包到一个结构中。然后代码执行一条 CPU 指令,使其特权级别上升到内核的特权级别,同时执行现在位于内核内部的代码路径。这称为进入内核。内核中的这段代码可以访问为系统调用组装的数据结构。它定位目标代码,从结构中为代码设置参数,然后进行调用。它收集返回码并安排它通过反向遍历路径返回到用户空间。
在此过程中还会发生其他事情,例如地址空间切换等,但这几乎是概念上发生的事情。
由于 C 几乎是 21 世纪的操作系统通用语言(从某种意义上说,大多数主流操作系统主要是用 C 编写的),因此许多编程语言实现都提供了调用 C 代码的方法。例如,Java 有 JNI,Python 和 Ruby 的参考实现(CPython 和 CRuby)都提供了创建 C 扩展模块等的能力。
大多数主流操作系统(包括 Linux)通常会公开一个或多个低级 C API,用于直接与设备交互、生成进程等。高级语言可以包装这些系统调用并使其在语言级别上可用程序员。
在英特尔架构中,任何对内核模式功能的调用都涉及带有一些参数(系统调用号和 linux 中的其他参数)的中断。如果任何编程语言想要利用它,它必须提供一个可以编译成正确程序集的构造(例如 int 80)。
C 和 C++ 提供了这一点。也可以使其他语言编译成本机代码来提供此功能。通常通过一些 RPC/COM 调用来调用 C/C++ 功能更容易。
大多数语言都有一些方法来调用通常称为Foreign Function Interface
. 我列出了一些我遇到的:
Java - JNI
Python, Ruby, Perl, TCL - have extensions for directly calling native C code. Python also provides `ctypes`
Microsoft's CLR - P/Invoke a mechanism to invoke native platform code
首先,系统调用使用汇编来调用内核——CPU 可以理解的语言。C被编译成汇编。x86 上的系统调用是使用 int 0x80 或 sysenter 完成的——两者都是由 CPU 执行的汇编指令。内核本身也是编译代码。您有两种类型的语言被编译和解释。编译后的语言被编译成汇编——它们可以在语言本身中有一层自己的代码,一种胶水,用系统调用实现调用 ac 库,或者它们可以有自己的编译成汇编的系统调用实现。解释语言是用随机语言编写的编译代码解释器,但编译为在 CPU 上运行的东西 - 它们具有相同的两个选项,但在解释器中 - 不是在字节码中,不是在脚本代码中。