Linux:系统调用改变了吗?
系统调用是内核面向用户空间的接口。 用户进程通常不会直接调用它们,而是使用libc来做到这一点。 libc或者只是在系统调用时提供一个简单的包装器,或者在fork()
和exec()
的情况下做更多的工作,
所以我的问题是 - 系统调用的内核接口是否以非向后兼容的方式在内核版本之间改变? 还是一旦系统调用建立,它永远不会改变?
系统调用从应用程序代码的角度来看是一个基本的原子操作(它是一个“虚拟机指令”)。 另请参阅syscalls(2)。
ABI指定了它究竟发生了什么。 对于x86-64,你可以在这里找到它。 另请参阅x86调用约定。
对于一些系统调用,最近的内核提供了vdso(7)以使它们更快。
Linux内核尽力在二进制级别保持兼容性。 据传15年前(静态链接)的ELF可执行文件应该在最新的内核上保持不变。
但是,在实践中,您不会直接在代码中执行系统调用(因为您需要在汇编中执行此操作,请参阅Linux汇编howto)。 你经常使用一些libc
(例如GNU libc或MUSL libc)。 由于几个很好的原因,您通常将程序动态链接到libc.so
那么,在很长的一段时间里,你可能会遇到一些不兼容问题(一些链接到旧libc
二进制程序可能无法运行更新或更旧的程序)。
由于以下原因,不会出现大的变化:
fork()
和exec()
的libc版本非常小,它们与系统调用完全一样。 也许你正在考虑system()
,实际上fork-s,用exec调用shell并等待其终止。
系统调用的重要性也低得多,它们并不是Linus和核心团队所喜欢的,例如以_reiser4开头的系统调用...,他们将来有更大的机会改变。
但是标准的系统调用,例如sys_open
, sys_close
等不会在最近的将来改变。
还有一件事情可以改变,它不是系统调用,而是如何调用的方法。 在古人中,linux / i386通过一个int 0x80
使用它,系统数必须放在eax
。 从那以后,它也出现了更好/更快的解决方案,例如有一个CPU特定的SYSENTER
asm-opcode,它也可以使用。 它们的可用性是特定于cpu的,因此它是第一次,当内核需要提供用户空间代码时,它的系统调用如何被调用。 如果你输入一个cat /proc/$$/maps
,你会在结尾看到一个[vdso]
或一个[vsyscall]
内存区域,这是。 较老的内核(也许在2.4之前)没有它。