为什么某些 Linux 系统支持 open() 系统调用,而其他系统不支持?

Ols*_*ist 1 linux-kernel arm64 archlinux-arm

我正在内联系统调用。是的,我知道这是有问题的,但我有充分的理由。我已经大量地追踪了我的错误,我只是问为什么__NR_open在这个 arm64 Arch Linux 系统上消失了?

5.0.1-1-ARCH #1 SMP Sun Mar 10 15:08:34 MDT 2019 aarch64 GNU/Linux

同样,我的代码是内联系统调用。这种内联方法适用于另一个X86_64系统,实际上内联mmap() 也适用于该系统。但是,在此 arm64 Arch Linux 上内联open()失败并显示EFAULT

追踪我的错误,首先,在这个构建环境中甚至没有定义__NR_open。其次,常规open()调用open64()执行一条svc指令,其中 x8 设置为 #56, __NR_openat。第三,__NR_open通常定义为 5 并且该数字已重新用于__NR_setxattr。这解释了EFAULT

基本上,open()在这个系统的用户库中被转换成openat()并且__NR_open系统调用已经完全消失,由一个新的系统调用接管。我不明白的是__NR_open是在arm64规范源中定义的,但不是在这个 Arch Linux arm64 系统上定义的。

我的错误修复很简单:内联openat()代替。但我的问题是为什么删除了这个,为什么这不被认为是从 Linux POV 中破坏的?我在想 Linus 说我们不破坏用户空间!不是从 POSIX POV 考虑这个问题。事实上,Linux 编程接口至少没有明确地涵盖这个删除。

caf*_*caf 7

您正在查看的文件是arch/arm64/include/asm/unistd32.harm32 兼容模式的系统调用定义。

原生 aarch64 的系统调用定义来自通用系统调用表include/uapi/asm-generic/unistd.h,你可以看到它没有定义__NR_open。系统调用没有被删除——它在 aarch64 上从未存在过。

__NR_open未在通用表中定义的原因是openat(2)系统调用是后来引入的,并且是功能的严格超集_NR_open,因此架构端口(在openat(2)引入之后创建)提供该系统调用是没有意义的- 它是多余的. POSIXopen()函数由用户空间 C 库提供,调用openat(2)系统调用。

之前存在的旧架构端口openat(2)- 如 x86 和 arm32 - 必须继续包含open(2),因为对于调用open(2)系统调用的那些架构来说,旧程序/库二进制文件肯定存在。这种担忧不适用于新的架构移植——“破坏用户空间”的保证是,如果它昨天工作,今天也能工作,但它并没有说如果它在现有架构上工作,它可以重新编译并在一些新的架构上工作建筑学。