Konfiguration, Kompilierung und Installation eines benutzerdefinierten Linux-Kernels

38

Ich möchte versuchen, einen anderen Kernel als den von meiner Distribution bereitgestellten zu verwenden - entweder von einem anderen Ort oder wie von mir angepasst. Ist das schwierig oder gefährlich?

Wo soll ich anfangen?

Goldlöckchen
quelle

Antworten:

51

Das Erstellen eines benutzerdefinierten Kernels kann zeitaufwändig sein - meistens in der Konfiguration, da moderne Computer den Build in wenigen Minuten ausführen können. Es ist jedoch nicht besonders gefährlich, wenn Sie Ihren aktuellen Kernel beibehalten und sicherstellen, dass Sie diesen beibehalten als Option über Ihren Bootloader (siehe Schritt 6 unten). Auf diese Weise können Sie, wenn Ihr neues nicht funktioniert, einfach das alte neu starten.

In den folgenden Anweisungen haben Pfade innerhalb des Quellbaums die Form [src]/whatever, in welchem [src]Verzeichnis Sie die Quelle installiert haben, z /usr/src/linux-3.13.3. Sie möchten dies wahrscheinlich tun, su rootda der Quellbaum hinsichtlich der Schreibberechtigungen sicher bleiben sollte (er sollte im Besitz von root sein).

Einige der Schritte sind optional, Sie sollten sie jedoch trotzdem lesen, da sie Informationen enthalten, die zum Verständnis des restlichen Prozesses erforderlich sind.

  1. Laden Sie den Quell-Tarball herunter und entpacken Sie ihn.

    Diese sind von kernel.org erhältlich . Die neuesten sind auf der Titelseite aufgelistet, aber wenn Sie in das /pub/Verzeichnis schauen , finden Sie ein Archiv , das bis zur Version 1.0 zurückreicht. Sofern Sie keinen besonderen Grund haben, etwas anderes zu tun, wählen Sie am besten nur den "Latest Stable". Zum Zeitpunkt des Schreibens handelt es sich um eine 74-MB- tar.xzDatei.

    Sobald der Tarball heruntergeladen ist, müssen Sie ihn irgendwo entpacken. Der normale Ort ist in /usr/src. Platziere die Datei dort und:

    tar -xJf linux-X.X.X.tar.xz
    

    Beachten Sie, dass einzelne Distributionen normalerweise die Verwendung eines ihrer Quellpakete anstelle des Vanillebaums empfehlen. Dies enthält distro-spezifische Patches, die für Sie von Belang sein können oder auch nicht. Es passt auch zu den Kernel-Include-Headern, die zum Kompilieren einiger Userspace-Tools verwendet werden, obwohl sie höchstwahrscheinlich sowieso identisch sind.

    In mehr als 15 Jahren des Erstellens von benutzerdefinierten Kerneln (hauptsächlich unter Fedora / Debian / Ubuntu) hatte ich nie ein Problem mit der Verwendung der Vanilla 1- Quelle. Dies zu tun macht jedoch keinen großen Unterschied, abgesehen von der Tatsache, dass Ihre Distribution den absolut neuesten Kernel wahrscheinlich noch nicht gepackt hat. Am sichersten ist es also, das Distributionspaket zu verwenden, in das installiert werden soll /usr/src. Ich bevorzuge den neuesten Stall, damit ich als Versuchskaninchen agieren kann, bevor er in die Distribution kommt :)

  2. Beginnen Sie mit einer Grundkonfiguration [optional].

    Sie müssen dies nicht tun - Sie können einfach eintauchen und eine Konfiguration von Grund auf neu erstellen. Wenn Sie dies jedoch noch nie zuvor getan haben, müssen Sie mit viel Versuch und Irrtum rechnen . Dies bedeutet auch, dass Sie die meisten Optionen durchlesen müssen (es gibt Hunderte). Besser ist es, die vorhandene Konfiguration zu verwenden, sofern verfügbar. Wenn Sie ein Distribution-Quellpaket verwendet haben, enthält es wahrscheinlich bereits eine [src]/.configDatei, sodass Sie diese verwenden können. Andernfalls prüfen Sie, ob a /proc/config.gz. Dies ist eine optionale Funktion, die im 2.6-Kernel hinzugefügt wurde. Wenn es existiert, kopieren Sie es in die oberste Ebene des Quellbaums und gunzip -c config.gz > .config.

Ist dies nicht der Fall, liegt dies möglicherweise daran, dass diese Option als Modul konfiguriert wurde. Versuchen Sie es sudo modprobe configs, und überprüfen Sie das /procVerzeichnis config.gzerneut.

Die Distributionskonfiguration ist nicht sehr ideal in dem Sinne, dass sie fast jeden möglichen Hardwaretreiber enthält. Dies ist für die Funktionalität des Kernels nicht besonders wichtig, da es sich um Module handelt und die meisten davon niemals verwendet werden, erhöht jedoch die für die Erstellung erforderliche Zeit erheblich. Es ist auch insofern umständlich, als ein Initramfs bestimmte Kernmodule enthalten muss (siehe Schritt 4 unten). Es ist jedoch wahrscheinlich ein besserer Ausgangspunkt als der Standard.

Beachten Sie, dass sich die Konfigurationsoptionen von einer Kernelversion zur nächsten verschieben und ändern. Wenn Sie eines der folgenden make configProgramme ausführen, .configwird es zuerst analysiert und aktualisiert, um der neuen Version zu entsprechen. Wenn die Konfiguration von einer sehr viel älteren Version stammt, kann dies zu seltsamen Ergebnissen führen. Achten Sie daher bei der Konfiguration darauf. AFAIK es wird nicht andersherum funktionieren (mit einer Konfiguration aus einer neueren Version).

  1. Erstellen Sie eine .configUration.

    [src]/.configist eine Textdatei, die zum Konfigurieren des Kernels verwendet wird. Bearbeiten Sie diese Datei nicht direkt . Das Ändern von Optionen ist häufig nicht einfach, indem Sie a Ydurch a Nusw. Ersetzen . In der Regel gibt es eine Reihe von Abhängigkeiten und Verzweigungsmöglichkeiten. Stattdessen möchten Sie eines der Konfigurationsziele aus dem Kernel-Makefile verwenden (dh in make _____der Befehlszeile aus dem Quellverzeichnis der obersten Ebene eingeben ):

    • make configist die grundlegendste, aber wahrscheinlich nicht den Geschmack der meisten Menschen. Es ist eine Abfolge von Fragen - viele Fragen - und wenn Sie Ihre Meinung ändern, müssen Sie erneut beginnen.

    • make oldconfigist wie make configaußer, wenn Sie bereits eine .configaus einer früheren Version haben, überspringt Fragen mit Ausnahme derer, die sich auf neue Optionen beziehen. Es kann immer noch eine Menge davon geben und die meisten werden für dich irrelevant sein, also empfehle ich es nicht.

    • make menuconfigist meine (und ich denke die meisten anderen) bevorzugte Methode. Es erstellt und führt eine TUI-Schnittstelle aus (farbige Menüs, die auf einem Terminal funktionieren). Dies setzt -devvoraus, dass Sie das Paket für ncurses installiert haben. Es ist ziemlich selbsterklärend, abgesehen von der Suche, die über erreichbar ist /; Die F1 "Hilfe" bietet eine Erklärung für die aktuelle Option. Es gibt eine alternative Version make nconfigmit ein paar zusätzlichen Funktionen, wobei F2 "syminfo" der Entsprechung von menuconfigs F1 entspricht.

    • make xconfigist eine vollständige GUI-Oberfläche. Dies erfordert qmakeund das -devPaket für Qt muss installiert werden, da es sich wiederum um ein Programm handelt, das kompiliert und erstellt wird. Wenn Sie diese zuvor nicht verwendet haben, ist dies möglicherweise ein erheblicher Download. Der Grund, warum ich menuconfigdie GUI-Version bevorzuge , ist, dass Optionshierarchien in der ersteren mit aufeinanderfolgenden Bildschirmen dargestellt werden, in der letzteren jedoch akkordeonartig.

    Eines der ersten Dinge, die Sie tun sollten (aber nicht müssen), ist das Hinzufügen einer Zeichenfolge "Lokale Version" (unter Allgemeines Setup ). Der Grund dafür wird in # 5 unten erwähnt.

    "Labyrinth" ist ein guter Weg, um die Optionshierarchie zu beschreiben, und es geht weit über den Rahmen einer solchen Frage- und Antwortrunde hinaus, sich damit auseinanderzusetzen. Wenn Sie sich hinsetzen und alles durchgehen möchten, nehmen Sie sich Stunden Zeit . Greg Kroah-Hartman (langjähriger Entwickler des Linux-Kernels) hat ein kostenloses Online-Buch über den Kernel (siehe Referenzen unten), das ein Kapitel über die Konfiguration enthält , obwohl es 2006 geschrieben wurde. Mein Rat ist, mit einer vernünftigen Basis zu beginnen von Ihrem aktuellen Distributionskernel (gemäß Nummer 2) und gehen Sie dann durch und deaktivieren Sie alle Dinge, die Sie wissen, dass Sie nicht brauchen. Sie werden wahrscheinlich auch einige der "Modul" -Optionen in "eingebaut" ändern wollen, was uns zu meinem nächsten Punkt bringt ...

  2. Über initramfs[optional]

    Ein "initramfs" ist ein komprimiertes Dateisystem, das in den Kernel eingebaut und / oder beim Booten geladen wird. Der Hauptzweck besteht darin, Module einzuschließen, die der Kernel benötigt, bevor er auf die im /lib/modulesRoot-Dateisystem befindlichen Module zugreifen kann, z. B. Treiber für das Gerät, das dieses Dateisystem enthält. Distros verwenden diese teilweise immer, da die Treiber nicht miteinander kompatibel sind und daher nicht alle in den Kernel integriert werden können. Stattdessen werden diejenigen ausgewählt, die dem aktuellen System entsprechen initramfs.

    Dies funktioniert gut und stellt keinerlei Nachteil dar, ist jedoch wahrscheinlich eine unnötige Komplikation beim Erstellen Ihres eigenen Kernels. 2 Wenn Sie kein initramfs verwenden, müssen Sie sicherstellen, dass die Treiber für Ihr Root-Dateisystem (und das Gerät, auf dem es sich befindet) im Kernel integriert sind. In menuconfigdiese ist die Differenz zwischen einer M(= Modul) Option und einer *(= eingebaut) Option. Wenn Sie dies nicht richtig verstehen, schlägt das System zu Beginn des Startvorgangs fehl. Wenn Sie beispielsweise eine SATA-Festplatte und ein ext4-Root-Dateisystem haben, benötigen Sie Treiber für diese eingebauten. [Wenn jemand an etwas anderes denken kann, das ein Muss ist, hinterlasse einen Kommentar und ich werde das hier einfügen].

    Wenn Sie ein verwenden möchten, initramfsmüssen Sie die entsprechenden Optionen im allgemeinen Setup auswählen . Es gibt ein Skelett Leitfaden für eine Erstellung in den Kernel eingebaut in [src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt, aber beachten Sie, dass die distros dies nicht tun; Sie verwenden eine externe gzippte cpio-Datei. Dieses Dokument enthält jedoch eine Beschreibung dessen, was in dem Dokument enthalten sein sollte initramfs(siehe "Inhalt von initramfs").

  3. Erstellen und installieren Sie den Kernel.

    Der nächste Schritt ist einfach. Um den Kernel zu erstellen, führen Sie einfach makedas [src]Verzeichnis aus. Wenn Sie sich in einem Multi-Core-System befinden, können Sie -j Nzur Beschleunigung hinzufügen, wie Nviele Kerne Sie für + 1 reservieren möchten. Es gibt kein testoder check. Sobald das erledigt ist, können Sie make modules. Bei einer schnellen Box sollte dies weniger als 10 Minuten dauern.

    Wenn alles gut geht, make INSTALL_MOD_STRIP=1 modules_install. Dadurch wird ein Verzeichnis erstellt /lib/modules, das der Versionsnummer des Kernels sowie der in Schritt 3 erwähnten Zeichenfolge "Lokale Version" entspricht, sofern vorhanden. Wenn Sie keine Zeichenfolge "Lokale Version" verwendet haben, müssen Sie vorsichtig sein, wenn Sie bereits einen Kernel mit derselben Version haben, von der Sie abhängig sind , da diese Module diese ersetzen. 3 INSTALL_MOD_STRIP=1 ist optional, für die Bedeutung siehe hier .

    Anschließend können Sie make installden Kernel an einem Standardspeicherort installieren. Ich empfehle jedoch, es selbst zu tun, um sicherzustellen, dass keine vorhandenen Dateien überschrieben werden. Schauen Sie in [src]/arch/[ARCH]/booteiner Datei mit dem Namen bzImage4 , wo [ARCH]ist , x86wenn Sie auf einem x86 oder x86-64 Maschine sind (und etwas anderes , wenn Sie auf etwas anderes sind). Kopieren Sie das in /bootund benennen Sie es in etwas spezifischeres und informativeres um (egal was). Machen Sie dasselbe mit [src]/System.map, aber benennen Sie es nach folgendem Schema um:

    System.map-[VERSION]
    

    Hier [VERSION]ist genau der gleiche wie der Name des Verzeichnisses , in /lib/moduleserstellt vonmake modules_install , die die „Local Version“ string gehören zB System.map-3.13.3-mykernel.

  4. Konfigurieren Sie den GRUB 2-Bootloader.

    Wenn Sie nicht verwenden grub(die Mehrheit der Linux-Desktopbenutzer), trifft dies offensichtlich nicht auf Sie zu. Sie sollten eine /etc/grub.d/40_customDatei haben, die nicht viel enthält. Wenn nicht, erstellen Sie es im Besitz von root und chmod 755(es muss ausführbar sein). Dazu fügen Sie hinzu:

    menuentry 'My new kernel, or whatever' {
        set root='hd0,1'
        linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
    }
    

    Wenn Sie ein initramfs verwenden, sollten Sie auch eine letzte Zeile haben initrd /path/to/initramfs. Pass auf die set root=Linie auf. Das Beispiel setzt voraus, dass grub auf der ersten Partition der ersten Festplatte (hd0,1) installiert wurde. Wenn Sie über mehrere Laufwerke verfügen, möchten Sie möglicherweise stattdessen die Partitions-UUID verwenden und diese Zeile durch Folgendes ersetzen:

        search --no-floppy --fs-uuid --set=root [the UUID of the partition]
    

    Sofern sich grub nicht in Ihrem Root-Dateisystem befindet, sollte dies auch der root=Anweisung in der linuxZeile entsprechen, die Ihr Root-Dateisystem angibt (das mit /sbin/initund /lib/modules). Die UUID-Version davon ist root=UUID=[the UUID].

    Sie können Ihren vorhandenen /boot/grub2/grub.cfgnach einem Hinweis auf den Gerätenamen durchsuchen. Hier ist eine kurze Anleitung für solche unter Grub 2. Wenn Sie zufrieden sind, führen Sie sie aus grub2-mkconfig -o /boot/grub2/grub.cfg( sichern Sie jedoch zuerst Ihre aktuelle grub.cfg). Sie können diese Datei dann bearbeiten und Ihren Eintrag nach oben verschieben. Es sollte immer noch eine Auflistung für Ihren alten (laufenden) Kernel enthalten, und Ihre Distribution verfügt möglicherweise über einen Mechanismus, der einen Eintrag für den neuen Kernel automatisch dupliziert (weil er in gefunden wurde /boot; Fedora tut dies, daher wird ein eindeutiger Titel mit menuentrya verwendet gute Idee). Sie können das später entfernen, wenn alles gut geht.

    Sie können auch fügen Sie einfach die menuentryin grub.cfgdirekt, aber einige Distributionen werden diese überschrieben werden, wenn ihr Kernel aktualisiert wird (während verwendet /etc/grub.d/wird hält es aufgenommen).

    Das ist es. Jetzt müssen Sie nur noch einen Neustart durchführen. Wenn es nicht funktioniert, versuchen Sie, das Problem aus der Bildschirmausgabe abzuleiten, starten Sie den Computer neu und wählen Sie einen alten Kernel aus. Kehren Sie dann zu Schritt 3 zurück (außer Sie verwenden den .configbereits vorhandenen und optimieren ihn). Es kann eine gute Idee sein, zwischen den Versuchen make clean(oder make mrproper) zu kopieren [src]/.config, aber stellen Sie sicher, dass Sie zuerst auf ein Backup kopieren , da dies gelöscht wird. Dadurch wird sichergestellt, dass die im Erstellungsprozess verwendeten Objekte nicht veraltet sind.

  5. In Bezug auf Kernel-Header et. al.

    Eine Sache, die Sie wahrscheinlich tun sollten, ist symlink ( ln -s -i) /lib/modules/X.X.X/sourceund /lib/modules/X.X.X/builddas /usr/srcVerzeichnis, in dem sich der Quellbaum befindet (behalten Sie das bei). Dies ist erforderlich, damit einige Userspace-Tools (und Treiberinstallationsprogramme von Drittanbietern) auf die Quelle für den ausgeführten Kernel zugreifen können.

    Ein damit verbundenes Problem sind .hDateien in /usr/includeusw. Diese ändern sich sehr allmählich und sind abwärtskompatibel . Sie haben zwei Möglichkeiten:

    • Lassen Sie die von Ihrer Distribution verwendeten. Wenn Sie das gesamte System regelmäßig aktualisieren, installiert die Distribution in regelmäßigen Abständen neue. Dies ist also die Option mit dem geringsten Aufwand.

    • Verwenden Sie make headers_install.

    Da sie abwärtskompatibel sind (was bedeutet, dass "ein Programm, das mit älteren Kernel-Headern gegen eine C-Bibliothek erstellt wurde, auf einem neueren Kernel ausgeführt werden sollte"), müssen Sie sich darüber keine Gedanken machen. Das einzige potenzielle Problem wäre, wenn Sie einen benutzerdefinierten Kernel erstellen und eine Weile aufbewahren. In dieser Zeit aktualisiert die Distribution das Paket "kernel-headers" auf eine neuere Version als die, die zum Erstellen Ihres Kernels verwendet wurde, und es stellt sich heraus, dass es einige gibt Inkompatibilität (die nur für Software gilt, die später aus dem Quellcode kompiliert wurde).

Verweise

Hier sind einige Ressourcen:

  • [src]/README Enthält eine kurze Anleitung zum Erstellen und Installieren.

  • Das [src]/DocumentationVerzeichnis enthält viele Informationen, die bei der Konfiguration hilfreich sein können.

  • Ein Großteil von Greg KHs Buch Linux Kernel in a Nutshell (kostenlos als PDF-Serie erhältlich) dreht sich um den Kernel.

  • Grub 2 hat ein Online-Handbuch .


1. "Vanille" bezieht sich auf die ursprüngliche, unverfälschte offizielle Quelle von kernel.org. Die meisten Distributionen verwenden diese Vanillequelle und fügen kleinere Anpassungen hinzu.

2. Beachten Sie, dass unter bestimmten Umständen ein initramfs erforderlich ist, da zum Mounten des Root-Dateisystems ein gewisser Benutzerbereich erforderlich ist, z. B. wenn es verschlüsselt oder über ein komplexes RAID-Array verteilt ist.

3. Module, die bereits vorhanden sind, werden nicht entfernt, wenn Sie sie nicht erstellt haben. Dies bedeutet, dass Sie ein Modul später hinzufügen können, indem Sie einfach Ihre Konfiguration ändern und es make modules_installerneut ausführen . Beachten Sie, dass für das Erstellen einiger Module möglicherweise Änderungen am Kernel selbst erforderlich sind. In diesem Fall müssen Sie auch den Kernel ersetzen. Sie können feststellen, wann Sie versuchen, modprobedas Modul einzufügen.

4. Diese Datei hat möglicherweise einen anderen Namen, wenn Sie eine nicht standardmäßige Komprimierungsoption verwendet haben. Ich bin mir nicht sicher, welche Möglichkeiten es gibt.

Goldlöckchen
quelle
3
Upvoted. Möglicherweise möchten Sie in einer Erwähnung localmodconfigund Tools wie das streamline_config.plSkript hinzufügen ; Ein hilfreicher Ansatz, um von Ihrem vorhandenen Setup zu arbeiten ...
JasonWryan
1
Dies ist wahrscheinlich detailliert genug, um eine kanonische Frage pro @ terdon-Initiative zu sein. Erwägen Sie eine Antwort auf seine Frage zu Meta. Oder ich könnte, wenn Sie es vorziehen. Es sieht so aus, als ob dies die Absicht gewesen sein könnte, da Sie die Frage trotzdem gestellt haben. Es wäre meiner Meinung nach auch nützlich, verteilungsspezifische Methoden zum Erstellen von Binärpaketen zu verwenden.
Faheem Mitha
1
FYI: initramfssoll fast immer verwendet werden. Beispielsweise erfordert das Festlegen von Rootfs unter LVM + RAID häufig eines. Encrypted root macht das definitiv. Sogar einigermaßen komplizierte RAID-Setups sind möglich. Die
kernelinterne
2
@derobert: Das wirft die Frage auf, dass "fast immer" Linux verwendet wird, um einen Unternehmensserver zu betreiben. Mein Punkt initramfsist, dass, wenn Sie keinen benötigen, Sie dies nicht tun müssen, und dies vereinfacht den Prozess. Wie auch immer, ich habe eine Fußnote über verschlüsselte Root-
Fs
Bitte geben Sie Details zu EFI und der efi-stub-Funktionalität von Linux an.
IW16