The Complete Fedora Kernel Headers

11 Comments

The official fedora kernel-devel package does not include the complete kernel headers. This should not be a problem in most cases when compiling third party modules, but there are times that one or more of these missing headers are absolutely needed. This document outlines a method to obtain the complete kernel headers for your currently running kernel in Fedora Core by using the kernel SRPM package without compiling the kernel.

The biggest part of the following info exists in the official Fedora Release Notes and the rest is the result of much trial and error…

The Situation

I bet you have been in a situation, where the compilation of a third party kernel module in Fedora does not complete, because a kernel header file is missing. The official kernel-devel Fedora RPM package does not include all the kernel headers. This seems to be a fact. I am not really sure what is the reason for this, but I truly believe that the developers have a good one for excluding some headers from the kernel-devel package.

However, from the user’s perspective, this situation is pretty annoying. A mere example is that a commonly needed LIRC module, lirc_gpio, cannot be compiled due to the fact that bttv.h and bttvp.h are not included in the kernel-devel package. There are a couple of other third party kernel modules I could not get compiled because of this, but I am sure there are more.

On the other hand, the complete Fedora Kernel Source Code is shipped in the kernel SRC RPM. This file can be downloaded from the official repositories. The solution to the above issues is to use the complete kernel headers contained in this SRPM package. Some preparation is required though, and this is what this document is all about.

The Goal

The primary goal of this article is to provide a method to prepare the Fedora kernel sources to match our currently running kernel, so that the headers can be properly used to compile modules that wouldn’t compile by using the kernel-devel package, because of the missing files.

The secondary goal is to achieve the previous goal without re-compiling the kernel. This article assumes that we want to use the default kernel configuration, so the re-compilation of the whole kernel is considered as a waste of system resources and time.

The Basic Steps

These steps are very well described in the Fedora Core 4 Release Notes (section 7.2.2.3.), but here I add some more explanation.

First of all, we need to download the kernel SRPM package, whose version and release match our currently running kernel. This version is shown by the following command:

# uname -r

The rest of the article assumes that our working directory is:
/usr/src/redhat/
All commands should be issued by a user and not by root, so that you do not accidentally break anything.

Use any method (wget, yumdownloader, any ftp or http client) you like to download the kernel SRC RPM. Just make sure you download the correct version. This is critical.

Next thing is to install the SRPM package. This just extracts the included files in the proper directories under /usr/src/redhat/ or to the directory tree you use for building. It does not actually install any kernels. As a user, run:

# rpm -ivh kernel-$(uname -r).src.rpm

This extracts the kernel source packages and the various patches in the SOURCES directory and the spec file in the SPECS directory. The SRC RPM file is not needed any more.

Next, we execute the %prep stage of the spec file, by issuing the following command:

# rpmbuild -bp --target $(arch) --rmsource --rmspec SPECS/kernel-2.6.spec

This extracts the kernel source code package and applies all the Red Hat patches. All the files are placed in the BUILD directory. Here follows an explanation of the options:
-bp : Execute only the %prep stage
–target : Specify the architecture. You can explicitly put your architecture, instead of the $(arch) in this option. This is the same thing.
–rmsource : This removes all the kernel SRC RPM related files under the SOURCES directory, so no unneeded files are left to the system.
–rmspec : This also removes the spec file from the SPECS directory.

Now, we move to the directory containing the fedora kernel sources (2.6.14 is the version of the kernel I was using at the moment of writing):

# cd BUILD/kernel-2.6.14/linux-2.6.14

Copy the proper kernel configuration file, that matches your architecture, from the configs directory and place it in our current working directory, naming it as .config and replacing the already existent .config file. For example, I used the kernel-2.6.14-i686.config file :

# cp configs/kernel-2.6.14-i686.config .config

These files most probably contain the same configuration options, but we do this for completeness.

Next thing is to add the proper kernel release number to the Makefile (in directory: BUILD/kernel-2.6.14/linux-2.6.14/). As it is stated in the Fedora release notes, in order to "protect the innocent" the value of the EXTRAVERSION field is -prep. Open this Makefile in a text editor and replace the -prep with the release number of your currently running kernel. For example, my running kernel at the time of writing is 2.6.14-1.1637_FC4. I replace the:

EXTRAVERSION = -prep

with :

EXTRAVERSION = -1.1637_FC4

The last action of the basic configuration is to run the following command:

# make oldconfig

This command sets the default answers to all kernel configuration questions according to the settings of our .config file. This command is more relevant to kernel re-building, but won’t hurt issuing it.

Extra Steps (updated Fri Dec 16, 2005)

At this point, if you try to compile any third party kernel modules using this directory as the kernel source directory, you will most probably encounter errors. This is because some more preparation should be done to the kernel sources (this mainly involves the include directory).

A full compilation of the kernel would set all these things straight, but one of the goals is to avoid the compilation of the kernel to save some time. We have not modified any of the kernel configuration options or applied any extra patches, so this would be pointless anyway.

I remind that our current directory is:
/usr/src/redhat/BUILD/kernel-2.6.14/linux-2.6.14

A file, named Module.symvers, which contains information about the native kernel modules, needs to be present inside our current directory. This file is normally created after the native kernel modules are compiled. Since we are not building the kernel or any modules and since we have not modified the default kernel configuration, we can use the Module.symvers file, which is included in the official fedora kernel-devel RPM.

The presense of this file is important when we compile any third party modules using these kernel headers. If it’s not there, then our modules will not contain any dependency information, regarding the native kernel modules. This way, if the third party module depends on some native kernel modules, then you will have to load the latter manually.

So, copy the Module.symvers file from the directory, where the official fedora kernel-devel package is installed, into our current directory:

# cp /usr/src/kernels/$(uname -r)-$(arch)/Module.symvers .

Finally, we issue the following command:

# make prepare scripts

This creates:

  1. The include/linux/version.h file, which contains kernel versioning information.
  2. The proper asm symlink for your platform and the asm-offsets.h file inside your platform’s specific asm directory.
  3. The scripts that come with the kernel sources. These are needed when we compile third party modules using these headers.

This is the proper and most complete way of preparing our headers, instead of compiling each of the files mentioned above individually (as I had written in this article before this update).

That should be the end of all the needed actions in order to accomplish our goal.

Final Words

At this point, we have a custom directory that contains:

  • The fedora kernel sources. The kernel has not been compiled.
  • The kernel headers that match those of the kernel-devel RPM package with the difference that they are complete. No files are missing.

This directory:
/usr/src/redhat/BUILD/kernel-2.6.14/linux-2.6.14
can be moved to any place you like. Give it a proper name that includes your currently running kernel version and release. The kernel headers, contained in this directory, can be used in order to compile any third party kernel modules. The rest of the contents of the /usr/src/redhat/BUILD/ directory, can be deleted, unless you need it.

Keep in mind, that if you install a different kernel in your system, this procedure has to be done again from the beginning. My next task is to create a BASH script that automates all this, so I do not have to do this by hand every time I upgrade the official kernel. You will find the script here.

If you use the official Fedora kernel, I highly recommend that you use the respective kernel-devel RPM package in order to build any third party modules. If they fail due to missing headers, then use the kernel sources. I always consider the latter as a secondary option.

Unfortunately, my technical knowledge cannot give you any guarantees that this will work for you or if this guide is complete. At least, I do not have any issues when I compile and use kernel modules, which would not compile using the kernel-devel package due to missing headers. You are encouraged to leave your feedback.

Further Reading

You should read:

The Complete Fedora Kernel Headers by George Notaras is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Copyright © 2005 - Some Rights Reserved

George Notaras avatar

About George Notaras

George Notaras is the editor of the G-Loaded Journal, a technical blog about Free and Open-Source Software. George, among other things, is an enthusiast self-taught GNU/Linux system administrator. He has created this web site to share the IT knowledge and experience he has gained over the years with other people. George primarily uses CentOS and Fedora. He has also developed some open-source software projects in his spare time.

11 responses on “The Complete Fedora Kernel Headers

  1. George Notaras Post authorPermalink →

    UPDATE [Fri Dec 16, 2005]

    1 – The extra steps:
    # make include/linux/version.h
    # make include/asm
    # make scripts

    Have been substituted with the more general and complete:
    # make prepare scripts

    2 – The copy of the Module.symvers file from the directory, where the kernel-devel package is installed, to the root of our kernel sources’ directory has been added as an extra and important step.

    Your feedback is welcome.

  2. Vikram Goyal Permalink →

    Hi Roul,

    It’s a very comprehensive and usefull way of making kernel headers available for a user. I normally download the kernel from kernel.org and compile a customised lean kernel for my machine. The problem which I face is that if I have to compile a third party module, say for vmware for my running customised kernel then I have to keep the whole compiled kernel image which amounts to nearly 1.5G whereas kernel-devel package installs only around 75Mb. Even if we keep all the headers then I think it should not go beyond 100Mb.

    So, I ask you, if you can post some pointers where one can delete the unneccessary files and make available kernel headers from the compiled kernel tree.

  3. George Notaras Post authorPermalink →

    Hello Vikram,
    I’m afraid that I do not have the necessary knowledge to provide an 100% accurate answer to this. My kernel sources directory occupies 268MB of space (the kernel hasn’t been compiled), which is still too much, since I only need the headers. So, I guess I have the same issue somehow.

    Generally, it should be safe to delete the C source *.c and the intermediate build products, for example the *.o files. Only the headers (.h files) are needed in order to compile 3rd party modules. Taking a closer look at the contents of the official fedora kernel-devel package, the needed files seem to be:
    *.h
    Makefile*
    Kconfig*
    – the /scripts directory

    The following command:

    # find /usr/src/kernels/2.6.14-1.1653_FC4-i686 -type f ! -name *.h ! -name Makefile* ! -name Kconfig* | grep -v 'FC4-i686/scripts'

    shows that the kernel-devel package, apart from the files mentioned above, also contains the following:

    /usr/src/kernels/2.6.14-1.1653_FC4-i686/.config
    /usr/src/kernels/2.6.14-1.1653_FC4-i686/include/config/MARKER
    /usr/src/kernels/2.6.14-1.1653_FC4-i686/Module.symvers
    /usr/src/kernels/2.6.14-1.1653_FC4-i686/arch/i386/kernel/asm-offsets.s

    This means, that if I erase all other files from my kernel sources directory, except for all those mentioned above, I would still have the complete kernel headers and 3rd party modules should compile properly.

    So I wrote a simple script to erase all other files:

    [UPDATE]: WordPress had removed the backslashes from the following script. This is fixed.

    #! /bin/bash
    
    #edit - WITHOUT TRAILING SLASH
    KERNSRC="/usr/src/redhat/BUILD/kernel-2.6.14-1.1653_FC4-i686-full-testing"
    
    find "$KERNSRC" -type f \
    	! -name *.h \
    	! -name Makefile* \
    	! -name Kconfig* \
    	! -name *.symvers \
    	! -name MARKER \
    	! -name .config \
    	! -name asm-offsets.s \
    	| grep -v "$KERNSRC/scripts" \
    	| xargs rm -f
    
    exit 0
    

    The occupied space was reduced to around 100MB. Only regular files were deleted though, the directories remained. I could further reduce the occupied space by deleting:
    – all irrelevant asm directories in include/. The needed ones are include/asm-generic, include/asm-i386 (depends on the architecture) and the asm symlink.
    – probably all directories under arch/, which are irrelevant to the architecture. I kept the arch/i386.
    – the documentation

    All the above, are based on the fedora kernel SRPM.

    Vikram, please consider all these as a hackish-like method to reduce the occupied space. Maybe this is a completely wrong approach. Anyway, after keeping only these files, I could compile the lirc_gpio and the truecrypt kernel modules without the singlest of problems.

    Furthermore, instead of all those actions, you could try doing a:
    NOTE: Keep a copy of the Module.symvers file.

    # make clean

    and then perform the extra step I describe in the above article:

    # make prepare
    # make scripts

    This way, you would get rid of the kernel compilation products which take a lot of space, but still have a usable set of kernel headers.

    I hope these give you some helpful hints to investigate the issue yourself. Thanks for your comment. Very interesting indeed.

  4. Radhakrishnan Permalink →

    Hello,

    This is Kris from Austin,TX.

    I am new to Linux, installed RHEL 3.0 on DELL 2550 and upgrded the kernel to 2.4.21-37ELsmp.

    Now I am trying to install the ncipher software which needs kernel headers for the above said kernel 2.4.21-37ELsmp.

    I tried your kernel header script to get the headers to install ncipher software. I couldn’t get Module.symvers file in the location you mentioned or Kernel-devlop rpm pkg in the source CD.

    RHEL 3.0 by default didn’t install any kernel headers .

    Appreciate if you let me know how to solve this issue.

    Thanks,
    Kris

  5. George Notaras Post authorPermalink →

    Kris: I have never used any version of RHEL so I don’t know about the RPM naming scheme. First of all, try to install the default kernel development package for your running kernel. This contains the kernel headers that most 3rd party modules need in order to be compiled. You could use the above article’s approach only if you cannot compile the 3rd party module using kernel-devel. But, the problem is that this info was written for a 2.6.X kernel.
    I strongly suggest that you ask for help at the Fedora Forum or contact Red Hat support.

  6. Radhakrishnan Permalink →

    Hi George,

    Thanks a lot I just installed kernel headers as per your script for RHEL4 for the kernel 2.6.9-11.EL.

    Can you tell me how to load the thirdparty drivers generally.

    example: I loaded ncipher server software after installing the headers it installed their drivers as nfp.
    lsmod shows the entry for new driver as nfp

    if i will try to add the module as modprobe nfp , I got the error as ” FATAL: Module nfp not found “.

    Any idea to fix this ?

    Thanks in advance
    Kris

    Kris

  7. George Notaras Post authorPermalink →

    Kris:
    This is general info regarding kernel modules. After you install them, you issue the following command so that the "module database" is updated:
    # depmod -a

    Then you load the module with modprobe exactly as you have written.

    I believe that you should address your questions regarding commercial software to their support channels or to a professional consultant.

  8. Anh Permalink →

    Hi George

    I followed your instructions but I could not find the file Module.symvers. In my /usr/src directory , I only see redhat directory , no kernels directory.
    # ls /usr/src/
    redhat

    Can you tell how I you get /usr/src/kernels?
    Thanks
    Anh

  9. George Notaras Post authorPermalink →

    Hi Anh,
    The /usr/src/kernels/ directory is created when you install the kernel-devel package.
    The Module.symvers file is created when we compile the kernel native modules. In order to save some time and since we use a kernel SRPM with same version as our running kernel, we use the Module.symvers file from the kernel-devel package.
    Although this info is included in the above article, I re-post it here, so that it is more clear.

  10. radix Permalink →

    GODLY TUTORIAL, THANK YOU!!!

  11. Chun-Chung Chen Permalink →

    Since you already have kernel-devel in place, wouldn’t it be easier just do a ‘rsync –ignore-existing’ from the source tree to your kernel-devel tree after doing the ‘rpmbuild -bp’?