There is a file version.h in /usr/include/linux. Many header files include this file and use the defines in there for their own ifdefs.

However, when I compile my own kernel, I cannot see how this can possibly be reflected correctly in e.g. version.h.

Actually this holds for all kernel-related header files. AFAICS /usr/include/linux always represent the kernel which came with my distribution and neither the running kernel, nor the kernel I tell make by means of SYSSRC.

In the past I resorted to creating symlinks to my own kernel sources, but I have a feeling that this is not the correct way.

How is this supposed to work? How do I compile (e.g. a kernel module) against a custom kernel?

  • I imagine that the package-manager that installs your system, sorts it out. Also if there is a change (not just an addition), then every single program would need recompiling. So I do not imagine that these things change much. – ctrl-alt-delor Jul 21 '16 at 22:41
  • My actual problem is with a kernel module. There I could understand that you really need the correct headers. For userspace programs you are probably right, though I don't quite know why they would need kernel headers at all. – Martin Drautzburg Jul 22 '16 at 12:47

When configuring a system against your own custom kernel, I would suggest adding a name to the current version in your modified kernel sources.

For instance, in Armbian they create their own kernel packages, and add a -sunxi to kernel.release.

Takin as an example modifying the 4.6.3 kernel version:

root@ruir:/usr/src/linux-headers-4.6.3-sunxi# grep -ri 4.6.3-sunxi *
include/generated/utsrelease.h:#define UTS_RELEASE "4.6.3-sunxi"

and also, for the kernel modules, in /lib/modules/4.6.3-sunxi/build:

include/generated/utsrelease.h:#define UTS_RELEASE "4.6.3-sunxi"
include/config/auto.conf.cmd:ifneq "$(KERNELVERSION)" "4.6.3-sunxi"

(see installing sysdig in ARM / Armbian Jessie - module compiled in wrong kernel version )

As we can see, this can be seen in uname -r:

$uname -r

As for the custom kernel packages:

$dpkg -l | grep sunxi
ii  linux-dtb-next-sunxi             5.16                                  armhf        Linux DTB, version 4.6.3-sunxi
ii  linux-firmware-image-next-sunxi  5.16                                  armhf        Linux kernel firmware, version 4.6.3-sunxi
ii  linux-headers-next-sunxi         5.16                                  armhf        Linux kernel headers for 4.6.3-sunxi on armhf
ii  linux-image-next-sunxi           5.16                                  armhf        Linux kernel, version 4.6.3-sunxi

As for adding your own headers of your compile kernel, I will refer to KernelHeaders (emphasis as bold is mine); if you are replacing minor kernel versions you may (or may not) get away with only make headers_install.

User space programs

In general, user space programs are built against the header files provided by the distribution, typically from a package named glibc-devel, glibc-kernheaders or linux-libc-dev. These header files are often from an older kernel version, and they cannot safely be replaced without rebuilding glibc as well. In particular, installing /usr/include/linux as a symbolic link to /usr/src/linux/include or /lib/modules/*/build/include/linux is highly discouraged as it frequently breaks rebuilding applications. For instance, older kernels had the architecture specific header files in include/asm-${arch} instead of arch/${arch}/include/asm and had on a symlink to the architecture specific directory.

The correct way to package the header files for a distribution is to run 'make headers_install' from the kernel source directory to install the headers into /usr/include and then rebuild the C library package, with a dependency on the specific version of the just installed kernel headers.

If you are distributing a user space program that depends on a specific version of some kernel headers, e.g. because your program runs only on patched or very recent kernels, you cannot rely on the headers in /usr/include. You also cannot use the header files from /usr/src/linux/include or /lib/modules/*/build/include/ because they have not been prepared for inclusion in user space. The kernel should warn you about this if you try it and point you to this Wiki page. The correct way to address this problem is to isolate the specific interfaces that you need, e.g. a single header file that is patched in a new kernel providing the ioctl numbers for a character device used by your program. In your own program, add a copy of that source file, with a notice that it should be kept in sync with new kernel versions. If your program is not licensed under GPLv2, make sure you have permission from the author of that file to distribute it under the license of your own program. Since your program now depends on kernel interfaces that may not be present in a regular kernel, it's a good idea to add run-time checks that make sure the kernel understands the interface and give a helpful error message if there is no fallback to an older interface.

Also for kernel development; or compiling a kernel/module for a different server or for a different kernel with multiple kernel versions installed, SYSSRC maybe be used to specify an alternate kernel source location.

  • I did add my custom suffix. I don't have a problem with /usr/src/linux-headers-xxx or the modules. My problem is with /usr/include/linux. This directory exists only once and if a program does #include <linux/version.h> it'll include from there, doesn't it? So it will always get the same kernel-headers, i.e. the ones which came with my distribution and not the ones from my custom kernel. – Martin Drautzburg Jul 22 '16 at 12:44
  • I added to the answer. – Rui F Ribeiro Jul 22 '16 at 13:52
  • Good. One last question: what is the point of the SYSSRC variable? What could a kernel module possibly want from the kernel sources particularly if the headers are taken from /usr/include. – Martin Drautzburg Jul 22 '16 at 19:54
  • Added again to the answer. – Rui F Ribeiro Jul 22 '16 at 20:50
  • I know what SYSSRC does, but I don't know why it is necessary. The headers are still taken from /usr/include (AFAICS). So something else of interest must be in the kernel source tree, but what? – Martin Drautzburg Jul 22 '16 at 21:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.