Official openSUSE Kernel 2.6.22.12-0.1 Readme

From openSUSE

sgt-d@wenix:/> ls -l /usr/src/linux-2.6.22.12-0.1/README.SUSE

lrwxrwxrwx 1 root root 50 2007-11-08 15:09 /usr/src/linux-2.6.22.12-0.1/README.SUSE -> ../../share/doc/packages/kernel-source/README.SUSE

Contents of:

/usr/share/doc/packages/kernel-source/README.SUSE

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/


Unofficial contribution

The kernel-source-xxx.i586.rpm produced by Suse seems to include several flavors, but when one tries to rpmbuild it from kernel-source-xxx.src.rpm only flavor "default" is built. Somebody should document how "SOURCES/extra-symbols" file is used since it might be related.

In the meantime, to generate kernel-source for a different flavor (in that case, RT) here is what i did. This is certainly not the correct way of building this rpm.

1) copy kernel-source.spec to kernel-rt-source.spec

2) edit file and change "Name:" to "kernel-rt-source"

3) locate the line below comment "Apply the patches needed for this architecture" and change it to read:

  %_sourcedir/guards rt RT %symbols < %_sourcedir/series.conf \

4) rpmbuild -bb kernel-rt-source.spec

note that it will conflict with the original kernel-source rpm contents.