While I was doing some reading on system calls, I did a search for "syscalls.h" to find the header file in LXR. The search results puzzled me. There is a dozen of "syscalls.h" files coming from directories under "arch/_arch_name_/include/asm". These are ok, they are architecture specific definitions or something else needed. The question is why do we have two different "syscalls.h" headers under both /include/linux and /include/asm-generic?

Also, I want to find out that what /include/linux headers are for and what /include/asm-generic headers are for. How do they differentiate between each other? What is the logic behind having two separate header folders? How do they relate to each other?



3 Answers 3


The headers under asm/generic are meant mostly as stopgap measures, portable versions in C until a architecture-specific version is written. You'll also find that in some cases /usr/include/foobar.h includes a slew of "internal implementation" headers, and finally fall back on a part that comes from the kernel, often called the same. Examples are math.h and (more Linux-dependent) syscall.h.


The software has to be portable. If you compile your C/C++ sources, then you don't need to know if you running i386/x86_64/arm/mips or what ever. The headers are linked in such way the software compiles.

All other header files exist because they were implemented a lot of different standards, there are ports from BSD and so on. So many of them are historically based. Where each one comes from and why they are there has many different reasons and will surely blow answers.

And an answer for asm-generic: stackoverflow


arch/x86/entry/ has two special syscall files:

syscalls/syscall_32.tbl and dito "64"

Syscalls are special because the kernel has to bring ABI and API together.

In general, the include dirs and the other header files (independant ones like kernel/sched/sched.h) follow a hierarchical logic. I think both make and gcc play a role.

There is systematic use of these symbols to make sure every header "unit" is read only once. ("protective wrappers" because there can be too much criss-cross). Here from include/linux/mm.h:

    #ifndef _LINUX_MM_H
    #define _LINUX_MM_H

    #include <linux/errno.h>

    #ifdef __KERNEL__

    ...  (#includes)
    ...  (ext. decl. etc., the whole mm.h)

    #endif /* __KERNEL__ */
    #endif /* _LINUX_MM_H */

The tbl files have:

# 32-bit system call numbers and entry vectors

The list starts with:

0    i386    restart_syscall    sys_restart_syscall       __ia32_sys_restart_syscall
1    i386    exit               sys_exit                  __ia32_sys_exit
2    i386    fork               sys_fork                  __ia32_sys_fork
3    i386    read               sys_read                  __ia32_sys_read

# 64-bit system call numbers and entry vectors
# The format is:
# <number> <abi> <name> <entry point>
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
# The abi is "common", "64" or "x32" for this file.

I'll do the layout later...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .