Eigenen Kernel erstellen: Unterschied zwischen den Versionen

Aus wiki.archlinux.de
Robert (Diskussion | Beiträge)
K pacman -Sy angepasst, siehe https://bbs.archlinux.de/viewtopic.php?id=17347
Zeile 27: Zeile 27:
== Vorarbeiten ==
== Vorarbeiten ==
Das ArchBuildSystem(ABS) sollte eingerichtet sein und synchronisiert.
Das ArchBuildSystem(ABS) sollte eingerichtet sein und synchronisiert.
  pacman -Sy cvsup wget abs
  pacman -S cvsup wget abs
Weitere Informationen zum ABS siehe [[Abs|hier]].
Weitere Informationen zum ABS siehe [[Abs|hier]].



Version vom 5. September 2010, 11:59 Uhr

Anleitung zum Bau eines eigenen Kernels. Gedacht als „Reserve-Kernel“ sowie auch um eigene Änderungen zum Standard-Kernel einzubinden. Dieser Kernel soll nicht einen bereits installierten Arch-Kernel überschreiben, oder von diesem überschrieben werden.

Vorgestellt werden Wege ohne und mit dem ArchLinux-Paketmanagement.
Es bietet sich an, diesen Beitrag einmal komplett durchzulesen. Wenn man das Prinzip einmal verstanden, und ein paar Gehversuche hinter sich hat, dann ist das Thema recht einfach. Nur: Am Anfang haben die Götter den Schweiß gesetzt ;-)

  1. eigener Kernel ohne das Paketmanagement („the old way“)
    Vorteile
    • Man kommt schnell zum eigenen Kernel, weniger Vorarbeiten
    • Extrem gut an die eigene Hardware anpassbar
    Nachteile
    • Konfiguration erfordert etwas Erfahrung
    • Nachträglich schwerer wartbar
  2. den ArchLinux-Standardkernel als eigener Kernel anpassen.
    Vorteile
    • Nachträglich gut wartbar
    • Hat alle Treiber und Patches, die der Arch-Kernel auch hat
    • Die schnellste Methode um an einen lauffähigen Kernel zu kommen
    Nachteile
    • Erfordert einiges an Vorarbeiten
  3. eigener Kernel mit dem Paketmanagement ("the arch way")
    Vorteile
    • Extrem gut an die eigene Hardware anpassbar
    • Nachträglich gut wartbar
    Nachteile
    • Erfordert einiges an Vorarbeiten

Vorarbeiten

Das ArchBuildSystem(ABS) sollte eingerichtet sein und synchronisiert.

pacman -S cvsup wget abs

Weitere Informationen zum ABS siehe hier.

Kernel "the old way"

Diese Methode zeigt, wie ein eigener Kernel auf "althergebrachte" Art gebaut und installiert werden kann. Also ohne diesen mit pacman installieren bzw. deinstallieren zu können. Dieser Kernel enthält kein Initrd-Image (gelogen...).

Kernel-Sourcecode besorgen

Kernelsourcen von http://www.kernel.org besorgen.
Hier exemplarisch für den 2.6.22.

Auspacken

cp $downloaddir/linux-2.6.22.tar.bz2 /usr/src/
cd /usr/src
tar xvjf linux-2.6.22.tar.bz2
cd /usr/src/linux-2.6.22

Kernel konfigurieren

Hier wird der Kernel an die eigene Hardware angepasst. Das ist nur etwas für erfahrene User (oder welche, die lernen wollen). Es sollte unbedingt die README im Kernel-Source-Verzeichnis gelesen werden.

Zwei Wege werden vorgestellt: Die Config selbst erstellen (ggf. unter Verwendung einer Vorlage eines anderen Kernels) und die, bei der einfach die config des Arch-Standard-Kernels genutzt wird.

1. Eigene Konfig
Da keine initrd erstellt wird müssen alle zum Booten benötigten Treiber (Harddisk-Controller, Root-Dateisystem) fest in den Kernel kompiliert werden. Also nicht als ladbare Module! Den Kernel konfigurieren mit einem der Front-Ends:

  • make menuconfig
  • make xconfig
  • make gconfig

Dies erstellt uns die Konfiguration .config im Kernelsource-Verzeichnis.

2. Konfig des Arch-Standard-Kernels als Grundlage nehmen
Ausgang sei hier der Arch-Kernel 2.6.22. Fallstrick: Diese Config basiert auch auf den im ArchLinux-Kernel installierten bzw. hinzugefügten Patches. Die Weiterverwendung dieser Config kann also gutgehen, muss aber nicht.

cp /boot/kconfig26 /usr/src/linux-2.6.22/.config
make oldconfig

Sollte die Datei /boot/kconfig26 nicht vorhanden sein, mit zcat die Config des gerade laufenden Kernels auslesen:

zcat /proc/config.gz > /usr/src/linux-2.6.22/.config
make oldconfig

Die Datei .config mit einem Editor öffnen. Folgendes ändern:

#
# General setup
#
CONFIG_LOCALVERSION="-ARCH"
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y

Hier CONFIG_LOCALVERSION ändern zu ="".
Was dieser Parameter bewirkt siehe Welche Parameter bewirken Namensänderungen?.

Kompilieren

Der Kernel und die Module werden kompiliert mit:

 make

Kernel und Module installieren

Die Verzeichnisse gelten sowohl für x86, als auch x86_64 Systeme.

Das Kernel-Image wird so nach /boot installiert:

 cp arch/x86/boot/bzImage /boot/vmlinuz
 cp System.map /boot/
 cp .config /boot/kconfig

Die Module installieren:

 make modules_install

(Doch) eine initrd erzeugen

Achtung: dieser Schritt wird nur benötigt, wenn oben die ArchLinux-Config als Vorlage genommen wurde (Konfig des Arch-Standard-Kernels als Grundlage nehmen). Bei der ArchLinux-Config sind die meisten Treiber als ladbare Module konfiguriert, deshalb muss zwingend auch für diesen Kernel eine initrd erstellt werden.

 mkinitcpio -k 2.6.22 -g /boot/initrd.img

Weiterhin muss im nächsten Abschnitt (Boot-Loader) diese erstelle initrd in den Grub-Eintrag hinzugefügt werden.

Boot-Loader (Grub) anpassen

Die Datei /boot/grub/menu.list um folgenden Eintrag erweitern. Die Einträge zu root und root= analog der eigenen menu.list anpassen!

# Eigener Kernel
title  Eigener Kernel
root   (hd0,0)
kernel /vmlinuz root=/dev/sda3 ro

oder wenn oben eine initrd erstellt wurde:

# Eigener Kernel
title  Eigener Kernel
root   (hd0,0)
kernel /vmlinuz root=/dev/sda3 ro
initrd /initrd.img

Was ist alles wo installiert, wie lösche ich den Kernel wieder? Ziel war, dass dieser Kernel nicht mit einem Arch-Kernel kollidiert. Folgende Einzel-Dateien bzw. Verzeichnisse wurden installiert und können problemlos wieder von Hand gelöscht werden:

  • /boot/vmlinuz (der Kernel)
  • /boot/System.map (Debug/Modul-Symboltabelle)
  • /boot/initrd.img (wenn ein initrd image erstellt wurde)
  • /boot/kconfig (Die Kernel-Konfig-Datei als Vorlage für spätere Änderungen)
  • /lib/modules/2.6.22 (das Verzeichnis mit den ladbaren Modulen)
  • /usr/src/linux-2.6.22 (die Kernel-Sources)

Der Kernel meldet sich so:

[gbdev@archdev ~]$ uname -r
2.6.22

Den ArchLinux Standard-Kernel als eigener, zusätzlicher Kernel

Unser Kernel soll ein eigenständiger Kernel sein, mit dem Namen 2.6.22-custom.

ABS aktualisieren

 abs

Kernel-Steuerdateien in eigenes Verzeichnis kopieren

 cp -R /var/abs/core/kernel26 /var/abs/local/
 cd /var/abs/local
 mv kernel26 kernel26custom
 cd kernel26custom

Dateien an eigenen Namen anpassen

 mv mkinitcpio-kernel26.conf mkinitcpio-kernel26custom.conf
 mv kernel26.install kernel26custom.install
 mv kernel26.preset kernel26custom.preset

Jetzt müssen einige Dateien editiert werden. Ich dokumentiere diese Änderungen anhand von diff-Vergleichen. Die Zeilen mit @@ enthalten Zeilen/Spaltennummern zum schnelleren Auffinden der Textstellen. Textänderungen sind so dokumentiert, dass die Zeile mit dem Minus(-) zur folgenden Zeile mit dem Plus(+) abgeändert werden muss. Wenn eine Zeile nur ein Plus hat (wie _ownver), dann ist diese Zeile an dieser Stelle hinzuzufügen.
Achtung: Das sind nicht die vollständigen Dateien! Hier sind lediglich die Textstellen aufgeführt bei denen Änderungen erforderlich sind. Also nicht einfach aus dem Block rauskopieren.

PKGBUILD
Als erstes in dieser Datei den gesamten Block md5sum=(xyz) löschen. Das sind Prüfsummen um die Integrität der Dateien beim Bauen zu überprüfen. Da wir einige Dateien ändern müssen wir diese Prüfsummen später neu berechnen lassen.

@@ -1,15 +1,16 @@
 # $Id: PKGBUILD,v 1.247 2007/08/15 21:08:35 thomas Exp $
 # Maintainer: Tobias Powalowski <tpowa@archlinux.org>
 # Maintainer: Thomas Baechler <thomas@archlinux.org>
-pkgname=kernel26
+pkgname=kernel26custom
 _basekernel=2.6.22
 pkgver=2.6.22.3
+_ownver=custom
 pkgrel=1
-pkgdesc="The Linux Kernel and modules"
+pkgdesc="The Linux Kernel and modules (Custom)"
 arch=(i686 x86_64)
 license=('GPL2')
 url="http://www.kernel.org"
-backup=('boot/kconfig26' etc/mkinitcpio.d/${pkgname}.preset)
+backup=('boot/kconfig26${_ownver}' etc/mkinitcpio.d/${pkgname}.preset)
 depends=('module-init-tools' 'mkinitcpio>=0.5.15')
 # pwc, ieee80211 and hostap-driver26 modules are included in kernel26 now
 # nforce package support was abandoned by nvidia, kernel modules should cover everything now.
@@ -18,7 +19,7 @@
           'alsa-driver' 'ieee80211' 'hostap-driver26'
           'pwc' 'nforce' 'squashfs' 'unionfs' 'ivtv'
          'zd1211' 'kvm-modules')
-install=kernel26.install
+install=kernel26custom.install
 source=(ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_basekernel.tar.bz2
         #http://www.kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.22-rc7.bz2
        #http://www.kernel.org/pub/linux/kernel/v2.6/snapshots/patch-2.6.22-rc7-git2.bz2
@@ -27,7 +28,7 @@
         logo_linux_clut224.ppm
         logo_linux_mono.pbm
         logo_linux_vga16.ppm
-        kernel26.preset
+        kernel26custom.preset
         mkinitcpio-$pkgname.conf
         acpi-dsdt-initrd-v0.8.4-2.6.21.patch
         toshiba-bluetooth.patch
@@ -108,15 +109,15 @@
   make bzImage modules || return 1
   mkdir -p $startdir/pkg/{lib/modules,boot}
   make INSTALL_MOD_PATH=$startdir/pkg modules_install || return 1
-  cp System.map $startdir/pkg/boot/System.map26
-  cp arch/$KARCH/boot/bzImage $startdir/pkg/boot/vmlinuz26
+  cp System.map $startdir/pkg/boot/System.map26${_ownver}
+  cp arch/$KARCH/boot/bzImage $startdir/pkg/boot/vmlinuz26${_ownver}
   install -D -m644 Makefile \
     $startdir/pkg/usr/src/linux-${_kernver}/Makefile
   install -D -m644 kernel/Makefile \
     $startdir/pkg/usr/src/linux-${_kernver}/kernel/Makefile
   install -D -m644 .config \
     $startdir/pkg/usr/src/linux-${_kernver}/.config
-  install -D -m644 .config $startdir/pkg/boot/kconfig26
+  install -D -m644 .config $startdir/pkg/boot/kconfig26${_ownver}
   mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/include

   mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/arch/$KARCH/kernel
@@ -185,6 +186,6 @@
   install -m644 -D $startdir/src/${pkgname}.preset $startdir/pkg/etc/mkinitcpio.d/${pkgname}.preset || return 1
   install -m644 -D $startdir/src/mkinitcpio-$pkgname.conf $startdir/pkg/etc/mkinitcpio.d/$pkgname-fallback.conf || return 1
   # set correct depmod command for install
-  sed -i -e "s/KERNEL_VERSION=.*/KERNEL_VERSION=${_kernver}/g" $startdir/kernel26.install
+  sed -i -e "s/KERNEL_VERSION=.*/KERNEL_VERSION=${_kernver}/g" $startdir/kernel26${_ownver}.install
   echo -e "# DO NOT EDIT THIS FILE\nALL_kver='${_kernver}'" > ${startdir}/pkg/etc/mkinitcpio.d/${pkgname}.kver
 }

kernel26custom.preset

@@ -1,14 +1,14 @@
-# mkinitcpio preset file for kernel26
+# mkinitcpio preset file for kernel26custom

 ########################################
 # DO NEVER EDIT THIS LINE:
-source /etc/mkinitcpio.d/kernel26.kver
+source /etc/mkinitcpio.d/kernel26custom.kver
 ########################################

 PRESETS=('default' 'fallback')

 default_config="/etc/mkinitcpio.conf"
-default_image="/boot/kernel26.img"
+default_image="/boot/kernel26custom.img"

-fallback_config="/etc/mkinitcpio.d/kernel26-fallback.conf"
-fallback_image="/boot/kernel26-fallback.img"
+fallback_config="/etc/mkinitcpio.d/kernel26custom-fallback.conf"
+fallback_image="/boot/kernel26custom-fallback.img"

kernel26custom.install

@@ -1,7 +1,8 @@
 # arg 1:  the new package version
 # arg 2:  the old package version

-KERNEL_VERSION=2.6.22-ARCH
+KERNEL_VERSION=2.6.22-custom
+_ownver=custom

 post_install () {
   # updating module dependencies
@@ -17,11 +18,11 @@
   echo ""
   echo ">>> Generating initial ramdisk, using mkinitcpio.  Please wait..."
 if [ "`vercmp $2 2.6.19`" -lt 0 ]; then
-  /sbin/mkinitcpio -p kernel26 -m "ATTENTION:\nIf you get a kernel panic below
+  /sbin/mkinitcpio -p kernel26${_ownver} -m "ATTENTION:\nIf you get a kernel panic below
 and are using an Intel chipset, append 'earlymodules=piix' to the
 kernel commandline"
 else
-  /sbin/mkinitcpio -p kernel26
+  /sbin/mkinitcpio -p kernel26${_ownver}
 fi
 if [ "`vercmp $2 2.6.21`" -lt 0 ]; then
   echo ""
@@ -136,11 +137,11 @@
   echo ""
   echo ">>> Generating initial ramdisk, using mkinitcpio.  Please wait..."
 if [ "`vercmp $2 2.6.19`" -lt 0 ]; then
-  /sbin/mkinitcpio -p kernel26 -m "ATTENTION:\nIf you get a kernel panic below
+  /sbin/mkinitcpio -p kernel26${_ownver} -m "ATTENTION:\nIf you get a kernel panic below
 and are using an Intel chipset, append 'earlymodules=piix' to the
 kernel commandline"
 else
-  /sbin/mkinitcpio -p kernel26
+  /sbin/mkinitcpio -p kernel26${_ownver}
 fi
 if [ "`vercmp $2 2.6.21`" -lt 0 ]; then
   echo ""

config

 #
 # General setup
 #
-CONFIG_LOCALVERSION="-ARCH"
+CONFIG_LOCALVERSION="-custom"
 CONFIG_LOCALVERSION_AUTO=y

config.x86_64

 #
 # General setup
 #
-CONFIG_LOCALVERSION="-ARCH"
+CONFIG_LOCALVERSION="-custom"
 CONFIG_LOCALVERSION_AUTO=y

Das war's jetzt mit dem Editieren, Ehrenwort ;-)

Jetzt laden wir den Kernelsource und die Patches aus dem Internet und lassen uns Prüfsummen generieren. Dank makepkg wird uns das ganz einfach gemacht.

 makepkg -g >> PKGBUILD

Nun können wir endlich den Computer etwas arbeiten lassen und uns einen Kaffee/Tee gönnen

 makepkg

Wenn das Kompilieren/Bauen fertig ist sehen wir am Ende folgende Meldungen:

 ==> Compressing package...
 ==> Finished making: kernel26custom  (Wed Aug 15 08:59:23 CEST 2007)

In unserem aktuellen Verzeichnis finden wir jetzt unser Kernel-Paket

 kernel26custom-2.6.22.3-1-i686.pkg.tar.gz

Dieses Paket werden wir jetzt mit pacman installieren. Bei der Installation verhält es sich so, wie wir es von "normalen" Kernel-Installationen gewohnt sind.

 pacman -U kernel26custom-2.6.22.3-1-i686.pkg.tar.gz

Jetzt fehlt lediglich noch der Eintrag im Bootloader (Grub) für unseren neuen Kernel. Die Einträge zu root und root= analog der eigenen menu.list anpassen!

# Eigener Kernel 2
title  Eigener Kernel (custom)
root   (hd0,0)
kernel /vmlinuz26custom root=/dev/sda3 ro
initrd /kernel26custom.img

# (1) Arch Linux
title  Eigener Kernel (custom) Fallback
root   (hd0,0)
kernel /vmlinuz26custom root=/dev/sda3 ro
initrd /kernel26custom-fallback.img

Kernel "the arch way"

Ziel ist es, einen eigenen Kernel basierend auf den Sourcen von http://www.kernel.org zu bauen, diesmal aber als Arch-Paket.
Dieses Paket wird über pacman installiert und kann so auch einfach aktualisiert oder entfernt werden.

Diese Methode eignet sich wunderbar um z.B. auch langfristig seinen "eigenen" Kernel mit entsprechenden Konfigurationsanpassungen oder Patches zu pflegen.

Aber auch als Reserve- / Rettungs-Kernel ist diese Methode geeignet, da sich der Rettungskernel wenn nötig sehr einfach an aktuelle Kernel-Quellen anpassen lässt.

Dafür werden wir u.a. eine PKGBUILD Steuerdatei erstellen, die sich prinzipiell an der orientiert, die auch zum Bauen des Arch-Standardkernels verwendet wird.
Der so erstellte Kernel soll einen eigenen Namen bekommen. Für dieses Beispiel anhand des 2.6.22 Kernels soll dieser nacher 2.6.22-custom heißen.

Zum Bauen erstellen wir ein eigenes Verzeichnis, hier als Beispiel im Home-Verzeichnis.

 mkdir ~/kernel26-custom
 cd ~/kernel26-custom

Jetzt erstellen wir uns die notwendigen Steuerdateien um das Paket mit makepkg bauen zu können. Im Gegensatz zur Methode 2 (Arch-Standard-Kernel anpassen) sind nachfolgend diese Dateien komplett aufgeführt. Diese müssen also lediglich aus dem Wiki rauskopiert werden.

PKGBUILD

# Contributor: Your name

pkgname=kernel26custom
basekernel=2.6.22
pkgver=2.6.22
_ownver=custom
pkgrel=1
pkgdesc="The Linux Kernel and modules  (Eigener Kernel)"
url=""
license="GPL"
arch=(i686 x86_64)
depends=('module-init-tools' 'mkinitcpio>=0.5.15')
install=${pkgname}.install
source=(ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${basekernel}.tar.bz2 \
        ${pkgname}.preset \
        ${pkgname}-fallback.conf \
        )
build() {
  [ "${CARCH}" = "i686" ]   && KARCH=i386
  [ "${CARCH}" = "x86_64" ] && KARCH=x86_64

  cd $startdir/src/linux-${basekernel}

  # Enable this to reuse your old kernel config.
  # The config file must sit in the directory where the PKGBUILD is.
  # Also enable: make oldconfig in the section below.
  cp $startdir/config ./.config

  # load configuration
  #yes "" | make config
  make oldconfig || return 1
  make menuconfig || return 1
  #make gconfig || return 1
  . ./.config
  _kernver="${basekernel}${CONFIG_LOCALVERSION}"

  # build!
  make bzImage modules || return 1
  mkdir -p $startdir/pkg/{lib/modules,boot}
  make INSTALL_MOD_PATH=$startdir/pkg modules_install || return 1
  cp System.map $startdir/pkg/boot/System.map26${_ownver}
  cp arch/$KARCH/boot/bzImage $startdir/pkg/boot/vmlinuz26${_ownver}
  install -D -m644 Makefile \
    $startdir/pkg/usr/src/linux-${_kernver}/Makefile
  install -D -m644 kernel/Makefile \
    $startdir/pkg/usr/src/linux-${_kernver}/kernel/Makefile
  install -D -m644 .config \
    $startdir/pkg/usr/src/linux-${_kernver}/.config
  install -D -m644 .config $startdir/pkg/boot/kconfig26${_ownver}
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/include

  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/arch/$KARCH/kernel
  for i in acpi asm-generic asm-$KARCH config linux math-emu media net pcmcia scsi sound video; do
    cp -a include/$i $startdir/pkg/usr/src/linux-${_kernver}/include/
  done

 # copy files necessary for later builds, like nvidia and vmware
  cp Module.symvers $startdir/pkg/usr/src/linux-${_kernver}
  cp -a scripts $startdir/pkg/usr/src/linux-${_kernver}
  # fix permissions on scripts dir
  chmod og-w -R $startdir/pkg/usr/src/linux-${_kernver}/scripts
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/.tmp_versions

  cp arch/$KARCH/Makefile $startdir/pkg/usr/src/linux-${_kernver}/arch/$KARCH/
  if [ "$CARCH" = "i686" ]; then
    cp arch/$KARCH/Makefile.cpu $startdir/pkg/usr/src/linux-${_kernver}/arch/$KARCH/
  fi
  cp arch/$KARCH/kernel/asm-offsets.s $startdir/pkg/usr/src/linux-${_kernver}/arch/$KARCH/kernel/

  # add headers for lirc package
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/drivers/media/video
  cp drivers/media/video/*.h  $startdir/pkg/usr/src/linux-${_kernver}/drivers/media/video/
  for i in bt8xx cpia2 cx25840 cx88 em28xx et61x251 pwc saa7134 sn9c102 usbvideo zc0301; do
   mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/drivers/media/video/$i
   cp -a drivers/media/video/$i/*.h $startdir/pkg/usr/src/linux-${_kernver}/drivers/media/video/$i
  done
  # add dm headers
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/drivers/md
  cp drivers/md/*.h  $startdir/pkg/usr/src/linux-${_kernver}/drivers/md
  # add inotify.h
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/include/linux
  cp include/linux/inotify.h $startdir/pkg/usr/src/linux-${_kernver}/include/linux/
  # add CLUSTERIP file for iptables
  mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/net/ipv4/netfilter/
  cp net/ipv4/netfilter/ipt_CLUSTERIP.c $startdir/pkg/usr/src/linux-${_kernver}/net/ipv4/netfilter/
  # copy in Kconfig files
  for i in `find . -name "Kconfig*"`; do
    mkdir -p $startdir/pkg/usr/src/linux-${_kernver}/`echo $i | sed 's|/Kconfig.*||'`
    cp $i $startdir/pkg/usr/src/linux-${_kernver}/$i
  done

  if [ "${KARCH}" = "i386" ]; then
    mkdir ${startdir}/pkg/usr/src/linux-${_kernver}/include/asm-x86_64
    cp -a include/asm-x86_64/tsc.h ${startdir}/pkg/usr/src/linux-${_kernver}/include/asm-x86_64
  else
    mkdir ${startdir}/pkg/usr/src/linux-${_kernver}/include/asm-i386
    cp -a include/asm-i386/{tsc,msr-index,processor-flags}.h ${startdir}/pkg/usr/src/linux-${_kernver}/include/asm-i386
  fi

  cd $startdir/pkg/usr/src/linux-${_kernver}/include && ln -s asm-$KARCH asm

  chown -R root.root $startdir/pkg/usr/src/linux-${_kernver}
  find $startdir/pkg/usr/src/linux-${_kernver} -type d -exec chmod 755 {} \;
  cd $startdir/pkg/lib/modules/${_kernver} && \
    (rm -f source build; ln -sf ../../../usr/src/linux-${_kernver} build)
  # for binary modules make prepare
  # cd $startdir/pkg/lib/modules/${_kernver}/build
  # make prepare
  # install fallback mkinitcpio.conf and kernel preset files
  install -m644 -D $startdir/src/kernel26custom.preset $startdir/pkg/etc/mkinitcpio.d/kernel26custom.preset
  install -m644 -D $startdir/src/kernel26custom-fallback.conf $startdir/pkg/etc/mkinitcpio.d/kernel26custom-fallback.conf
  # set correct depmod command for install
  sed -i -e "s/KERNEL_VERSION=.*/KERNEL_VERSION=${_kernver}/g" $startdir/kernel26${_ownver}.install
  echo -e "# NEVER EDIT THIS FILE\nALL_kver='${_kernver}'" > ${startdir}/pkg/etc/mkinitcpio.d/${pkgname}.kver

  # Copy the current - maybe changed - kernel config back to our startdir.
  # This is for easier reuse of this good config on the next run.
  cp $startdir/src/linux-${basekernel}/.config $startdir/config
}

kernel26custom.install

# arg 1:  the new package version
# arg 2:  the old package version

# Change this if either your kernel version or your local version changed
KERNEL_VERSION=2.6.22-custom
_ownver=custom

post_install () {
  # updating module dependencies
  echo ">>> Updating module dependencies. Please wait ..."
  depmod -v $KERNEL_VERSION > /dev/null 2>&1
  # generate init ramdisks
  echo ">>> MKINITCPIO SETUP"
  echo ">>> ----------------"
  echo ">>> If you use LVM2, Encrypted root or software RAID,"
  echo ">>> Ensure you enable support in /etc/mkinitcpio.conf ."
  echo ">>> More information about mkinitcpio setup can be found here:"
  echo ">>> http://wiki.archlinux.org/index.php/Mkinitcpio"
  echo ""
  echo ">>> Generating initial ramdisk, using mkinitcpio.  Please wait..."
if [ "`vercmp $2 2.6.19`" -lt 0 ]; then
  /sbin/mkinitcpio -p kernel26${_ownver} -m "ATTENTION:\nIf you get a kernel panic below
and are using an Intel chipset, append 'earlymodules=piix' to the
kernel commandline"
else
  /sbin/mkinitcpio -p kernel26${_ownver}
fi
if [ "`vercmp $2 2.6.21`" -lt 0 ]; then
  echo ""
  echo "Important ACPI Information:"
  echo ">>> Since 2.6.20.7 all possible ACPI parts are modularized."
  echo ">>> The modules are located at:"
  echo ">>> /lib/modules/$(uname -r)/kernel/drivers/acpi"
  echo ">>> For more information about ACPI modules check this wiki page:"
  echo ">>> 'http://wiki.archlinux.org/index.php/ACPI_modules'"
fi
}

post_upgrade() {
  pacman -Q grub &>/dev/null
  hasgrub=$?
  pacman -Q lilo &>/dev/null
  haslilo=$?
  # reminder notices
  if [ $haslilo -eq 0 ]; then
    echo ">>>"
    if [ $hasgrub -eq 0 ]; then
      echo ">>> If you use the LILO bootloader, you should run 'lilo' before rebooting."
    else
      echo ">>> You appear to be using the LILO bootloader. You should run"
      echo ">>> 'lilo' before rebooting."
    fi
    echo ">>>"
  fi

  if grep "/boot" /etc/fstab 2>&1 >/dev/null; then
    if ! grep "/boot" /etc/mtab 2>&1 >/dev/null; then
      echo "WARNING: /boot appears to be a seperate partition but is not mounted"
      echo "         This is most likely not what you want.  Please mount your /boot"
      echo "         partition and reinstall the kernel unless you are sure this is OK"
    fi
  fi

  if [ "`vercmp $2 2.6.13`" -lt 0 ]; then
    # important upgrade notice
    echo ">>>"
    echo ">>> IMPORTANT KERNEL UPGRADE NOTICE"
    echo ">>> -------------------------------"
    echo ">>> As of kernel 2.6.13, DevFS is NO LONGER AVAILABLE!"
    echo ">>> If you still use DevFS, please make the transition to uDev before"
    echo ">>> rebooting.  If you really need to stay with DevFS for some reason,"
    echo ">>> then you can manually downgrade to an older version:"
    echo ">>>"
    echo ">>> # pacman -U http://archlinux.org/~judd/kernel/kernel26-scsi-2.6.12.2-1.pkg.tar.gz"
    echo ">>>"
    echo ">>> If you choose to downgrade, don't forget to add kernel26-scsi to your"
    echo ">>> IgnorePkg list in /etc/pacman.conf"
    echo ">>>"
    echo ">>> (NOTE: The following portion applies to uDev users as well!)"
    echo ">>>"
    echo ">>> If you use any DevFS paths in your GRUB menu.lst, then you will not"
    echo ">>> be able to boot!  Change your root= parameter to use the classic"
    echo ">>> naming scheme."
    echo ">>>"
    echo ">>> EXAMPLES:"
    echo ">>> - change root=/dev/discs/disc0/part3 to root=/dev/sda3"
    echo ">>> - change root=/dev/md/0 to root=/dev/md0"
    echo ">>>"
  fi
 # generate new init ramdisk
  if [ "`vercmp $2 2.6.18`" -lt 0 ]; then
    echo ">>> --------------------------------------------------------------"
    echo ">>> |                          WARNING:                          |"
    echo ">>> |mkinitrd is not supported anymore in kernel >=2.6.18 series!|"
    echo ">>> |              Please change to Mkinitcpio setup.            |"
    echo ">>> --------------------------------------------------------------"
    echo ">>>"
  fi
  # updating module dependencies
  echo ">>> Updating module dependencies. Please wait ..."
  depmod -v $KERNEL_VERSION > /dev/null 2>&1
  echo ">>> MKINITCPIO SETUP"
  echo ">>> ----------------"
  if [ "`vercmp $2 2.6.18`" -lt 0 ]; then
    echo ">>> Please change your bootloader config files:"
    echo ">>> Grub: /boot/grub/menu.lst | Lilo: /etc/lilo.conf"
    echo "------------------------------------------------"
    echo "| - initrd26.img to kernel26.img               |"
    echo "| - initrd26-full.img to kernel26-fallback.img |"
    echo "------------------------------------------------"
  fi
  if [ "`vercmp $2 2.6.19`" -lt 0 ]; then
    echo ""
    echo ">>> New PATA/IDE subsystem - EXPERIMENTAL"
    echo ">>> ----------"
    echo ">>> To use the new pata drivers, change the 'ide' hook "
    echo ">>> to 'pata' in /etc/mkinicpio.conf HOOKS="
    echo ">>> The new system changes: /dev/hd? to /dev/sd?"
    echo ">>> Don't forget to modify GRUB, LILO and fstab to the"
    echo ">>> new naming system. "
    echo ">>> eg: hda3 --> sda3, hdc8 --> sdc8"
    echo ""
    echo ">>> piix/ata_piix (Intel chipsets) - IMPORTANT"
    echo "----------"
    echo ">>> If you have enabled ide/pata/sata HOOKs in /etc/mkinitcpio.conf"
    echo ">>> the 'ata_piix' module will be used."
    echo ">>> This may cause your devices to shift names, eg:"
    echo ">>> - IDE: devices from hd? to sd?"
    echo ">>> - SATA: sda might shift to sdc if you have 2 other disks on a PIIX IDE port."
    echo ">>> To check if this will affect you, check 'mkinitcpio -M' for piix/ata_piix"
    echo ""
  fi

  echo ">>> If you use LVM2, Encrypted root or software RAID,"
  echo ">>> Ensure you enable support in /etc/mkinitcpio.conf ."
  echo ">>> More information about mkinitcpio setup can be found here:"
  echo ">>> http://wiki.archlinux.org/index.php/Mkinitcpio"
  echo ""
  echo ">>> Generating initial ramdisk, using mkinitcpio.  Please wait..."
if [ "`vercmp $2 2.6.19`" -lt 0 ]; then
  /sbin/mkinitcpio -p kernel26${_ownver} -m "ATTENTION:\nIf you get a kernel panic below
and are using an Intel chipset, append 'earlymodules=piix' to the
kernel commandline"
else
  /sbin/mkinitcpio -p kernel26${_ownver}
fi
if [ "`vercmp $2 2.6.21`" -lt 0 ]; then
  echo ""
  echo "Important ACPI Information:"
  echo ">>> Since 2.6.20.7 all possible ACPI parts are modularized."
  echo ">>> The modules are located at:"
  echo ">>> /lib/modules/$(uname -r)/kernel/drivers/acpi"
  echo ">>> For more information about ACPI modules check this wiki page:"
  echo ">>> 'http://wiki.archlinux.org/index.php/ACPI_modules'"
fi
}

op=$1
shift

$op $*

kernel26custom.conf

# vim:set ft=sh
# MODULES
# The following modules are loaded before any boot hooks are
# run.  Advanced users may wish to specify all system modules
# in this array.  For instance:
#     MODULES="piix ide_disk reiserfs"
# BusLogic is added to support VMWARE arch booting in fallback image
MODULES="BusLogic"

# BINARIES
# This setting includes, into the CPIO image, and additional
# binaries a given user may wish.  This is run first, so may
# be used to override the actual binaries used in a given hook.
# (Existing files are NOT overwritten is already added)
# BINARIES are dependancy parsed, so you may safely ignore libraries
#BINARIES=""

# FILES
# This setting is similar to BINARIES above, however, files are added
# as-is and are not parsed in anyway.  This is useful for config files.
# Some users may wish to include modprobe.conf for custom module options,
# like so:
#    FILES="/etc/modprobe.d/modprobe.conf"
FILES=""

# HOOKS
# This is the most important setting in this file.  The HOOKS control the
# modules and scripts added to the image, and what happens at boot time.
# Order is important, and it is recommended that you do not change the
# order in which HOOKS are added.  Run 'mkinitcpio -H <hook name>' for
# help on a given hook.
# 'base' is _required_ unless you know precisely what you are doing.
# 'udev' is _required_ in order to automatically load modules
# 'modload' may be used in place of 'udev', but is not recommended
# 'filesystems' is _required_ unless you specify your fs modules in MODULES
# Examples:
#    This setup specifies all modules in the MODULES setting above.
#    No raid, lvm, or encrypted root is needed.
#    HOOKS="base"
#
#    This setup will autodetect all modules for your system and should
#    work as a sane default
#    HOOKS="base udev autodetect ide scsi sata filesystems"
#
#    This setup will generate a 'full' image which supports most systems.
#    No autodetection is done.
#    HOOKS="base udev ide scsi sata usb filesystems"
#
#    This setup assembles an ide raid array with an encrypted root FS.
#    Note: See 'mkinitcpio -H raid' for more information on raid devices.
#    HOOKS="base udev ide filesystems raid encrypt"
#
#    This setup loads an LVM volume group on a usb device.
#    HOOKS="base udev usb filesystems lvm"
HOOKS="base udev ide scsi sata usbinput raid filesystems"

kernel26custom-fallback.conf

# vim:set ft=sh
# MODULES
# The following modules are loaded before any boot hooks are
# run.  Advanced users may wish to specify all system modules
# in this array.  For instance:
#     MODULES="piix ide_disk reiserfs"
# BusLogic is added to support VMWARE arch booting in fallback image
MODULES="BusLogic"

# BINARIES
# This setting includes, into the CPIO image, and additional
# binaries a given user may wish.  This is run first, so may
# be used to override the actual binaries used in a given hook.
# (Existing files are NOT overwritten is already added)
# BINARIES are dependancy parsed, so you may safely ignore libraries
#BINARIES=""

# FILES
# This setting is similar to BINARIES above, however, files are added
# as-is and are not parsed in anyway.  This is useful for config files.
# Some users may wish to include modprobe.conf for custom module options,
# like so:
#    FILES="/etc/modprobe.d/modprobe.conf"
FILES=""

# HOOKS
# This is the most important setting in this file.  The HOOKS control the
# modules and scripts added to the image, and what happens at boot time.
# Order is important, and it is recommended that you do not change the
# order in which HOOKS are added.  Run 'mkinitcpio -H <hook name>' for
# help on a given hook.
# 'base' is _required_ unless you know precisely what you are doing.
# 'udev' is _required_ in order to automatically load modules
# 'modload' may be used in place of 'udev', but is not recommended
# 'filesystems' is _required_ unless you specify your fs modules in MODULES
# Examples:
#    This setup specifies all modules in the MODULES setting above.
#    No raid, lvm, or encrypted root is needed.
#    HOOKS="base"
#
#    This setup will autodetect all modules for your system and should
#    work as a sane default
#    HOOKS="base udev autodetect ide scsi sata filesystems"
#
#    This setup will generate a 'full' image which supports most systems.
#    No autodetection is done.
#    HOOKS="base udev ide scsi sata usb filesystems"
#
#    This setup assembles an ide raid array with an encrypted root FS.
#    Note: See 'mkinitcpio -H raid' for more information on raid devices.
#    HOOKS="base udev ide filesystems raid encrypt"
#
#    This setup loads an LVM volume group on a usb device.
#    HOOKS="base udev usb filesystems lvm"
HOOKS="base udev ide scsi sata usbinput raid filesystems"

kernel26custom.preset

# mkinitcpio preset file for kernel26custom

########################################
# NEVER EDIT THIS LINE:
source /etc/mkinitcpio.d/kernel26custom.kver
########################################

PRESETS=('default' 'fallback')

default_config="/etc/mkinitcpio.conf"
default_image="/boot/kernel26custom.img"

fallback_config="/etc/mkinitcpio.d/kernel26custom-fallback.conf"
fallback_image="/boot/kernel26custom-fallback.img" 

Build-Prozess vorbereiten, Prüfsummen erzeugen
Dieser Vorgang muss jedesmal ausgeführt werden, wenn sich eine Datei ändert die im PKGBUILD unter source=(...) aufgeführt ist. Die alten Prüfsummen in PKGBUILD sind vorher zu löschen.

makepkg -g >> PKGBUILD 

Ein wichtiger Punkt ist die Kernel-Konfigurationsdatei. Wir haben hier (wenn dieser Vorgang zum ersten Mal ausgeführt wird) folgende Möglichkeiten:
1. Wir können die Konfiguration des momentanen Kernel (wahrscheinlich der Arch-Standard-Kernel) als Vorlage nehmen. Das beschert uns die gleichen Treiber/Module wie sie dieser Kernel mitbringt. Allerdings können wir während des Build-Prozesses diese Konfig abändern um z.B. Treiber für nicht vorhandene Hardware wegzulassen. Dazu ist aber etwas an Erfahrung notwendig.
Wir bekommen diese Konfig, indem wir die momentane in unser Verzeichnis kopieren:

 cp /boot/kconfig26 ./config

2. Ganz erfahrene User können sich die Konfig quasi von Null selbst einstellen
Dafür darf keine Konfig-Datei config im Verzeichnis mit der PKGBUILD vorhanden sein. Beim erstmaligen Start ist auch keine vorhanden.

Während des Build-Prozesses wird diese Ausgangs-Konfig verwendet um daraus eine zum bauenden Kernel passende Konfig zu erstellen. Dies geschieht durch den Aufruf von make oldconfig im Ablauf der PKGBUILD.
Danach wird basierend auf dieser Konfig ein Frontend zum Editieren gestartet. In obiger PKGBUILD ist das make menuconfig. Mit diesem Frontend kann die Konfiguration angepasst werden.

Ganz wichtig: Im Zuge der Konfiguration mit dem Frontend muss unbedingt die lokale Version unserer Konfig eingestellt werden!
Zu finden ist dieser Parameter unter General setup->Local Version. Hier muss unserer lokaler Zusatz eingetragen werden, in diesem Fall -custom.

Build-Prozess starten

makepkg -c

Das Frontend zur Kernel-Konfig nach der oben beschriebenen Bearbeitung beenden und die Konfiguration speichern lassen. Danach wird der Build-Prozess normal weitergeführt.
Wenn alles glatt gelaufen ist, dann sehen wir eine ähnliche Meldung wie diese auf dem Bildschirm:

 ==> Compressing package...
 ==> Finished making: kernel26custom  (Wed Aug 15 08:59:23 CEST 2007)

Wir erhalten auch unser Kernel-Paket, welches über pacman installiert wird

kernel26custom-2.6.22-1-i686.pkg.tar.gz

Die Installation läuft entsprechend der normaler Kernel-Installation, wie wir sie kennen, ab.

pacman -U kernel26custom-2.6.22-1-i686.pkg.tar.gz

Eine Besonderheit ist hier noch zu erwähnen: Wenn der Build-Vorgang erfolgreich war, dann hat das PKGBUILD-Skript die von Dir eventuell angepasste Kernel-Konfigdatei zurück ins "Startverzeichnis" kopiert.
Warum? Damit der nächste Lauf immer mit deiner guten, aktuellen Konfiguration startet.

Bootloader anpassen
Jetzt fehlt lediglich noch der Eintrag im Bootloader (Grub) für unseren neuen Kernel. Die Einträge zu root und root= analog der eigenen menu.list anpassen!

# Eigener Kernel 2
title  Eigener Kernel (custom)
root   (hd0,0)
kernel /vmlinuz26custom root=/dev/sda3 ro
initrd /kernel26custom.img

# (1) Arch Linux
title  Eigener Kernel (custom) Fallback
root   (hd0,0)
kernel /vmlinuz26custom root=/dev/sda3 ro
initrd /kernel26custom-fallback.img

Hat sich dieser Aufwand jetzt gelohnt?
Der Vorteil dieser Methode kommt eigentlich erst richtig zum tragen, wenn wir z.B. eine Änderung an diesem Kernel vornehmen wollen. Sei es, dass wir eine andere Version der Vanilla-Kernelsourcen einbinden wollen, oder lediglich an der Konfig etwas verändern möchten.

Angenommen, du müsstest die Konfig verändern. Dann würde das Prozedere so ablaufen:

  • Prüfsummen (md5sums=) aus der PKGBUILD löschen
  • In der PKGBUILD den Wert von pkgrel um 1 erhöhen
  • makepkg -g >> PKGBUILD
  • makepkg
  • pacman -U kernel26custom-2.6.22-2-i686.pkg.tar.gz

Und schon wäre unser Kernel aktualisiert

Was ist mit den externen Treibern? Z.B. NVidia?

Um diese unter dem Reserve/Notfall-Kernel bzw. unter einem ständigen eigenen Paket installieren und nutzen zu können müssen diese Pakete auch selbst kompiliert werden. Eben passend zu unserem Kernel.

Diese Pakete kommen entweder aus dem ABS oder dem AUR. Das Prinzip funktioniert wie bei unserem Kernel: wir editieren die PKGBUILD's und andere Steuerdateien und passen diese an unsere Kernel-Version/Namen an.

Exemplarisch z.B. für den aktuellen NVidia-Treiber:
ABS aktualisieren

abs

Das PKGBUILD kopieren

cp -R /var/abs/extra/x11/nvidia /var/abs/local/
cd /var/abs/local
mv nvidia nvidia-custom
cd nvidia-custom

Dateien editieren Der Einfachheit halber hier nur die Änderungen:
PKGBUILD
pkgname=nvidia-custom
_kernver='2.6.22-custom'
pkgrel=1
pkgdesc="NVIDIA drivers for kernel26custom."
depends=('kernel26custom' 'nvidia-utils')
nvidia-install
KERNEL_VERSION='2.6.22-custom'
post_remove() {
KERNEL_VERSION='2.6.22-custom'

Paket bauen

makepkg

Installieren

pacman -U nvidia-custom-100.14.11-1-i686.pkg.tar.gz

Analog ist mit anderen, externen Kernel-Modulen zu verfahren.

Welche Parameter bewirken Namensänderungen?

Es gibt bei den vorgestellten Verfahren mehrere Parameter in verschiedenen Configs, die später eine Auswirkung darauf haben:

  • wie der Kernel "heißt" (uname -r)
  • wie das Verzeichnis heißt, in dem die Module installiert werden (/lib/modules/$name)
  • wie das ArchLinux-Paket heißt (unser Paket darf im Paketsystem z.B. nicht mit dem Paket kernel26 kollidieren)

.config
Die Kernel-Config, die wir z.B. mit make menuconfig erstellen oder die beim Arch-Standard-Kernel analog obigen Beispielen in $HOME/kernel26-custom als config bzw. config.x86_64 liegt.

#
# General setup
#
CONFIG_LOCALVERSION="-custom"

Was wir hier eintragen wird intern an den Kernel-Namen angehängt und bewirkt u.a. auch, wie das Modul-Verzeichnis heißt. Wenn wir CONFIG_LOCALVERSION="-custom" eintragen, dann wird der Kernel die Module in /lib/modules/2.6.22-custom suchen.

PKGBUILD
Wenn wir einen Kernel mit dem Paketmanagement bauen, dann haben Parameter darin Auswirkungen wie später das gebaute Paket heißt und welchen Namen der Kernel in der Paketdatenbank hat. Dies müssen wir anpassen um nicht mit den Standard-Kerneln zu kollidieren.

 pkgname=kernel26custom

Dies bewirkt, wie das Paket zum Installieren heißt (blabla.pkg.tar.gz), welchen Namen Verzeichnisse und Kernel bzw. initrd-Image haben.

 _ownver=custom

Dies ist ein eigener Parameter, den wir benutzen um in der Steuerdatei unseren Versionszusatz an z.B. Kopieraktionen anzuhängen.

 pkgrel=1

Wenn wir unseren eigenen Kernel später mal verändern, dann sollten wir diesen Parameter um Eins erhöhen. Dadurch können wir mit pacman unser Paket leicht aktualisieren.