【问题标题】:Linux: do syscalls change?Linux:系统调用会改变吗?
【发布时间】:2014-05-08 01:40:13
【问题描述】:

系统调用是内核面向用户空间的接口。用户进程通常不会直接调用它们,而是使用 libc 来执行此操作。 libc 要么只是为系统调用提供一个瘦包装器,要么像fork()exec() 那样做更多的工作

所以我的问题是 - 内核的系统调用接口是否会以非向后兼容的方式在内核版本之间发生变化?还是系统调用一旦建立就永远不会改变?

【问题讨论】:

  • 请允许我引用 open(2) 手册页:“符合”。
  • 你到底为什么要问???
  • @BasileStarynkevitch 我想用像 musl 这样的静态 libc 编译我的应用程序,并确保它永远不会中断 :)
  • “从不”在 IT 中没有任何意义。但是您的应用程序可能在十几年(或稍短一些)内都不会崩溃。如果这还不够,那就让它成为免费软件(希望有人能在 2030 年或 2040 年将源代码调整为相关标准)!
  • 对于这个问题的任何回答,在 Linux 的上下文中,都必须包含内核开发人员的座右铭:“永不破坏用户空间”。这是一个重要的政策,Linus 曾多次谴责甚至是内核维护者。更多详情,请阅读this post

标签: linux kernel system-calls


【解决方案1】:

从应用程序代码的角度来看,syscall 是一个基本的原子操作(它是一个“虚拟机指令”)。另见syscalls(2)

ABI 指定了它是如何发生的。对于 x86-64,您可以找到它here。另见x86 calling conventions

对于某些系统调用,最近的内核提供了vdso(7) 以使其更快。

Linux 内核努力保持二进制级别的兼容性。有传言说,一个 15 岁(静态链接)ELF 可执行文件应该在最新的内核上运行不变。

但是,实际上,您不会直接在代码中执行系统调用(因为您需要在汇编中执行此操作,请参阅Linux assembly howto)。您经常为此使用一些libc(例如GNU libcMUSL libc)。出于几个很好的原因,您通常将您的程序动态链接到libc.so。然后,您可能会遇到 - 从长远来看 - 一些不兼容问题(一些链接到旧的 libc 的二进制程序可能无法与更新或更旧的程序一起运行)。

【讨论】:

    【解决方案2】:

    由于以下原因,预计不会发生大的变化:

    1. 虽然它们主要通过 libc 调用,但 libc 可以更改 - 它会在内核和 libc 版本之间产生兼容性问题,需要避免。
    2. 系统调用完全按照 libc 调用进行标准化。

    fork()exec() 的 libc 版本非常小,它们与系统调用完全相同。也许您正在考虑system(),它实际上是 fork-s,使用 exec 调用 shell 并等待其终止。

    还有一些重要性低得多的系统调用,它们并不是 Linus 和核心团队真正喜欢的,例如以 _reiser4... 开头的系统调用,它们有更大的机会未来的变化。

    但标准系统调用,例如sys_opensys_close 等,在不久的将来不会改变。


    还有一件事是可以改变的,不是系统调用,而是方法如何被调用。在古人中,linux/i386 通过int 0x80 使用它,其中syscal 的数量必须放入eax。从那时起,也出现了更好/更快的解决方案,例如,有一个特定于 CPU 的SYSENTER asm-opcode,它也可以使用。它们的可用性是特定于 cpu 的,因此这是第一次,当内核需要提供 用户空间代码时,如何调用它的系统调用。如果您键入cat /proc/$$/maps,您将在末尾看到[vdso][vsyscall] 内存区域,这是。较旧的内核(可能在 2.4 之前?)没有它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2016-03-02
      相关资源
      最近更新 更多