哪个系统电话号码头文件正确?

时间:2018-11-02 16:34:48

标签: c linux-kernel unistd.h

我最近正在做一些内核编码,我发现了2个 unistd.h 文件。

第一个位置是 /usr/include/asm/unistd.h 。第二个来自内核的源代码: linux/include/uapi/asm-generic/unistd.h 。 源代码的版本与内核的版本相同,但是两个头文件 彼此不同。

/usr/include/asm/unistd.h (从我的PC):

#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4
#define __NR_fstat 5
#define __NR_lstat 6
#define __NR_poll 7
#define __NR_lseek 8
#define __NR_mmap 9

linux/include/uapi/asm-generic/unistd.h (来源):

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
#define __NR_io_destroy 1
__SYSCALL(__NR_io_destroy, sys_io_destroy)
#define __NR_io_submit 2
__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
#define __NR_io_cancel 3
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_io_getevents 4
__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)

/* fs/xattr.c */
#define __NR_setxattr 5
__SYSCALL(__NR_setxattr, sys_setxattr)
#define __NR_lsetxattr 6
__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
#define __NR_fsetxattr 7
__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
#define __NR_getxattr 8
__SYSCALL(__NR_getxattr, sys_getxattr)
#define __NR_lgetxattr 9

有什么区别?我应该使用哪一个来索引sys_call_table

2 个答案:

答案 0 :(得分:1)

asm-generic是一个模板版本,如果您正在为内核开发新的体系结构,可以使用它。我相信您会发现内核源中实际上有unistd.h的许多版本,因为系统调用的顺序(实际上是系统调用的存在)因体系结构而异。从内核源层次结构的根开始尝试以下操作:

find . -name 'unistd*.h'

特别是对于x86,在构建内核时会自动生成uapi版本。请参阅Makefile目录中的*.tbl和各种arch/x86/entry/syscalls/文件。最终生成文件:

arch/x86/include/generated/uapi/asm/unistd_64.h
arch/x86/include/generated/uapi/asm/unistd_32.h
arch/x86/include/generated/uapi/asm/unistd_x32.h

(所有#include来自存根unistd.h文件)。

最终,Linux“发行版”的创建是非常特定于体系结构的,因此发行版创建者应将正确的unistd.h文件复制到/usr/include层次结构中的某个适当位置。 (当然,您的libc也需要针对正确的版本进行编译,以使普通的libc系统调用正常工作。)

总而言之,/usr/include/asm中的版本更好与您正在运行的内核匹配,否则将无法从系统上的用户进程正确生成即席系统调用,但您不应在内核源层次结构中使用该代码,因为从根本上讲,内核源层次结构从不依赖于用户空间标头。在内核源代码中,为该表建立索引的机制与体系结构有关,因为表的布局和顺序本身与体系结构有关,并且通常只有体系结构特定的代码(系统调用条目代码)才能访问该表,因此代码“需要知道”正确的索引。

现在,如果要创建一个新的系统调用,则需要在所有unistd.h文件中为您希望其出现的所有体系结构定义其编号。

答案 1 :(得分:1)

这实际上取决于您要寻找的体系结构。这会随着拱的变化而变化,通常放置在arch/$ARCH文件夹下的某个位置。对于嵌入式体系结构,这通常是一个硬编码表,对于不同的变体甚至可能会更改。

对于x86 / 64,此表是在构建时自动生成的,正如您在arch / x86 / Makefile中看到的那样

syscall32 := $(srctree)/$(src)/syscall_32.tbl
syscall64 := $(srctree)/$(src)/syscall_64.tbl
...
$(uapi)/unistd_32.h: $(syscall32) $(syshdr)
    $(call if_changed,syshdr)
...
$(uapi)/unistd_64.h: $(syscall64) $(syshdr)
    $(call if_changed,syshdr)

基本上会调用arch/x86/entry/syscalls/syscallhdr.sh脚本,该脚本将根据您的unistd_32.h自动生成unistd_x32.h / unistd_64.h / menuconfig文件。

这意味着,如果您要查找x86 / x64的实际syscall表,可以在以下位置找到它们: arch/x86/entry/syscalls/syscall_32.tbl / arch/x86/entry/syscalls/syscall_64.tbl