Eigenen Kernel erstellen: Unterschied zwischen den Versionen

Aus wiki.archlinux.de
Zur Navigation springen Zur Suche springen
K (pacman -Sy angepasst, siehe https://bbs.archlinux.de/viewtopic.php?id=17347)
K (Tippfehler des Befehls lscpu verbessert)
 
(21 dazwischenliegende Versionen von 8 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
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.
+
{{Artikelstil}}{{Veraltet}}
 +
{{hinweis|Nur die ersten beiden großen Überschriften wurden überarbeitet!}}
 +
{{righttoc}}
 +
In diesem Artikel wird das Erstellen eines eigenen Kernels (Custom-Kernels) beschrieben. Man sollte sich bewusst sein, dass die Funktion des Arch Linux Standard-Kernels garantiert ist, die eines Custom-Kernels nicht. Der von Arch Linux installierte Kernel sollte daher nicht überschrieben werden.
  
Vorgestellt werden Wege ohne und mit dem ArchLinux-Paketmanagement.<br>
+
== Arten eines eigenen Kernels ==
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 ;-)
 
  
#eigener Kernel ohne das Paketmanagement („the old way“)
+
Auch bei eigenen Kerneln gibt es verschiedene Wege um an sein Ziel zu kommen. Man kann entweder die von Linus Torvalds und anderen engagierten Programmieren "Vanilla" Packages von https://www.kernel.org herunterladen. Diese Variante wird von vielen Leuten empfohlen, weil man damit den originalen Linux Kernel bekommt. Oder man kann auch die Arch Linux Kernel-Pakete anpassen und damit weitestgehend einen eigenen Kernel erstellen. Seinen wirklich eigenen Kernel bekommt man aber nur, wenn man die erste Variante wählt und die Konfiguration selber übernimmt. Eine Anleitung dazu findet man in dem nächsten "Kapitel".
#: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
 
#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
 
#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 ==
+
== Ein eigener Kernel auf die normale Art ("Vanilla" Kernel) ==
Das ArchBuildSystem(ABS) sollte eingerichtet sein und synchronisiert.
 
pacman -S cvsup wget abs
 
Weitere Informationen zum ABS siehe [[Abs|hier]].
 
  
== Kernel "the old way" ==
+
Dieser Weg ist der von den Kernelentwicklern empfohlene Weg. Man lädt sich den von den Entwicklern bereitgestellten Code in einem Archiv herunter und entpackt dieses. Danach erzeugt man eine Kernel-Konfiguration und kompiliert schließlich den Kernel. Schließlich erzeugt man ein Initramfs und aktualisiert die Bootloader-Konfiguration, damit der neue Kernel auch erkannt wird und gestartet werden kann.
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'''
+
=== Vorbereiten ===
  
Kernelsourcen von http://www.kernel.org besorgen.<br>
+
Zuerst muss man allerdings einige Dinge vorbereiten. Das Erstellen eines Kernels auf diese Art und Weise dauert einige Zeit und erfordert etwas Erfahrung. Wenn man das nicht möchte, sollte man in das nächste "Kapitel" schauen.
Hier exemplarisch für den 2.6.22.
 
  
'''Auspacken'''
+
'''Herunterladen des Quellcodes'''
<pre>
 
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
 
</pre>
 
  
'''Kernel konfigurieren'''
+
Den Quellcode findet man auf der Seite https://www.kernel.org. Dort findet man auch nicht nur den aktuellen "Stable" Kernel, sondern auch "Long Term" (LTS) und "Mainline" Kernel. In meinem Beispiel nutze ich die Kernelversion 4.16.12. Man kann diesen Kernel mit dem folgendem Befehl herunterladen:
 +
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.16.12.tar.xz
 +
Die Versionsnummer sollte man seiner Version anpassen. Dies gilt auch für den weiteren Verlauf dieses Artikels.
  
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.
+
'''Vorbereiten des Workspaces'''
  
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.
+
Zuerst muss man den Quellcode auspacken und die entpackten Dateien an einen Ort verschieben, an dem man das Workspace leicht wiederfindet. In meinem Fall werde ich die Dateien nach "/usr/src/" verschieben:
 +
tar xJf linux-4.16.12.tar.xz
 +
sudo mv linux-4.16.12 /usr/src/
 +
cd /usr/src/linux-4.16.12
 +
Danach sollte man zum nächsten Schritt gehen und den Kernel konfigurieren.
  
1. Eigene Konfig<br>
+
'''Konfigurieren des Kernels'''
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<br>
+
Um festzulegen, welche Teile des Linux Kernels kompiliert werden und ob diese als Modul vorliegen oder direkt in das Kernel Image hineinkompiliert werden, ist es zwingend erforderlich, eine Konfiguration zu erstellen. Es ist egal, ob man dies auf Basis einer alten oder älteren Konfiguration oder auf Basis einer komplett neuen Konfiguration macht. Wichtig ist nur, dass man eine erstellt.<br>
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.
+
Wenn man die aktuelle Konfiguration auslesen möchte, sind diese Befehle nötig:
cp /boot/kconfig26 /usr/src/linux-2.6.22/.config
+
  zcat /proc/config.gz > .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
 
  make oldconfig
Die Datei .config mit einem Editor öffnen. Folgendes ändern:
+
Bei dem letzten Befehl kann es sein, dass man bei bestimmten Funktionen gefragt wird. Hier kann man einfach "ENTER" drücken und die Standardeinstellung nutzen. WICHTIG:<br>
#
+
Diese Funktion zum Auslesen der Konfiguration muss vorher im Kernel aktiviert worden sein. Bei dem Arch Linux Standard-Kernel ist dies der Fall.<br>
# General setup
+
Möchte man die Konfiguration selber vornehmen, so gibt es verschiedene Möglichkeiten:
#
 
CONFIG_LOCALVERSION="-ARCH"
 
CONFIG_LOCALVERSION_AUTO=y
 
CONFIG_SWAP=y
 
Hier CONFIG_LOCALVERSION ändern zu ="".<br>
 
Was dieser Parameter bewirkt siehe [[Eigenen_Kernel_erstellen#Welche Parameter bewirken Namensänderungen?|Welche Parameter bewirken Namensänderungen?]].
 
 
 
'''Kompilieren'''
 
  
Der Kernel und die Module werden kompiliert mit:
+
{{achtung|Man sollte sich mit dem Kernel sehr gut auskennen, da man mit einer eigenen Konfiguration dafür sorgen kann, dass bestimmte elementare Funktionen nicht vorhanden sind! Außerdem kostet die Erstellung einer eigenen Konfiguration viel Zeit und Mühe!}}
  make
+
#Konsolen-basierte Konfiguration
 +
#:Bei dieser Art der Konfiguration wird man wie bei "make oldconfig" für jede Konfiguration gefragt und muss die Antwort angeben oder "ENTER" drücken. Der Befehl lautet:
 +
#:<pre>make config</pre>
 +
#Konsolen-basierte Konfiguration mit einfachem Menü
 +
#:Bei dieser Art der Konfiguration wird einem ein einfaches Menü in der Konsole angezeigt. Der Befehl lautet:
 +
#:<pre>make menuconfig</pre>
 +
#:oder mit nconfig:
 +
#:<pre>make nconfig</pre>
 +
#Grafische Konfiguration unter [[X]] mit GTK
 +
#:Bei dieser Art der Konfiguration wird das Menü aus "make menuconfig" mithilfe von GTK dargestellt. Der Befehl lautet:
 +
#:<pre>make gconfig</pre>
 +
#Grafische Konfiguration unter [[X]] mit QT
 +
#:Bei dieser Art der Konfiguration wird das Fenster nicht mit GTK, sondern mit QT dargestellt. Der Befehl lautet:
 +
#:<pre>make xconfig</pre>
 +
Nach einer fertigen Konfiguration kann mit dem Kompilieren des Kernels begonnen werden.
  
'''Kernel und Module installieren'''
+
=== Kompilieren und Installieren des Kernels ===
 
 
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!
 
<pre>
 
# Eigener Kernel
 
title  Eigener Kernel
 
root  (hd0,0)
 
kernel /vmlinuz root=/dev/sda3 ro
 
</pre>
 
oder wenn oben eine initrd erstellt wurde:
 
<pre>
 
# Eigener Kernel
 
title  Eigener Kernel
 
root  (hd0,0)
 
kernel /vmlinuz root=/dev/sda3 ro
 
initrd /initrd.img
 
</pre>
 
  
'''Was ist alles wo installiert, wie lösche ich den Kernel wieder?'''
+
Nachdem man den Kernel konfiguriert hat und gesagt hat, welche Funktionen man haben möchte und welche als Modul ausgelagert werden sollen, muss der Kernel nun kompiliert und installiert werden.
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 ==
+
'''Kompilieren des Kernels'''
  
Unser Kernel soll ein eigenständiger Kernel sein, mit dem Namen 2.6.22-custom.
+
Das Kompilieren des Kernels bedeutet, dass der Quellcode der ausgewählten Teile des Kernels in Maschinensprache übersetzt wird. Dabei werden als Modul markierte Funktionen als Module ausgelagert kompiliert. Andere ausgewählte Funktionen werden zu einer Datei zusammengefasst, die danach nach /boot/ kopiert wird.
  
ABS aktualisieren
+
Die Kompilierung wird mit dem folgendem Befehl durchgeführt:
  abs
+
make
Kernel-Steuerdateien in eigenes Verzeichnis kopieren
+
Die Abarbeitung des Befehls dauert üblicherweise an die zwanzig Minuten.
  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.<br>
 
'''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'''<br>
+
''Tipp:''
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.
+
Wenn man nur {{ic|make}} ausführt, so wird nur ''ein'' Prozessorkern verwendet. Man kann die Compilierzeit mithilfe des Arguments {{ic|-jX}} beschleunigen.
<pre>
+
Das {{ic|X}} soll jediglich die Anzahl der CPU-Cores sein. Man kann diese mithilfe von {{ic|lscpu}} anzeigen lassen.
@@ -1,15 +1,16 @@
+
Wenn man demnach
# $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
+
  make -j4
@@ -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
 
}
 
</pre>
 
  
'''kernel26custom.preset'''<br>
+
macht, so werden 4 CPU Cores für das Kompilieren miteinbezogen.
<pre>
+
Man sollte die Anzahl seiner Cores + Threads angeben, da eine zu große Zahl die Geschwindigkeit bremsen anstatt beschleunigen wird.
@@ -1,14 +1,14 @@
 
-# mkinitcpio preset file for kernel26
 
+# mkinitcpio preset file for kernel26custom
 
  
########################################
+
Beispiel:  
# DO NEVER EDIT THIS LINE:
 
-source /etc/mkinitcpio.d/kernel26.kver
 
+source /etc/mkinitcpio.d/kernel26custom.kver
 
########################################
 
  
PRESETS=('default' 'fallback')
+
Mit einer Quadcore-CPU kann man {{ic|make -j8}} verwenden, da ein Core 2 Threads haben kann.
  
default_config="/etc/mkinitcpio.conf"
+
'''Installieren des Kernels'''
-default_image="/boot/kernel26.img"
 
+default_image="/boot/kernel26custom.img"
 
  
-fallback_config="/etc/mkinitcpio.d/kernel26-fallback.conf"
+
Nach dem Kompilieren müssen der Kernel und seine Module installiert werden. Dies geschieht mit den folgenden Befehlen:
-fallback_image="/boot/kernel26-fallback.img"
+
sudo cp arch/x86/boot/bzImage /boot/vmlinuz-4.16.12
+fallback_config="/etc/mkinitcpio.d/kernel26custom-fallback.conf"
+
sudo make modules_install
+fallback_image="/boot/kernel26custom-fallback.img"
+
Nachdem man diese Schritte ausgeführt hat, sollten jetzt die Kernel-Headers angepasst werden.
</pre>
 
  
'''kernel26custom.install'''<br>
+
'''Einrichten der Kernel-Headers'''
<pre>
 
@@ -1,7 +1,8 @@
 
# arg 1:  the new package version
 
# arg 2:  the old package version
 
  
-KERNEL_VERSION=2.6.22-ARCH
+
{{hinweis|Die Kernel-Headers sind nicht zwingend erforderlich. Es sei denn, man nutzt [[:en:DKMS|DKMS]] oder bestimmte Treiber!}}
+KERNEL_VERSION=2.6.22-custom
+
Die Kernel-Headers befinden sich im Verzeichnis /lib/modules/4.16.12/ bzw. /usr/lib/modules/4.16.12/. Dort sind die Headers aber momentan nicht wirklich installiert. Es wurden nur Verknüpfungen auf die entsprechenden Dateien in dem Workspace angelegt. Deshalb müssen die folgenden Befehle ausgeführt werden:
+_ownver=custom
+
cd /usr/lib/modules/4.16.12
 +
sudo mv build build.bak
 +
sudo mv source source.bak
 +
sudo mkdir build source
 +
sudo cp -r build.bak/* build/
 +
sudo cp -r source.bak/* source/
 +
sudo rm build.bak
 +
sudo rm source.bak
 +
Damit stehen die Headers für den Kernel jetzt dauerhaft zur Verfügung. Die Headers werden für bestimmte Grafiktreiber und für [[:en:DKMS|DKMS]] gebraucht.
  
post_install () {
+
'''Generieren des Initramfs'''
  # 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 ""
 
</pre>
 
  
'''config'''<br>
+
Das Initramfs wird benötigt, wenn Funktionen in Module ausgelagert wurden. Es ist dafür da, wichtige Module an dem Anfang des Startvorgangs in den Arbeitsspeicher zu laden. Es wird mit dem folgendem Befehlt generiert:
<pre>
+
  sudo mkinitcpio -k 4.16.12 -g /boot/initramfs-4.16.12.img
#
+
Nachdem der Kernel jetzt fertig installiert und konfiguriert ist, sollte man das Workspace säubern. Danach muss man den Bootloader aktualisieren, damit der Kernel gestartet werden kann.
# General setup
 
  #
 
-CONFIG_LOCALVERSION="-ARCH"
 
+CONFIG_LOCALVERSION="-custom"
 
CONFIG_LOCALVERSION_AUTO=y
 
</pre>
 
  
'''config.x86_64'''<br>
+
'''Säubern des Workspaces'''
<pre>
 
#
 
# General setup
 
#
 
-CONFIG_LOCALVERSION="-ARCH"
 
+CONFIG_LOCALVERSION="-custom"
 
CONFIG_LOCALVERSION_AUTO=y
 
</pre>
 
  
Das war's jetzt mit dem Editieren, Ehrenwort ;-)
+
Das Workspace wird mit den folgenden Befehlen gesäubert, wobei ca. 1 GB Speicherplatz frei werden:
 +
cd /usr/src/linux-4.16.12/
 +
make clean
 +
Damit muss nur noch der Bootloader aktualisiert werden, damit der Kernel gestartet werden kann.
  
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.
+
=== Aktualisieren des Bootloaders ===
  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!
 
<pre>
 
# Eigener Kernel 2
 
title  Eigener Kernel (custom)
 
root  (hd0,0)
 
kernel /vmlinuz26custom root=/dev/sda3 ro
 
initrd /kernel26custom.img
 
  
# (1) Arch Linux
+
Der Bootloader ist für den Start des Kernels zuständig und muss den Kernel erkennen. Dafür ist bei den meisten Bootloadern, wie in meinem Beispiel bei GRUB, ein neu generieren der Konfiguration erforderlich. Wenn man den Bootloader GRUB nutzt, lautet der Befehl:
title  Eigener Kernel (custom) Fallback
+
sudo grub-mkconfig -o /boot/grub/grub.cfg
root  (hd0,0)
+
Wenn man einen anderen Bootloader nutzt, muss man den entsprechenden Befehl nutzen. Der Kernel ist jetzt startbereit und kann getestet werden.
kernel /vmlinuz26custom root=/dev/sda3 ro
 
initrd /kernel26custom-fallback.img
 
</pre>
 
  
 +
{{achtung|Ab hier wurde der Artikel noch nicht weiter überarbeitet! Es wurde nur das Kapitel "Ein angepasster Arch Linux Standardkernel" gelöscht!}}
 
== Kernel "the arch way" ==
 
== 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.<br>
 
Ziel ist es, einen eigenen Kernel basierend auf den Sourcen von http://www.kernel.org zu bauen, diesmal aber als Arch-Paket.<br>
Zeile 341: Zeile 134:
  
 
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.<br>
 
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.<br>
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.
+
Der so erstellte Kernel soll einen eigenen Namen bekommen. Für dieses Beispiel anhand des 2.6.22 Kernels soll dieser nachher 2.6.22-custom heißen.
  
 
Zum Bauen erstellen wir ein eigenes Verzeichnis, hier als Beispiel im Home-Verzeichnis.
 
Zum Bauen erstellen wir ein eigenes Verzeichnis, hier als Beispiel im Home-Verzeichnis.
Zeile 782: Zeile 575:
 
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.<br>
 
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.<br>
 
Wir bekommen diese Konfig, indem wir die momentane in unser Verzeichnis kopieren:
 
Wir bekommen diese Konfig, indem wir die momentane in unser Verzeichnis kopieren:
   cp /boot/kconfig26 ./config
+
   zcat /proc/config.gz > ./config
 
2. Ganz erfahrene User können sich die Konfig quasi von Null selbst einstellen<br>
 
2. Ganz erfahrene User können sich die Konfig quasi von Null selbst einstellen<br>
 
Dafür darf keine Konfig-Datei ''config'' im Verzeichnis mit der PKGBUILD vorhanden sein. Beim erstmaligen Start ist auch keine vorhanden.
 
Dafür darf keine Konfig-Datei ''config'' im Verzeichnis mit der PKGBUILD vorhanden sein. Beim erstmaligen Start ist auch keine vorhanden.
Zeile 836: Zeile 629:
 
Und schon wäre unser Kernel aktualisiert
 
Und schon wäre unser Kernel aktualisiert
  
== Was ist mit den externen Treibern? Z.B. NVidia? ==
+
== 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.
 
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.
  

Aktuelle Version vom 10. Dezember 2020, 12:54 Uhr

Überarbeitung.png Dieser Artikel oder Artikelabschnitt bedarf einer stilistischen Überarbeitung laut Empfehlungen in Artikelstil.


20040916-achtung.jpg Dieser Artikel wurde als veraltet markiert, und sollte kontrolliert, und gegebenfalls korrigiert bzw. aktualisiert werden.


Hinweis: Nur die ersten beiden großen Überschriften wurden überarbeitet!

In diesem Artikel wird das Erstellen eines eigenen Kernels (Custom-Kernels) beschrieben. Man sollte sich bewusst sein, dass die Funktion des Arch Linux Standard-Kernels garantiert ist, die eines Custom-Kernels nicht. Der von Arch Linux installierte Kernel sollte daher nicht überschrieben werden.

Arten eines eigenen Kernels

Auch bei eigenen Kerneln gibt es verschiedene Wege um an sein Ziel zu kommen. Man kann entweder die von Linus Torvalds und anderen engagierten Programmieren "Vanilla" Packages von https://www.kernel.org herunterladen. Diese Variante wird von vielen Leuten empfohlen, weil man damit den originalen Linux Kernel bekommt. Oder man kann auch die Arch Linux Kernel-Pakete anpassen und damit weitestgehend einen eigenen Kernel erstellen. Seinen wirklich eigenen Kernel bekommt man aber nur, wenn man die erste Variante wählt und die Konfiguration selber übernimmt. Eine Anleitung dazu findet man in dem nächsten "Kapitel".

Ein eigener Kernel auf die normale Art ("Vanilla" Kernel)

Dieser Weg ist der von den Kernelentwicklern empfohlene Weg. Man lädt sich den von den Entwicklern bereitgestellten Code in einem Archiv herunter und entpackt dieses. Danach erzeugt man eine Kernel-Konfiguration und kompiliert schließlich den Kernel. Schließlich erzeugt man ein Initramfs und aktualisiert die Bootloader-Konfiguration, damit der neue Kernel auch erkannt wird und gestartet werden kann.

Vorbereiten

Zuerst muss man allerdings einige Dinge vorbereiten. Das Erstellen eines Kernels auf diese Art und Weise dauert einige Zeit und erfordert etwas Erfahrung. Wenn man das nicht möchte, sollte man in das nächste "Kapitel" schauen.

Herunterladen des Quellcodes

Den Quellcode findet man auf der Seite https://www.kernel.org. Dort findet man auch nicht nur den aktuellen "Stable" Kernel, sondern auch "Long Term" (LTS) und "Mainline" Kernel. In meinem Beispiel nutze ich die Kernelversion 4.16.12. Man kann diesen Kernel mit dem folgendem Befehl herunterladen:

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.16.12.tar.xz

Die Versionsnummer sollte man seiner Version anpassen. Dies gilt auch für den weiteren Verlauf dieses Artikels.

Vorbereiten des Workspaces

Zuerst muss man den Quellcode auspacken und die entpackten Dateien an einen Ort verschieben, an dem man das Workspace leicht wiederfindet. In meinem Fall werde ich die Dateien nach "/usr/src/" verschieben:

tar xJf linux-4.16.12.tar.xz
sudo mv linux-4.16.12 /usr/src/
cd /usr/src/linux-4.16.12

Danach sollte man zum nächsten Schritt gehen und den Kernel konfigurieren.

Konfigurieren des Kernels

Um festzulegen, welche Teile des Linux Kernels kompiliert werden und ob diese als Modul vorliegen oder direkt in das Kernel Image hineinkompiliert werden, ist es zwingend erforderlich, eine Konfiguration zu erstellen. Es ist egal, ob man dies auf Basis einer alten oder älteren Konfiguration oder auf Basis einer komplett neuen Konfiguration macht. Wichtig ist nur, dass man eine erstellt.
Wenn man die aktuelle Konfiguration auslesen möchte, sind diese Befehle nötig:

zcat /proc/config.gz > .config
make oldconfig

Bei dem letzten Befehl kann es sein, dass man bei bestimmten Funktionen gefragt wird. Hier kann man einfach "ENTER" drücken und die Standardeinstellung nutzen. WICHTIG:
Diese Funktion zum Auslesen der Konfiguration muss vorher im Kernel aktiviert worden sein. Bei dem Arch Linux Standard-Kernel ist dies der Fall.
Möchte man die Konfiguration selber vornehmen, so gibt es verschiedene Möglichkeiten:

Achtung: Man sollte sich mit dem Kernel sehr gut auskennen, da man mit einer eigenen Konfiguration dafür sorgen kann, dass bestimmte elementare Funktionen nicht vorhanden sind! Außerdem kostet die Erstellung einer eigenen Konfiguration viel Zeit und Mühe!

  1. Konsolen-basierte Konfiguration
    Bei dieser Art der Konfiguration wird man wie bei "make oldconfig" für jede Konfiguration gefragt und muss die Antwort angeben oder "ENTER" drücken. Der Befehl lautet:
    make config
  2. Konsolen-basierte Konfiguration mit einfachem Menü
    Bei dieser Art der Konfiguration wird einem ein einfaches Menü in der Konsole angezeigt. Der Befehl lautet:
    make menuconfig
    oder mit nconfig:
    make nconfig
  3. Grafische Konfiguration unter X mit GTK
    Bei dieser Art der Konfiguration wird das Menü aus "make menuconfig" mithilfe von GTK dargestellt. Der Befehl lautet:
    make gconfig
  4. Grafische Konfiguration unter X mit QT
    Bei dieser Art der Konfiguration wird das Fenster nicht mit GTK, sondern mit QT dargestellt. Der Befehl lautet:
    make xconfig

Nach einer fertigen Konfiguration kann mit dem Kompilieren des Kernels begonnen werden.

Kompilieren und Installieren des Kernels

Nachdem man den Kernel konfiguriert hat und gesagt hat, welche Funktionen man haben möchte und welche als Modul ausgelagert werden sollen, muss der Kernel nun kompiliert und installiert werden.

Kompilieren des Kernels

Das Kompilieren des Kernels bedeutet, dass der Quellcode der ausgewählten Teile des Kernels in Maschinensprache übersetzt wird. Dabei werden als Modul markierte Funktionen als Module ausgelagert kompiliert. Andere ausgewählte Funktionen werden zu einer Datei zusammengefasst, die danach nach /boot/ kopiert wird.

Die Kompilierung wird mit dem folgendem Befehl durchgeführt:

make

Die Abarbeitung des Befehls dauert üblicherweise an die zwanzig Minuten.

Tipp: Wenn man nur make ausführt, so wird nur ein Prozessorkern verwendet. Man kann die Compilierzeit mithilfe des Arguments -jX beschleunigen. Das X soll jediglich die Anzahl der CPU-Cores sein. Man kann diese mithilfe von lscpu anzeigen lassen. Wenn man demnach

make -j4

macht, so werden 4 CPU Cores für das Kompilieren miteinbezogen. Man sollte die Anzahl seiner Cores + Threads angeben, da eine zu große Zahl die Geschwindigkeit bremsen anstatt beschleunigen wird.

Beispiel:

Mit einer Quadcore-CPU kann man make -j8 verwenden, da ein Core 2 Threads haben kann.

Installieren des Kernels

Nach dem Kompilieren müssen der Kernel und seine Module installiert werden. Dies geschieht mit den folgenden Befehlen:

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-4.16.12
sudo make modules_install

Nachdem man diese Schritte ausgeführt hat, sollten jetzt die Kernel-Headers angepasst werden.

Einrichten der Kernel-Headers

Hinweis: Die Kernel-Headers sind nicht zwingend erforderlich. Es sei denn, man nutzt DKMS oder bestimmte Treiber!

Die Kernel-Headers befinden sich im Verzeichnis /lib/modules/4.16.12/ bzw. /usr/lib/modules/4.16.12/. Dort sind die Headers aber momentan nicht wirklich installiert. Es wurden nur Verknüpfungen auf die entsprechenden Dateien in dem Workspace angelegt. Deshalb müssen die folgenden Befehle ausgeführt werden:

cd /usr/lib/modules/4.16.12
sudo mv build build.bak
sudo mv source source.bak
sudo mkdir build source
sudo cp -r build.bak/* build/
sudo cp -r source.bak/* source/
sudo rm build.bak
sudo rm source.bak

Damit stehen die Headers für den Kernel jetzt dauerhaft zur Verfügung. Die Headers werden für bestimmte Grafiktreiber und für DKMS gebraucht.

Generieren des Initramfs

Das Initramfs wird benötigt, wenn Funktionen in Module ausgelagert wurden. Es ist dafür da, wichtige Module an dem Anfang des Startvorgangs in den Arbeitsspeicher zu laden. Es wird mit dem folgendem Befehlt generiert:

sudo mkinitcpio -k 4.16.12 -g /boot/initramfs-4.16.12.img

Nachdem der Kernel jetzt fertig installiert und konfiguriert ist, sollte man das Workspace säubern. Danach muss man den Bootloader aktualisieren, damit der Kernel gestartet werden kann.

Säubern des Workspaces

Das Workspace wird mit den folgenden Befehlen gesäubert, wobei ca. 1 GB Speicherplatz frei werden:

cd /usr/src/linux-4.16.12/
make clean

Damit muss nur noch der Bootloader aktualisiert werden, damit der Kernel gestartet werden kann.

Aktualisieren des Bootloaders

Der Bootloader ist für den Start des Kernels zuständig und muss den Kernel erkennen. Dafür ist bei den meisten Bootloadern, wie in meinem Beispiel bei GRUB, ein neu generieren der Konfiguration erforderlich. Wenn man den Bootloader GRUB nutzt, lautet der Befehl:

sudo grub-mkconfig -o /boot/grub/grub.cfg

Wenn man einen anderen Bootloader nutzt, muss man den entsprechenden Befehl nutzen. Der Kernel ist jetzt startbereit und kann getestet werden.

Achtung: Ab hier wurde der Artikel noch nicht weiter überarbeitet! Es wurde nur das Kapitel "Ein angepasster Arch Linux Standardkernel" gelöscht!

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 nachher 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:

 zcat /proc/config.gz > ./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.