Viele Kernelversionen mit Linux

   
Das Problem
Der Kernel bekommt eine Extraversion
Das Image installieren...
...und in die lilo.conf eintragen
Und was ist mit der /etc/modules.conf?
     Vorbereitungen
     modules.conf wechsle dich
Wenn alles klappt
Noch einige Anmerkungen
Fussnoten
Häh? und Diverses


 
    Das Problem Inhalt   

Will man mehrere Kernel parallel verwenden bzw. testen, so beginnt man wohl damit, zuerst die Kernelimages unterschiedlich zu benennen und in der /etc/lilo.conf die Images mit diesen Namen einzutragen, also in etwa so:


Eine "normale" /lilo.conf (einfach aber doch idealisiert)
# LILO Konfigurations-Datei
# Start LILO global Section
[..]
message=/boot/greetings
#### End LILO global Section
 
#### Current default Kernel ####
  image = /boot/vmlinuz
  root  = /dev/hda5
  label = l
 
#### Test-Kernel ####
  image = /boot/bzImage
  root  = /dev/hda5
  label = t

#### Original-Kernel ####
  image = /boot/vmlinux.org
  root  = /dev/hda5
  label = o

#### Windows ####
other = /dev/hda1
  label = w
     

Was passiert aber, wenn die zum jeweiligen Kernel passende System.map nicht zu den anderen Kernels passt?

Was ist, wenn manche Module für einen Kernel deaktiviert, für einen anderen aber aktiviert werden müssen?

Wie kann man also die Kernelimages, die System.map, die /etc/conf.modules (bzw. die /etc/modules.conf) und natürlich die Module alle mit Versionen versehen, so daß die jeweils zueinander passenden verwendet werden?

Ich habe mit der Zeit eine Lösung zusammentragen können, die ich im Folgenden anhand meiner Konfiguration beschreiben will und die auf meiner "Kiste" mit verschiedenen 2.2.14er und mehreren 2.2.15er Kernels funktioniert.

Ich werde daher in allen Beispielen von einer Kernel-Version 2.2.15 ausgehen, welche natürlich meist angepasst werden muß.

Ich folge dabei in der Beschreibung meinem üblichen Vorgehen, aber natürlich kann man z.B. während das "make bzImage" läuft, schon in aller Ruhe die /etc/lilo.conf anpassen...

 
    Der Kernel bekommt eine Extraversion Inhalt   

Um mehrere unterschiedlich konfigurierte Kernel zu verwenden, nutzen wir die vorhandene Möglichkeit (zumindest seit den 2.2.x Kernels) eine EXTRAVERSION definieren zu können und verpassen so dem Kernel eine weitere Versionsnummer [1].

Dazu wechseln wir ins Verzeichnis /usr/src/linux und editieren mit unserem Lieblingseditor das sich dort befindliche Makefile:


/usr/src/linux/Makefile (original)
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 15
EXTRAVERSION =
[...]

/usr/src/linux/Makefile (neu)
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 15
EXTRAVERSION = -6
[...]

Obiges Beispiel ergibt z.B. die Kernelversion 2.2.15-6 (u.a. bei jedem Aufruf von "uname -r", was später von Bedeutung sein wird), der bei EXTRAVERSION definierte String wird also direkt, ohne Punkt oder Bindestrich an die "normale" Kernelversion, die durch VERSION.PATCHLEVEL.SUBLEVEL definiert wird, angehängt. Natürlich können dabei auch Buchstaben statt einer "Bindestrich-Zahl"-Kombination verwendet werden, also z.B. EXTRAVERSION = b, was dann 2.2.15b ergeben würde.

Nachdem wie also dem Kernel eine "Extraversion" verpasst haben, folgt die Kernelkonfiguration mit dem üblichen "/usr/src/linux # make config" oder "/usr/src/linux # make menuconfig" oder "/usr/src/linux # make xconfig" und schon bei dieser Konfiguration erscheint die "Extraversion" im Fenstertitel. Nach dem Abspeichern der Konfiguration folgt dann der übliche Kompiliervorgang, z.B. mit

/usr/src/linux # time make dep clean bzImage modules modules_install 2>&1 | tee make.out

Wenn man anschließend in /lib/modules schaut, sieht man hoffentlich, daß die Module (bei obigem Beispiel) wie gewünscht in /lib/modules/2.2.15-6 gelandet sind.

 
    Das Image installieren... Inhalt   

Nun kommt der mit entscheidende Schritt. Das neue Image wird ins Bootverzeichnis /boot/ kopiert und bekommt dabei einen neuen Namen mit der Endung "-`uname -r`". Ich verwende hier das Schema: bzImage-`uname -r`, also um bei obiger Beispielversion zu bleiben:

/usr/src/linux # cp /usr/src/linux/arch/i386/boot/bzImage /boot/bzImage-2.2.15-6

Eine andere Möglichkeit wäre z.B. vmlinuz-`uname -r`...

Auch die neue System.map muss kopiert werden:

/usr/src/linux # cp /usr/src/linux/System.map /boot/System.map-2.2.15-6

Achtung!   Es darf keine Datei /boot/System.map geben, denn dann werden die mit einer Version versehenen System.map-Dateien ignoriert.

Dazu muss(?) gegebenenfalls das bisherige Kernelimage und dessen System.map ebenfalls mit der passenden -`uname -r` Endung versehen werden.

Danach sollte also ein ls -1 /boot in etwa folgendes ergeben:

/usr/src/linux # ls -1 /boot
System.map-2.2.14f
System.map-2.2.15-2
System.map-2.2.15-6
System.map-2.3.99-pre6-1
System.map-2.4.0-test1
System.map-2.4.0-test1-1
System.map-2.4.0-test4-1
boot.0300
boot.0303
boot.0305
bzImage-2.2.15-2
bzImage-2.2.15-6
bzImage-2.3.99-pre6-1
bzImage-2.4.0-test1
bzImage-2.4.0-test1-1
bzImage-2.4.0-test4-1
chain.b
greetings
map
os2_d.b
susedsk
testnew
vmlinuz-2.2.14f

Es macht scheinbar nichts aus, wenn noch diverse andere Kernel in /boot/ herumfahren (z.B. ein vmlinuz), aber ich habe keine Ahnung welche System.map ein solches Image dann verwenden wuerde, da ich die Images ohne eine passende System.map-`uname -r` noch nie gebootet habe...
Sachdienliche Hinweise hierzu sind willkommen unter: david@dhaller.de

 
    ...und in die lilo.conf eintragen Inhalt   

Das Image wird dann wie gewohnt in /etc/lilo.conf eingetragen, also z.B.:


/etc/lilo.conf
[...]
#### Test-Kernel 2.2.15-6 ####
  image = /boot/bzImage-2.2.15-6
  root  = /dev/hda5
  label = linux-2-2-15-6
  alias = 5-6
[...]

Beim label= kann man seiner Phantasie natürlich relativ freien Lauf lassen, ich denke aber, das ein an die Kernelversion angelehntes Schema Sinn macht (wie z.B. linux-2-215-6 für obiges Beispiel eines Kernels 2.2.15-6. Wie man die label und aliase am sinnvollsten nennt

Anmerken möchte ich noch, daß man (bei lilo 21 und lilo 21.4.2 maximal 19 Images in der /etc/lilo.conf eintragen kann [2].

Es sei auch allen Lesern dieses Textes die Lektüre von man 8 lilo (und auch von man -L en 8 lilo), man 5 lilo.conf (und man -L en 5 lilo.conf), und ganz besonders auch von /usr[/share]/doc[/packages]/lilo/* empfohlen.

Ach ja, in die Datei /boot/greetings sollte man den neuen Kernel auch eintragen ;-)

Wie üblich ist anschließend ein "# /sbin/lilo" fällig.

 
    Und was ist mit der /etc/modules.conf? Inhalt   


  Vorbereitungen

Auch die /etc/modules.conf bzw. /etc/conf.modules läßt sich versionieren! Ich beziehe mich jetzt einfach mal auf den Fall einer /etc/modules.conf.
Ich verwende mit Absicht keine /etc/conf.modules, denn dieser Dateiname ist "veraltet":


man -L en 5 modules.conf
[..]
ALTERNATIVE CONFIGURATION FILE
       For historical  reasons,  if  /etc/modules.conf  does  not
       exist, modutils will read /etc/conf.modules instead.  How­
       ever the use of this historical name is deprecated and  it
       should be replaced with /etc/modules.conf.
[..]

Zuerst erstellt man eine Kopie der bisherigen /etc/modules.conf bzw. /etc/conf.modules, z.B. als /etc/conf.modules.org und dann eine weitere Kopie namens /etc/modules.conf-`uname -r`, also z.B. /etc/modules.conf-2.2.15-6. Letztere wird dann an den entsprechenden Kernel, also z.B. 2.2.15-6 angepasst.


  modules.conf wechsle dich

Nun ruft man mit seinem Lieblingseditor die /etc/modules.conf auf und schreibt (nur) das folgende hinein:


/etc/modules.conf
# /etc/modules.conf - With Versions
# (c)2000 David Haller, david@dhaller.de

if -f /etc/modules.conf-`uname -r`
  include /etc/modules.conf-`uname -r`
else
  include /etc/modules.conf.org
endif
 
    Wenn alles klappt Inhalt   
 
    Noch einige Anmerkungen Inhalt   

Man kann natürlich ein anderes Schema der Kernel-Namen verwenden, eine /etc/conf.modules statt einer /etc/modules.conf verwenden, und wahrscheinlich (ich habe es bisher nicht getestet) auch die allen modules.conf-`uname -r` 's gemeinsamen Zeilen in der /etc/modules.conf unterbringen... Dies sei aber der Experimentierfreude des geneigten Lesers überlassen.

 
    Fussnoten Inhalt   

[1] Ist EXTRAVERSION schon definiert, wie zum Beispiel bei den 2.4.0-testN Kerneln, dann kann man "seine" Version einfach dranhängen, also z.B. "EXTRAVERSION = test4-1" statt "EXTRAVERSION = test4".
[2] Wieviele Images konkret eingetragen werden können, lässt sich mit folgendem Script herausfinden, nachdem die Dateien common.h und lilo.h aus dem Quelltext-Paket des verwendeten Lilo nach /tmp kopiert oder verlinkt wurden:
/tmp/showmaximages.sh
#!/bin/sh
if ! gcc -v 2>/dev/null
then echo "Can't find gcc" > /dev/stderr; exit 1; fi
cat <<EOF > /tmp/showmaximages.c
#include <stdio.h>
#include "common.h"
int main() {
  fprintf(stdout,"Maximum number of images "
                 "in /etc/lilo.conf: %i\n",MAX_IMAGES);
  return 0;
}
EOF

gcc -Wall -o /tmp/showmaximages /tmp/showmaximages.c \
  || exit 1
/tmp/showmaximages
rm /tmp/showmaximages /tmp/showmaximages.c
 
    Häh? und Diverses Inhalt   

Noch Fragen? Verbesserungen? Oder Vorschläge?

Dann bitte ich um eine Mail an mich. David Haller David@dhaller.de


Letzte Änderung: 2001/02/07, webmaster@dhaller.de