Linux Kernel Headers – Usage in Userspace and Differences

kernel-moduleslinux-headerslinux-kernel

It might be a incoherent question about kernel headers as I don't have clear understanding about it and where and how it is used. I think it might get flagged down. My question has 3 parts:

  1. I think Kernel headers provide a interface so that other part of the kernel, like modules, can use them. That's my bookish knowledge. I haven't seen or found any code that used kernel headers (I would appreciate if someone can point me to it). Can it be used in userspace too? Any code example would be appreciated.

  2. I found out that using make headers_install kernel headers are exposed for by userspace, but at the same time it is discouraged to use kernel headers in userspace. If it is discouraged then what is the use of exposing it to userspace?

  3. As per this and this, kernel header files (.h files) should be at 3 places:
    a. /usr/include/linux/kernel.h which is intended for user space
    b. /lib/modules/$(uname -r)/build/include/linux/sched.h which is external modules
    c. /usr/src/... which is used for kernel modules
    Does it mean header files in different directories have different purpose or different interface or signature? In other words, does #include <linux/xyz.h> in a userspace code has different meaning than #include <linux/xyz.h> in kernel module? Also is external module same as kernel module?

Thanks.

Best Answer

Welcome to Unix & Linux StackExchange!

Yes, the kernel headers provide an interface for other parts of the kernel - in this you're entirely correct. They also include definitions for the interface between the kernel and the userspace - but usually the "raw" kernel interface is not used directly, but through the C library (often glibc).

The userspace-kernel interface may include multiple versions of a particular system call, for backwards compatibility reasons. By making the system call through the C library, all the applications get the same version of the actual system call, and thus a guarantee of consistent behavior. Also, when the relevant part of the kernel interface gets updated, you'll only need to update the C library to take advantage of new features.

(For example, when time_t gets extended to 64-bit in 32-bit architectures to avoid the Y2K38 problem, the C library may move to always use the 64-bit version of the kernel interface, but have an userspace-configurable mapping for applications that still use the 32-bit version. At that point, the functions using 32-bit time_t can be obsoleted and removed from the kernel, and the C library can provide better workarounds for legacy applications that still use the 32-bit type.)

So, unless you're compiling your own versions od the C library also, you should generally prefer the development headers of the C library instead of using the kernel headers directly.

The headers in /usr/include/linux/ generally come with the development header package of the C library, and describe the version of the kernel theC limrary was compiled for. This is what an userspace application developer normally needs.

/lib/modules/$(uname -r)/build is often a symbolic link to /usr/src/... where the headers or full source code of the actual running kernel version is stored. It is used when compiling external (aka third-party) kernel modules, i.e kernel modules from sources that are not integrated to the main kernel source code. These headers include the necessary kernel API version signatures so that the modules can use version-specific kernel-internal APIs.

Related Question