RedHatKernelModulePackages
From KernelDrivers
Red Hat provide support for an implementation of Kernel Module Packages (kmods) through their joint work on the Fedora rawhide distribution, aswell as the Red Hat Enterprise Linux Driver Update Program (e.g. RHEL5 DUP). Different Linux distributions have differing goals with respect to module packaging, but a decision was taken early on to base any generalized Red Hat solution on the Fedora Extras kernel module packaging process, since the community had already invested significant time and effort into that process. We wanted to avoid re-inventing the wheel while also working with other vendors on common problems.
What you'll find here
In this article, you will learn the following:
- How the overall process of kmods works.
- How to write kmod SPEC files from scratch.
- How to modify existing Fedora Extras packages.
- Where to find out more information.
- Some further technical commentary.
Who to contact
For further information, you can contact Jon Masters and ask to be added to a (low bandwidth) announce list, which should receive traffic when updates to this documentation are made available. If you are a Red Hat partner or customer, contact your partner manager or other Red Hat point of contact for further information (or just mail Jon Masters directly). We suggest bookmarking this site and checking back from time to time as updates are made to this documentation.
Overview of Red Hat Kernel Module Packaging process
Red Hat distributions provide infrastructure to support kernel module packaging. This means that drivers (or other modules) that are built for a given Linux kernel may be packaged up and supplied to end users. There is support for kernel ABI tracking to allow a given module package to be used with a range of target Linux kernels. Therefore, it is not always necessary to rebuild drivers when newer kernel releases occur.
The following data is used to support Red Hat kmods (kver is the kernel version built against):
- Symbolic reference data for the current kernel in /usr/src/kernels/$kver/symsets-$kver.tar.gz
- Symbolic reference data for the updated driver in /lib/modules/$kver/extra/test/kmp.ko
- RPM "provides" and "requires" dependencies referencing these data.
- A few scripts and glue to hold the process together.
The internal build process is somewhat complex, but the packaging itself is not. In fact, it's possible to adapt an existing Fedora Extras kernel module package (kmod) in a matter of minutes by making just a couple of changes to the RPM SPEC file. In the case that you're packaging from scratch, it is not difficult to write a simple spec file from scratch for your package(s).
Once a kernel module has been packaged, you're usually left with two RPM packages per kernel module that you wish to ship - the "kmod" module RPM itself, and a "common" RPM package containing higher level user dependencies (documentation, firmware files, and the like). The kmod package provides dependency requirements against subsets of the kernel ABI, as provided by the kernel package itself. This allows regular package management software (such as yum) to make semi-intelligent decisions about driver and kernel versions installed.
Writing your own kmod
Building your own kmod package is not difficult and can be achieved in a matter of minutes by following this guide. Broadly speaking, there are two ways to build a kmod. You can use the macros discussed here directly in your SPEC file, or you can choose to forego these simplification macros and work with a more complex RPM SPEC file - it's your choice. We suggest using the macros in the first instance, especially for relatively straightforward driver packaging situations.
- You can download and install an example kmod SRPM from this website (see the README file in the downloads directory for build instructions) that you can use to follow along with this process, should you like to do so. Another more complex example for a real working WiFi driver, not using the standard macros, is included on the same download site location, and is discussed later in this article.
Please note that kmods require some module source that successfully builds out-of-tree against a particular Linux kernel. You should already have a tarball containing such sources before proceeding further - for information about building drivers outside of the Linux kernel, check out the many useful articles and reference information at LWN.
Example Files
In the case of this example, a test archive test-1.0.tar.bz2 contains the following files:
hello.c Kbuild
hello.c
The module source is contained within the hello.c file. It simply uses the kernel's printk function in order to log a greeting whenever the module is loaded and unloaded from a running kernel. Here is the source:
/*
* hello.c - An example Kernel Module Package.
*
* Copyright (C) 2006
* Jon Masters <jcm@redhat.com>
*
* Based on the KMP example from Novell which is
* Copyright (C) 2003, 2004, 2005, 2006
* Andreas Gruenbacher <agruen@suse.de>, SUSE Labs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/init.h>
int hello_world(void)
{
printk("Hello, World!\n");
return 0;
}
int __init hello_init(void)
{
printk("Loaded module.\n");
return 0;
}
void __exit hello_exit(void)
{
printk("Unloaded module.\n");
}
/* Module Metadata */
MODULE_AUTHOR("Jon Masters <jcm@redhat.com>");
MODULE_DESCRIPTION("KMP example");
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
/* Exported Functions */
EXPORT_SYMBOL_GPL(hello_world);
Kbuild
The module source is built using the kernel kbuild system using the commands located within the Kbuild file:
obj-m := kmp.o kmp-y += hello.o
The output of the build process is a single kernel object .ko file called kmp.ko that can be loaded:
$ modprobe kmp
and unloaded:
$ modprobe -r kmp
using the standard module-init-tools commands, provided that the module has been installed into the standard /lib/modules (or other alternatively configured) location.
test.spec
The test module can be built but in order to be shipped out using the standardized kernel ABI tracking, it is necessary to produce a modified RPM SPEC file. The test.spec SPEC file is not particularly complex, since the magic is hidden within a special script known as kmodtool. A special version of this Fedora Extras script has been made available, which supports generating kernel ABI dependency information. You should use the version supplied on this website and in the test packages if you wish to have ABI tracking enabled, which you probably do, since you're reading through this documentation.
Here is the example SPEC file:
%define kmodtool sh /usr/lib/rpm/redhat/kmodtool
# hardcode for now:
%{!?kversion: %{expand: %%define kversion %(uname -r)}}
%define kmod_name test
%define kverrel %(%{kmodtool} verrel %{?kversion} 2>/dev/null)
%define upvar ""
%ifarch i686
%define paevar PAE
%endif
%ifarch i686 ia64 x86_64
%define xenvar xen
%endif
%ifarch ppc64
%define kdumpvar kdump
%endif
%{!?kvariants: %define kvariants %{?upvar} %{?xenvar} %{?kdumpvar}}
Name: %{kmod_name}-kmod
Version: 6.0
Release: 1.0
Summary: An example RHEL5 kmod (driver update)
License: Distributable
Group: System Environment/Kernel
URL: http://www.kerneldrivers.org/
#Source is created from these files:
Source0: test-1.0.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
ExclusiveArch: i686 ia64 ppc64 s390x x86_64
%description
This package provides a test kmod package for RHEL style driver updates. It is
built to depend upon the specific ABI provided by a range of releases of the
same variant of the RHEL kernel and not on any one specific build.
# magic hidden here:
# NOTE: these two extra defines will not be necessary in future.
%define kmp_version %{version}
%define kmp_release %{release}
%{expand:%(%{kmodtool} rpmtemplate_kmp %{kmod_name} %{kverrel} %{kvariants} 2>/dev/null)}
%prep
%setup -q -c -T -a 0
for kvariant in %{kvariants} ; do
cp -a test-1.0 _kmod_build_$kvariant
done
%build
for kvariant in %{kvariants}
do
ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
pushd _kmod_build_$kvariant
make -C "${ksrc}" modules M=$PWD
popd
done
%install
export INSTALL_MOD_PATH=$RPM_BUILD_ROOT
export INSTALL_MOD_DIR=extra/%{kmod_name}
for kvariant in %{kvariants}
do
ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
pushd _kmod_build_$kvariant
make -C "${ksrc}" modules_install M=$PWD
popd
done
%clean
rm -rf $RPM_BUILD_ROOT
%changelog
* Fri Feb 23 2007 Jon Masters <jcm@redhat.com>
- Redid this example for kerneldrivers.org documentation.
The SPEC file simply extends the existing Fedora Extras packaging process by providing a new parameter to the kmodtool script (rpmtemplate_kmp) that is very slightly different from the Fedora Extras version. The regular unpack, patch and build cycles are as they would be for most packages, although specific use of a loop to build a variety of variants of the same kmod allows for the many kernel flavors in use.
Building the example kmod
Download the test SRPM packages (both kmod-test and its common counterpart) from this website as an alternative to simply typing the previous sections in a text editor from scratch.
- Install the SRPMS using rpm:
$ sudo rpm -ivh test-kmod-6.0-1.0.src.rpm \
test-kmod-common-6.0-1.src.rpm
- Rebuild the RPMS using rpmbuild:
$ sudo rpmbuild -ba /usr/src/redhat/SPECS/test.spec $ sudo rpmbuild -ba /usr/src/redhat/SPECS/test-common.spec
- Install the binary RPMS using rpm:
$ sudo rpm -ivh \
/usr/src/redhat/RPMS/$arch/kmod-test-6.0-1.0.$arch.rpm
/usr/src/redhat/RPMS/noarch/test-kmod-common-6.0-1.noarch.rpm
You can now confirm that the packages are installed and operating correctly by using modprobe:
$ sudo /sbin/modprobe kmp
to unload:
$ sudo /sbin/modprobe -r kmp
Congratulations! You have successfully built an ABI-tracking kmod.
Notes
- If you don't want to have a dependency on the "common" package, you can use your own version of kmodtool. Simply copy the standard version to your RPM SOURCES, change the script location in the SPEC file and comment out the reference to the "common" package from your local kmodtool copy. In later releases, it will not be necessary to do this as use of a common package will be controlled via a flag to the systemwide kmodtool script.
This document is being expanded to cover a number of other technical issues beyond simple packaging examples. Please check back here soon (or mail and ask to be added to the announcement list) for updated coverage and for a variety of links to additional documentation.

