【发布时间】:2017-12-30 09:21:25
【问题描述】:
我在摆弄系统调用。我添加了两个新的,并通过调用 syscall 验证了它们的工作原理。
我希望系统调用号位于标头中,以便用户空间不必明确知道系统调用号。
在arch/x86/syscalls/syscall_64.tbl 我有:
317 64 krun_read_msrs sys_krun_read_msrs
318 64 krun_reset_msrs sys_krun_reset_msrs
一些 grepping 表明 kbuild 已经为新的系统调用自动生成了宏:
$ ag __NR_krun *
arch/x86/include/generated/uapi/asm/unistd_64.h
321:#define __NR_krun_read_msrs 317
322:#define __NR_krun_reset_msrs 318
文件名表明我不需要手动添加条目,但这与 Linux Kernel 文档所说的相反:
Some architectures (e.g. x86) have their own architecture-specific syscall tables, but several other architectures share a generic syscall table. Add your new system call to the generic list by adding an entry to the list in include/uapi/asm-generic/unistd.h:
#define __NR_xyzzy 292
__SYSCALL(__NR_xyzzy, sys_xyzzy)
嗯,我的系统调用是特定于 x86_64 的,因为它们读取和写入仅在英特尔芯片中发现的 MSR。因此,在此之后,我开始挖掘是否可以为我的 amd64 系统找到特定于架构的标头。
您可能希望它位于arch/x86_64 之下,但其中根本没有包含。所以我假设 x86_64 继承自 x86。在这种情况下,特定于架构的标题应该是:
arch/x86/include/uapi/asm/unistd.h
如果你打开它,它只是一个基于 arch 调度的小包装:
# ifdef __i386__
# include <asm/unistd_32.h>
# elif defined(__ILP32__)
# include <asm/unistd_x32.h>
# else
# include <asm/unistd_64.h>
# endif
所以这大概是为了接听/usr/include/x86_64-linux-gnu/asm/unistd.h,但这还不包括我的新系统调用号码。
我希望 headers_install 目标安装新的标头(也许),但可惜它没有。
我很困惑。我应该手动将我的新系统调用添加到文件中吗?如果有,是哪个文件?如果没有,我如何将自动生成的__NR_* 宏暴露给标准位置的用户空间?
谢谢
【问题讨论】:
-
如果您在库中实现包装函数来调用系统调用,则不一定需要。毕竟,这是 C 库在 POSIXy 系统上所做的大部分工作。您可以让库头文件公开系统调用号(适用于当前架构)。要向所有 Linux 用户包含新的系统调用,您需要将补丁推送到 Linux 内核(通过 LKML)和 GNU C 库或特定发行版的上游,以便他们将更改添加到其系统头文件.
-
是的,这不太可行,因为系统调用不适合一般用途。
-
什么(不可行),将系统调用包装成函数? (如果你的意思是把它推到上游,我同意。)不过,你真的应该考虑将系统调用包装到函数中;即使只是作为头文件中的静态内联函数,也要根据拱门和字长(使用预处理器宏)选择正确的系统调用号。与修改后的内核(或内核修改)一起提供 extra 头文件比在标准头文件中包含额外项要容易得多。
-
拥有包装函数会很好,是的,但第一步确实是尝试导出
__NR_*和朋友。您建议的包装器功能是否不依赖于那些?我只需要某种方式知道系统调用号,它可能因架构或内核版本而异。 -
啊,现在我明白了。问题是,大多数 Linux 发行版不使用内核提供的用户空间头文件;相反,它们使用 C 库提供的头文件,以及安装的任何其他开发库。例如,Debian(以及 Debian 衍生产品,如 Ubuntu、Mint 等)将内核头文件保持在
/usr/src/linux-headers-$(uname -r)/(当前的头文件);当前运行的内核的系统调用号在/usr/src/linux-headers-$(uname -r)/uapi/asm-generic/unistd.h中。包装函数可以使用uname()C库函数来获取当前[...]
标签: c linux linux-kernel system-calls