一如既往,我感谢您在我的旅程中花费的时间和精力来帮助我:)
因此,作为一个 Nerd ,我已经开始深入了解操作系统的工作原理。我有一个关于内核和标准库的问题,例如 Linux 的 glibc,它充当函数包装器。
为什么操作系统需要一个用 C 语言编写的标准库?或者以另一种方式问你能用 C 以外的另一种语言为 Linux 内核编写一个标准库吗?
我假设 STD 库的语言可能取决于为内核选择的语言。因此,在我们用 C 编写的 Linux 示例中,包装器 STD 库也需要是 C 语言。
我理解为什么内核通常需要 STD 库,所以这并不是我真正想要在 JIC 上得到的东西,我不清楚。
再次感谢!
最佳答案
让我们深入了解有关操作系统 - 用户空间通信的更多细节。你知道进展如何吗?基本上每个平台都使用自己的方法来进行所谓的系统调用 -> 从用户空间到内核空间的控制传输。
例如x86使用int
指令,x86-64使用syscall
指令,arm使用swi
等等。此外,每个平台对于在调用系统调用指令之前应如何建立参数和系统调用号都有自己的理解。让我们关注 x86-64:
例如,对于调用 execve(系统调用号 0x3b),此代码就足够了。你可以尝试一下。
section .text
global _start
_start:
mov rax, 0x3b
mov rdi, cmd
mov rsi, 0
mov rdx, 0
syscall
section .data
cmd: db '/bin/sh'
.end:
现在让我们了解什么是 execve
libc 函数。基本上,如果您深入研究 libc 代码,您会发现它是导致 syscall 函数的包装器(请参阅 syscall.S 了解 libc 中的架构)。这个 syscall.S 看起来与上面的示例非常相似:
.text
ENTRY (syscall)
movq %rdi, %rax /* Syscall number -> rax. */
movq %rsi, %rdi /* shift arg1 - arg5. */
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp),%r9 /* arg6 is on the stack. */
syscall /* Do the system call. */
基本上,正如 user4098326 和 rcgldr 所提到的 - uspace 和内核之间的互连是汇编代码,而其之上的所有内容 - 只是包装器。据我了解,所有这些包装器都可以不仅用 C 编写。
关于c - 操作系统架构: Kernel and Standard Library interoperability,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29563735/