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:
- The
include/linux/version.h
file, which contains kernel versioning information. - The proper
asm
symlink for your platform and theasm-offsets.h
file inside your platform’s specificasm
directory. - 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
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 thekernel-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.
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.
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 fedorakernel-devel
package, the needed files seem to be:–
*.h
–
Makefile*
–
Kconfig*
– the
/scripts
directoryThe 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.
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 areinclude/asm-generic
,include/asm-i386
(depends on the architecture) and theasm
symlink.– probably all directories under
arch/
, which are irrelevant to the architecture. I kept thearch/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 thetruecrypt
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.
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
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.
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
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.
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
Hi Anh,
The
/usr/src/kernels/
directory is created when you install thekernel-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.
GODLY TUTORIAL, THANK YOU!!!
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’?