我正在摆弄系统调用。我添加了两个新的,并使用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内核文档所说的相反:
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的标题应为:
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_*
宏公开给标准位置的用户空间?
由于
答案 0 :(得分:2)
内核构建过程分配的实际系统调用号是内核构建过程的一部分 ...所以你不能获得实际的最终数字,但仅限于已经构建的核心。构建内核,您将在构建的头文件中看到实际的分配。我担心你试图在一个干净的内核源代码中搜索它们,这就是你找不到合适的包含文件的原因。
另一方面,隐藏实际的系统调用号是很常见的,它由一些包含上面提到的内核头的包装程序完成,并使用#define
d符号来表示要进行的调用号码__SYSCAL(...)
实际通话。这通常甚至是必要的,因为每个系统调用通常具有不同的接口。您使用的所有正常系统调用都在stdlib中包含了它们的包装器,但新的系统调用将不包括在内。这里有两种方法:修补标准C库以包含(并在/usr/include
) OR 的某处写入函数原型的标准头文件,以包含包装文件{{1}您将使用新系统调用的所有程序中(此名称在您方便的时候)。
答案 1 :(得分:1)
好吧,我有一个部分答案。部分因为它是Debian特有的。
如果在内核源中使用make deb-pkg
目标,则会在父目录中创建.deb
个包。如果您随后安装了这些,那么您的标头就会安装到系统中。
为上述内核执行此操作后:
$ grep krun /usr/include
/usr/include/asm/unistd_64.h:#define __NR_krun_read_msrs 317
/usr/include/asm/unistd_64.h:#define __NR_krun_reset_msrs 318