hum*_*ace 38 linux system-calls
我知道系统调用接口是在低级别实现的,因此依赖于体系结构/平台,而不是“通用”代码。
然而,我无法清楚地看到为什么 Linux 32 位 x86 内核中的系统调用在类似架构 Linux 64 位 x86_64 中具有不保持相同的编号?这个决定背后的动机/原因是什么?
我的第一个猜测是后台原因是保持 32 位应用程序可在 x86_64 系统上运行,以便通过对系统调用号的合理偏移,系统将知道用户空间是 32 位还是 64 位分别。然而事实并非如此。至少在我看来,在 x86_64 中 read() 是系统调用号 0 不能与这种想法保持一致。
另一种猜测是更改系统调用号可能有安全/强化背景,我无法确认这一点。
由于不知道实现依赖于体系结构的代码部分的挑战,我仍然想知道如何更改系统调用号,当似乎没有必要时(因为即使是 16 位寄存器也会存储更多,而不是当前的 ~346 个数字来表示所有调用),将有助于实现任何事情,除了破坏兼容性(尽管通过库 libc 使用系统调用可以缓解它)。
Ran*_*832 36
至于具体编号背后的原因,它与任何其他架构都不匹配 [除了“x32”,它实际上只是 x86_64 架构的一部分]:在 linux 内核中 x86_64 支持的早期,在没有任何其他架构之前严重的向后兼容性限制,所有系统调用都重新编号以在缓存行使用级别对其进行优化。
我对内核开发知之甚少,无法了解这些选择的具体基础,但显然选择使用这些特定数字重新编号所有内容而不是简单地从现有架构复制列表并删除未使用的列表背后有一些逻辑。看起来顺序可能基于它们被调用的频率 - 例如读/写/打开/关闭在前面。Exit 和 fork 可能看起来是“基本的”,但它们每个进程只被调用一次。
可能还会发生一些事情,将通常一起使用的系统调用保留在同一缓存行中(这些值只是整数,但内核中有一个表,每个表都有函数指针,因此每组 8 个系统调用占用该表的 64 字节缓存行)
xhi*_*nne 16
请参阅问题“为什么 amd64 linux 中的系统调用号不同?”的答案。在堆栈溢出上。
总结一下:为了兼容性,系统调用列表是稳定的,只能增长。当 x86 64 架构出现时,ABI(参数传递,返回值)不同,因此内核开发人员借此机会带来了期待已久的变化。