424 lines
15 KiB
Plaintext
424 lines
15 KiB
Plaintext
|
WORKING WITH THE SUSE 2.6.x KERNEL SOURCES
|
||
|
|
||
|
Andreas Gruenbacher <agruen@suse.de>, SUSE Labs, 2003, 2004, 2005, 2006
|
||
|
|
||
|
|
||
|
This document gives an overview of how SUSE Linux kernels are
|
||
|
created, and describes tasks like building individual kernels
|
||
|
and creating external kernel modules.
|
||
|
|
||
|
A companion Update Media HOWTO that describes how to build driver update
|
||
|
disks (among other things) is available at:
|
||
|
|
||
|
ftp://ftp.suse.com/pub/people/hvogel/Update-Media-HOWTO.
|
||
|
|
||
|
|
||
|
TABLE OF CONTENTS
|
||
|
|
||
|
Overview
|
||
|
Compiling your own kernel
|
||
|
Building additional (external) modules
|
||
|
Supported vs. unsupported modules
|
||
|
Patch selection mechanism
|
||
|
Where to find configuration files
|
||
|
How to configure the kernel sources
|
||
|
Module load paths
|
||
|
|
||
|
|
||
|
OVERVIEW
|
||
|
|
||
|
The kernels for SUSE are generated from the vanilla Linux kernel sources
|
||
|
found at http://ftp.kernel.org, on top of which a number of patches are
|
||
|
applied. The resulting kernel source tree is configured and built,
|
||
|
resulting in a binary kernel.
|
||
|
|
||
|
Internally, the add-on patches and configuration files are maintained in
|
||
|
a CVS repository. A script (scripts/tar-up.sh) packs up the files in the
|
||
|
CVS repository in a form suitable for rpmbuild. When building the RPM
|
||
|
packages, the following binary packages get created:
|
||
|
|
||
|
* kernel-source
|
||
|
|
||
|
The kernel source tree, generated by unpacking the vanilla kernel
|
||
|
sources and applying the patches. The kernel sources are used by
|
||
|
a number of other packages. They can also be used for compiling
|
||
|
additional kernel modules.
|
||
|
|
||
|
* kernel-$FLAVOR
|
||
|
|
||
|
A number of binary kernels (for example, kernel-default for
|
||
|
uniprocessor machines, kernel-smp for smp machines, etc.). These
|
||
|
packages are all generated from the same kernel sources, and
|
||
|
differ in the kernel configurations used.
|
||
|
|
||
|
* kernel-syms
|
||
|
|
||
|
Kernel symbol version information for compiling external modules:
|
||
|
Functions and data structures that the kernel exports have version
|
||
|
information attached. When loading kernel modules, this version
|
||
|
information is used to make sure that the modules match the running
|
||
|
kernel.
|
||
|
|
||
|
* kernel-dummy
|
||
|
|
||
|
This package is relevant inside the SUSE build system only. We use
|
||
|
it to synchronize release numbers among the kernel packages. When
|
||
|
building packages locally, the kernel-dummy package can safely be
|
||
|
ignored.
|
||
|
|
||
|
|
||
|
The CVS repository contains the configuration files (.config) for all
|
||
|
SUSE kernel flavors. All configuration files are included in the
|
||
|
kernel-source package (see WHERE TO FIND CONFIGURATION FILES below).
|
||
|
|
||
|
|
||
|
In the installed system, the kernel-source package installs files in the
|
||
|
following directories:
|
||
|
|
||
|
|
||
|
* /usr/src/linux-$VERSION-$RELEASE/
|
||
|
|
||
|
The kernel sources.
|
||
|
|
||
|
* /usr/src/linux
|
||
|
|
||
|
A symbolic link to /usr/src/linux-$VERSION-$RELEASE.
|
||
|
|
||
|
* /usr/src/linux-$VERSION-$RELEASE-obj/$ARCH/$FLAVOR/
|
||
|
|
||
|
Kernel build object files for one kernel flavor. These
|
||
|
files are used for compiling additional kernel modules.
|
||
|
|
||
|
* /usr/src/linux-obj
|
||
|
|
||
|
A symbolic link to /usr/src/linux-$VERSION-$RELEASE-obj/$ARCH/$FLAVOR.
|
||
|
|
||
|
* /usr/share/doc/packages/kernel-source/
|
||
|
|
||
|
This document and an external kernel module example.
|
||
|
|
||
|
* /etc/init.d/running-kernel
|
||
|
|
||
|
Init script that adapts the kernel sources in /usr/src/linux to
|
||
|
the running kernel.
|
||
|
|
||
|
|
||
|
COMPILING YOUR OWN KERNEL
|
||
|
|
||
|
The kernel sources are found in the kernel-source.$ARCH.rpm package. The
|
||
|
recommended way to produce a binary kernel is:
|
||
|
|
||
|
(1) Install kernel-source.$ARCH.rpm. Change to the /usr/src/linux
|
||
|
directory.
|
||
|
|
||
|
(2) Configure the kernel (for example, ``make oldconfig'' or ``make
|
||
|
cloneconfig'', see HOW TO CONFIGURE THE KERNEL SOURCES).
|
||
|
|
||
|
(3) Build the kernel and all its modules (``make'').
|
||
|
|
||
|
(5) Install the kernel and the modules (``make modules_install'',
|
||
|
followed by ``make install''). This will automatically create
|
||
|
an initrd for the new kernel as well (see ``mkinitrd -h'').
|
||
|
|
||
|
(6) Add the kernel to the boot manager. When using lilo, run ``lilo''
|
||
|
to update the boot map.
|
||
|
|
||
|
Instead of building binary kernels by hand, you can also build
|
||
|
one of the kernel-$FLAVOR packages using RPM.
|
||
|
|
||
|
|
||
|
BUILDING ADDITIONAL (EXTERNAL) MODULES
|
||
|
|
||
|
A single binary kernel module generally only works for a specific
|
||
|
version of the kernel source tree, for a specific architecture and
|
||
|
configuration. This means that for each binary kernel that SUSE ships, a
|
||
|
custom module must be built. This requirement is to some extent relaxed
|
||
|
by the modversion mechanism: modversions attach a checksum to each
|
||
|
symbol (function or variable) exported to modules by the kernel. This
|
||
|
allows to use kernel modules that have been built for a kernel with a
|
||
|
different version or release number in many cases, as long as none of
|
||
|
the symbols the module uses have changed between the two kernel
|
||
|
versions.
|
||
|
|
||
|
When releasing maintenance or security update kernels for a specific
|
||
|
product, we carefully try to keep the kernel ABI stable. Despite this,
|
||
|
we sometimes have no choice but to break binary compatibility. In this
|
||
|
case, those kernel modules must be rebuilt.
|
||
|
|
||
|
Additional kernel modules for one of the SUSE kernel flavors can be
|
||
|
built in three different ways:
|
||
|
|
||
|
(1) by configuring the kernel sources in /usr/src/linux (or a copy,
|
||
|
see HOW TO CONFIGURE THE KERNEL SOURCES), or
|
||
|
|
||
|
(2) by using one of the standard configurations in
|
||
|
/usr/src/linux-obj/$ARCH/$FLAVOR, or
|
||
|
|
||
|
(3) by creating a Kernel Module Package (KMP) as described in the
|
||
|
Kernel Module Packages Manual, http://www.suse.de/~agruen/KMPM/.
|
||
|
|
||
|
|
||
|
The first method involves the following steps:
|
||
|
|
||
|
(1) Install kernel-source.$ARCH.rpm.
|
||
|
|
||
|
(2) Change to the /usr/src/linux directory. Configure the kernel
|
||
|
(for example, ``make oldconfig'' or ``make cloneconfig'', see
|
||
|
HOW TO CONFIGURE THE KERNEL SOURCES).
|
||
|
|
||
|
(3) Create files required for compiling external modules:
|
||
|
``make scripts'' and ``make prepare''.
|
||
|
|
||
|
(4) Compile the module(s) by changing into the module source directory
|
||
|
and typing ``make -C /usr/src/linux M=$(pwd)''.
|
||
|
|
||
|
(5) Install the module(s) by typing
|
||
|
``make -C /usr/src/linux M=$(pwd) modules_install''.
|
||
|
|
||
|
|
||
|
The second method involves the following steps:
|
||
|
|
||
|
(1) Install kernel-source.$ARCH.rpm.
|
||
|
|
||
|
(2) Install kernel-syms.$ARCH.rpm. This package is necessary for
|
||
|
symbol version information (CONFIG_MODVERSIONS).
|
||
|
|
||
|
(3) Compile the module(s) by changing into the module source directory
|
||
|
and typing ``make -C /usr/src/linux-obj/$ARCH/$FLAVOR M=$(pwd)''.
|
||
|
Substitute $ARCH and $FLAVOR with the architecture and flavor
|
||
|
for which to build the module(s).
|
||
|
|
||
|
If the installed kernel sources match the running kernel, you
|
||
|
can build modules for the running kernel by using the path
|
||
|
/lib/modules/$(uname -r)/build as the -C option in the above
|
||
|
command. (build is a symlink to /usr/src/linux-obj/$ARCH/$FLAVOR).
|
||
|
|
||
|
Starting with SuSE Linux 9.2 / SLES9 Service Pack 1, the
|
||
|
modversion information for the running kernel is also
|
||
|
contained in the kernel-$FLAVOR packages, and so for building
|
||
|
modules for the running kernel, the kernel-syms package is no
|
||
|
longer required.
|
||
|
|
||
|
(4) Install the module(s) with
|
||
|
``make -C /usr/src/linux-obj/$ARCH/$FLAVOR M=$(pwd) modules_install''.
|
||
|
|
||
|
|
||
|
Whenever building modules, please use the kernel build infrastructure as
|
||
|
much as possible, and do not try to circumvent it. The
|
||
|
Documentation/kbuild directory in the kernel sources documents kbuild
|
||
|
makefiles.
|
||
|
|
||
|
Please take a look at the demo module installed under
|
||
|
/usr/share/doc/packages/kernel-source for a simple example of an Kernel
|
||
|
Module Package (KMP).
|
||
|
|
||
|
|
||
|
SUPPORTED VS. UNSUPPORTED MODULES
|
||
|
|
||
|
As an extension to the mainline kernel, modules can be tagged as
|
||
|
supported (directly by SUSE, or indirectly by a third party) or
|
||
|
unsupported. Modules which are known to be flakey or for which SUSE does
|
||
|
not have the necessary expertise are marked as unsupported. Modules for
|
||
|
which SUSE has third-party support agreements are marked as externally
|
||
|
supported. Modules for which SUSE provides direct support are marked as
|
||
|
supported.
|
||
|
|
||
|
The support status of a module can be queried with the modinfo tool.
|
||
|
Modinfo will report one of the following:
|
||
|
|
||
|
- direct support by SUSE: "supported: yes"
|
||
|
- third-party support: "supported: external"
|
||
|
- unsupported modules: no supported tag.
|
||
|
|
||
|
At runtime, the setting of the" unsupported" kernel command line
|
||
|
parameter and /proc/sys/kernel/unsupported determines whether
|
||
|
unsupported modules can be loaded or not, and whether or not loading an
|
||
|
unsupported module causes a warning in the system log:
|
||
|
|
||
|
0 = only allow supported modules,
|
||
|
1 = warn when loading unsupported modules,
|
||
|
2 = don't warn.
|
||
|
|
||
|
Irrespective of this setting, loading an externally supported or unsupported
|
||
|
module both set a kernel taint flag. The taint flags are included in
|
||
|
Oopses. The taint status of the kernel can be inspected in
|
||
|
/proc/sys/kernel/tainted: Bits 0 to 4 have the following meanings:
|
||
|
|
||
|
bit 0 = a module with a GPL-incompatible license was loaded (tainted & 1),
|
||
|
bit 1 = module load was enforced (tainted & 2),
|
||
|
bit 2 = an SMP-unsafe module was loaded (tainted & 4),
|
||
|
bit 3 = (reserved),
|
||
|
bit 4 = an unsupported module was loaded (tainted & 16),
|
||
|
bit 5 = a module with third-party support was loaded (tainted & 32).
|
||
|
bit 10 = a machine check exception has occurred (taint & 1024; x86_64 only
|
||
|
so far).
|
||
|
|
||
|
The corresponding codes for the taint flags in Oopses are (x = unknown):
|
||
|
|
||
|
- "Pxxx" if bit 0 set or else
|
||
|
"Gxxx" if bit 0 unset,
|
||
|
|
||
|
- "xFxx" if bit 1 set or else
|
||
|
"x xx" if bit 1 unset,
|
||
|
|
||
|
- "xxSx" if set or else
|
||
|
"xx x" if bit 2 unset,
|
||
|
|
||
|
- "xxxU" if bit 4 set or else
|
||
|
"xxxX" if bit 5 set or else
|
||
|
"xxx ".
|
||
|
|
||
|
By default, external modules will not have the supported flag (that is,
|
||
|
they wil be marked as unsupported). For building externally supported
|
||
|
modules, please get in touch with Kurt Garloff <garloff@suse.de>.
|
||
|
|
||
|
|
||
|
PATCH SELECTION MECHANISM
|
||
|
|
||
|
The SUSE kernels consist of the vanilla kernel sources on top of which a
|
||
|
number of patches is applied. Almost all of these patches are applied on
|
||
|
all architectures; a few patches are only used on a subset of
|
||
|
architectures. The file series.conf determines which patches are applied
|
||
|
on which architectures. A script named "guards" converts series.conf
|
||
|
into a plain list of patch files to be applied. Guards decides which
|
||
|
patches to include and exclude based on a list of symbols. The symbols
|
||
|
used by default are computed by the helper script "arch-symbols". From
|
||
|
the kernel-source.src.rpm package, a fully patched kernel source tree
|
||
|
can be generated from vanilla sources + patches like this:
|
||
|
|
||
|
# Install the package:
|
||
|
|
||
|
$ rpm -i kernel-source.src.rpm
|
||
|
|
||
|
# Unpack the patches and the kernel sources:
|
||
|
|
||
|
$ cd /usr/src/packages/SOURCES
|
||
|
$ for f in patches.*.tar.bz2; do \
|
||
|
tar xfj $f || break; \
|
||
|
done
|
||
|
$ tar xfj linux-2.6.5.tar.bz2
|
||
|
|
||
|
# Apply the patches
|
||
|
|
||
|
$ for p in $(./guards $(./arch-symbols) < series.conf); do
|
||
|
patch -d linux-2.6.5 -p1 < $p || break
|
||
|
done
|
||
|
|
||
|
The configuration script config.conf which is similar to series.conf is
|
||
|
used for configuration file selection. See the section WHERE TO FIND
|
||
|
CONFIGURATION FILES.
|
||
|
|
||
|
The file format of series.conf and config.conf should be obvious from
|
||
|
the comments in series.conf, and from the guards(1) manual page. (The
|
||
|
guards(1) manual page can be generated by running pod2man on the guards
|
||
|
script.)
|
||
|
|
||
|
|
||
|
WHERE TO FIND CONFIGURATION FILES
|
||
|
|
||
|
Kernel configuration files are stored in the kernel CVS repository. When
|
||
|
packing up the repository, they end up in config.tar.bz. When
|
||
|
kernel-source.$ARCH.rpm is built, the config files are copied from
|
||
|
config/$ARCH/$FLAVOR to arch/$ARCH/defconfig.$FLAVOR in the kernel
|
||
|
source tree (for eaxmple, arch/i386/defconfig.default).
|
||
|
|
||
|
The kernel-$FLAVOR packages are based on arch/$ARCH/defconfig.$FLAVOR
|
||
|
(kernel-default is based on arch/$ARCH/defconfig.default, for example).
|
||
|
The kernel-$FLAVOR packages install their configuration files as
|
||
|
/boot/config-$VER_STR (for example, boot/config-2.6.5-99-default).
|
||
|
|
||
|
In addition, the running kernel exposes a gzip compressed version of its
|
||
|
configuration file as /proc/config.gz. The kernel sources can be
|
||
|
configured based on /proc/config.gz with ``make cloneconfig''.
|
||
|
|
||
|
|
||
|
HOW TO CONFIGURE THE KERNEL SOURCES
|
||
|
|
||
|
Before a binary kernel is built or an additional loadable module
|
||
|
for an existing kernel is created, the kernel must be configured.
|
||
|
|
||
|
In order for a loadable module to work with an existing kernel, it must
|
||
|
be created with a configuration that is identical to the kernel's
|
||
|
configuration, or at least very close to that. Each configuration is
|
||
|
contained in a single file. The kernel-source package contains
|
||
|
configurations for all standard SUSE kernel variants, so for building
|
||
|
only external kernel modules it is not necessary to configure the kernel
|
||
|
sources.
|
||
|
|
||
|
Configuring the kernel sources for a specific configuration is
|
||
|
straightfoward:
|
||
|
|
||
|
- Locate the configuration file you want to use. (See WHERE TO FIND
|
||
|
CONFIGURATION FILES above).
|
||
|
|
||
|
- Copy the configuration to the file .config in the kernel source
|
||
|
tree. The kernel-source package installs its source tree in
|
||
|
/usr/src/linux.
|
||
|
|
||
|
- Run the following commands in sequence to apply the configuration,
|
||
|
generate version information files, etc.:
|
||
|
|
||
|
make clean
|
||
|
make oldconfig
|
||
|
|
||
|
Alternatively to ``make oldconfig'', you can also use ``make
|
||
|
menuconfig'' for a text menu oriented user interface. If the kernel
|
||
|
sources do not match the configuration file exactly, ``make
|
||
|
oldconfig'' will prompt for settings that are undefined.
|
||
|
|
||
|
For configuring the kernel to match the running kernel, there is a
|
||
|
shortcut ``make cloneconfig'' that expands the file /proc/config.gz
|
||
|
into .config, and then runs ``make oldconfig''.
|
||
|
|
||
|
|
||
|
MODULE LOAD PATHS
|
||
|
|
||
|
Modules that belong to a specific kernel release are installed in
|
||
|
/lib/modules/2.6.5-99-smp and similar. Note that this path contains the
|
||
|
kernel package release number. Modules from KMPs must be installed
|
||
|
below /lib/modules/2.6.5-99-smp/updates/ and similar: modules below
|
||
|
updates/ have priority over other modules.
|
||
|
|
||
|
When KMPs contain modules that are compatible between multiple installed
|
||
|
kernels, symlinks are used to make those modules available to those
|
||
|
compatible kernels like this:
|
||
|
|
||
|
/lib/modules/2.6.16-100-smp/weak-updates/foo.ko ->
|
||
|
/lib/modules/2.6.16-99-smp/updates/foo.ko
|
||
|
|
||
|
Modules in the weak-updates directory have lower priority than modules
|
||
|
in /lib/modules/2.6.16-100-smp/updates/, and higher priority than other
|
||
|
modules in /lib/modules/2.6.16-100-smp.
|
||
|
|
||
|
|
||
|
REFERENCES
|
||
|
|
||
|
General
|
||
|
|
||
|
Documentation in the kernel source tree.
|
||
|
|
||
|
Linux Documentation Project, http://www.tldp.org/
|
||
|
|
||
|
Linux Weekly News, http://lwn.net
|
||
|
|
||
|
Rusty's Remarkably Unreliable Guides (Kernel Hacking
|
||
|
and Kernel Locking guides),
|
||
|
http://www.netfilter.org/unreliable-guides/
|
||
|
|
||
|
Kernel newbies, http://www.kernelnewbies.org/
|
||
|
|
||
|
|
||
|
Loadable Kernel Modules
|
||
|
|
||
|
Peter Jay Salzman and Ori Pomerantz: Linux Kernel Module
|
||
|
Programming Guide, Version 2.4, April 2003,
|
||
|
http://www.tldp.org/guides.html
|
||
|
|
||
|
|
||
|
Kernel Module Packages
|
||
|
|
||
|
Andreas Gruenbacher: Kernel Module Packages Manual.
|
||
|
Versions for CODE9 (SLES9, SUSE LINUX 10.0) and CODE10
|
||
|
(SUSE Linux 10.1, SLES10),
|
||
|
http://www.suse.de/~agruen/KMPM/
|