Nächste: Die Image-Schnittstelle von Guix System, Vorige: Automatisch an virtueller Konsole anmelden, Nach oben: Systemkonfiguration [Inhalt][Index]
Im Kern ist Guix eine quellcodebasierte Distribution mit Substituten (siehe Substitute in Referenzhandbuch zu GNU Guix), daher ist das Erstellen von Paketen aus ihrem Quellcode heraus genauso vorgesehen wie die normale Installation und Aktualisierung von Paketen. Von diesem Standpunkt ist es sinnvoll, zu versuchen, den Zeitaufwand für das Kompilieren von Paketen zu senken, und kürzliche Neuerungen sowie Verbesserungen beim Erstellen und Verteilen von Substituten bleiben ein Diskussionsthema innerhalb von Guix.
Der Kernel braucht zwar keine übermäßigen Mengen an Arbeitsspeicher beim Erstellen, jedoch jede Menge Zeit auf einer durchschnittlichen Maschine. Die offizielle Konfiguration des Kernels umfasst, wie bei anderen GNU/Linux-Distributionen auch, besser zu viel als zu wenig. Das ist der eigentliche Grund, warum seine Erstellung so lange dauert, wenn man den Kernel aus dem Quellcode heraus erstellt.
Man kann den Linux-Kernel jedoch auch als ganz normales Paket beschreiben, das genau wie jedes andere Paket angepasst werden kann. Der Vorgang ist ein klein wenig anders, aber das liegt hauptsächlich an der Art, wie die Paketdefinition geschrieben ist.
Die linux-libre
-Kernelpaketdefinition ist tatsächlich eine Prozedur,
die ein Paket liefert.
(define* (make-linux-libre* version gnu-revision source supported-systems
#:key
(extra-version #f)
;; Eine Funktion, die eine Architektur und eine
;; Variante nimmt. Siehe kernel-config als Beispiel.
(configuration-file #f)
(defconfig "defconfig")
(extra-options (default-extra-linux-options version)))
…)
Das momentane linux-libre
-Paket zielt ab auf die 5.15.x-Serie und ist
wie folgt deklariert:
(define-public linux-libre-5.15
(make-linux-libre* linux-libre-5.15-version
linux-libre-5.15-gnu-revision
linux-libre-5.15-source
'("x86_64-linux" "i686-linux" "armhf-linux"
"aarch64-linux" "riscv64-linux")
#:configuration-file kernel-config))
Alle Schlüssel, denen kein Wert zugewiesen wird, erben ihren Vorgabewert von
der Definition von make-linux-libre
. Wenn Sie die beiden Schnipsel
oben vergleichen, ist anzumerken, dass sich der Code-Kommentar in ersterem
auf #:configuration-file
bezieht. Deswegen ist es nicht so leicht,
aus der Definition heraus eine eigene Kernel-Konfiguration anhand der
Definition zu schreiben, aber keine Sorge, es gibt andere Möglichkeiten, um
mit dem zu arbeiten, was uns gegeben wurde.
Es gibt zwei Möglichkeiten, einen Kernel mit eigener Kernel-Konfiguration zu
erzeugen. Die erste ist, eine normale .config-Datei als native
Eingabe zu unserem angepassten Kernel hinzuzufügen. Im Folgenden sehen Sie
ein Schnipsel aus der angepassten 'configure
-Phase der
make-linux-libre
-Paketdefinition:
(let ((build (assoc-ref %standard-phases 'build))
(config (assoc-ref (or native-inputs inputs) "kconfig")))
;; Wir benutzen eine eigene Kernel-Konfigurationsdatei oder eine
;; vorgegebene Konfigurationsdatei.
(if config
(begin
(copy-file config ".config")
(chmod ".config" #o666))
(invoke "make" ,defconfig)))
Nun folgt ein Beispiel-Kernel-Paket. Das linux-libre
-Paket ist nicht
anders als andere Pakete und man kann von ihm erben und seine Felder
ersetzen wie bei jedem anderen Paket.
(define-public linux-libre/E2140
(package
(inherit linux-libre)
(native-inputs
`(("kconfig" ,(local-file "E2140.config"))
,@(alist-delete "kconfig"
(package-native-inputs linux-libre))))))
Im selben Verzeichnis wie die Datei, die linux-libre-E2140
definiert,
befindet sich noch eine Datei namens E2140.config, bei der es sich um
eine richtige Kernel-Konfigurationsdatei handelt. Das Schlüsselwort
defconfig
von make-linux-libre
wird hier leer gelassen, so
dass die einzige Kernel-Konfiguration im Paket die im
native-inputs
-Feld ist.
Die zweite Möglichkeit, einen eigenen Kernel zu erzeugen, ist, einen neuen
Wert an das extra-options
-Schlüsselwort der
make-linux-libre
-Prozedur zu übergeben. Das
extra-options
-Schlüsselwort wird zusammen mit einer anderen, direkt
darunter definierten Funktion benutzt:
(define (default-extra-linux-options version) `(;; https://lists.gnu.org/archive/html/guix-devel/2014-04/msg00039.html ("CONFIG_DEVPTS_MULTIPLE_INSTANCES" . #true) ;; In der initrd benötigte Module: ("CONFIG_NET_9P" . m) ("CONFIG_NET_9P_VIRTIO" . m) ("CONFIG_VIRTIO_BLK" . m) ("CONFIG_VIRTIO_NET" . m) ("CONFIG_VIRTIO_PCI" . m) ("CONFIG_VIRTIO_BALLOON" . m) ("CONFIG_VIRTIO_MMIO" . m) ("CONFIG_FUSE_FS" . m) ("CONFIG_CIFS" . m) ("CONFIG_9P_FS" . m))) (define (config->string options) (string-join (map (match-lambda ((option . 'm) (string-append option "=m")) ((option . #true) (string-append option "=y")) ((option . #false) (string-append option "=n"))) options) "\n"))
Und im eigenen configure-Skript des „make-linux-libre“-Pakets:
;; Anhängen an die Datei ist wirksam, egal ob die Option in der Datei ;; stand. Es zählt das letzte Vorkommen. (let ((port (open-file ".config" "a")) (extra-configuration ,(config->string extra-options))) (display extra-configuration port) (close-port port)) (invoke "make" "oldconfig")
Indem wir also kein „configuration-file“ mitgeben, ist .config anfangs leer und danach schreiben wir dort die Sammlung der gewünschten Optionen („Flags“) hinein. Hier ist noch ein eigener Kernel:
(define %macbook41-full-config (append %macbook41-config-options %file-systems %efi-support %emulation ((@@ (gnu packages linux) default-extra-linux-options) version))) (define-public linux-libre-macbook41 ;; XXX: Auf die interne 'make-linux-libre*'-Prozedur zugreifen, welche privat ;; ist und nicht exportiert, des Weiteren kann sie sich in Zukunft ändern. ((@@ (gnu packages linux) make-linux-libre*) (@@ (gnu packages linux) linux-libre-version) (@@ (gnu packages linux) linux-libre-gnu-revision) (@@ (gnu packages linux) linux-libre-source) '("x86_64-linux") #:extra-version "macbook41" #:extra-options %macbook41-config-options))
Im obigen Beispiel ist %file-systems
eine Sammlung solcher „Flags“,
mit denen Unterstützung für verschiedene Dateisysteme aktiviert wird,
%efi-support
aktiviert Unterstützung für EFI und %emulation
ermöglicht es einer x86_64-linux-Maschine, auch im 32-Bit-Modus zu
arbeiten. Die Prozedur default-extra-linux-options
ist die oben
definierte, die hinzugefügt werden musste, um die vorgegebenen
Konfigurationsoptionen für das extra-options
-Schlüsselwort zu
behalten.
All das klingt machbar, aber woher weiß man überhaupt, welche Module für ein
bestimmtes System nötig sind? Es gibt zwei hilfreiche Anlaufstellen, zum
einen das
Gentoo-Handbuch, zum anderen die
Dokumentation des Kernels selbst. Aus der Kernel-Dokumentation erfahren
wir, dass make localmodconfig
der Befehl sein könnte, den wir wollen.
Um make localmodconfig
auch tatsächlich ausführen zu können, müssen
wir zunächst den Quellcode des Kernels holen und entpacken:
tar xf $(guix build linux-libre --source)
Sobald wir im Verzeichnis mit dem Quellcode sind, führen Sie touch
.config
aus, um mit einer ersten, leeren .config
anzufangen. make localmodconfig
funktioniert so, dass angeschaut
wird, was bereits in Ihrer .config steht, und Ihnen mitgeteilt wird,
was Ihnen noch fehlt. Wenn die Datei leer bleibt, fehlt eben alles. Der
nächste Schritt ist, das hier auszuführen:
guix shell -D linux-libre -- make localmodconfig
und uns die Ausgabe davon anzuschauen. Beachten Sie, dass die .config-Datei noch immer leer ist. Die Ausgabe enthält im Allgemeinen zwei Arten von Warnungen. Am Anfang der ersten steht „WARNING“ und in unserem Fall können wir sie tatsächlich ignorieren. Bei der zweiten heißt es:
module pcspkr did not have configs CONFIG_INPUT_PCSPKR
Für jede solche Zeile kopieren Sie den CONFIG_XXXX_XXXX
-Teil in die
.config im selben Verzeichnis und hängen =m
an, damit es am
Ende so aussieht:
CONFIG_INPUT_PCSPKR=m CONFIG_VIRTIO=m
Nachdem Sie alle Konfigurationsoptionen kopiert haben, führen Sie noch
einmal make localmodconfig
aus, um sicherzugehen, dass es keine
Ausgaben mehr gibt, deren erstes Wort „module“ ist. Zusätzlich zu diesen
maschinenspezifischen Modulen gibt es noch ein paar mehr, die Sie auch
brauchen. CONFIG_MODULES
brauchen Sie, damit Sie Module getrennt
erstellen und laden können und nicht alles im Kernel eingebaut sein
muss. Sie brauchen auch CONFIG_BLK_DEV_SD
, um von Festplatten lesen
zu können. Möglicherweise gibt es auch sonst noch Module, die Sie brauchen
werden.
Die Absicht hinter dem hier Niedergeschriebenen ist nicht, eine Anleitung zum Konfigurieren eines eigenen Kernels zu sein. Wenn Sie also vorhaben, den Kernel an Ihre ganz eigenen Bedürfnisse anzupassen, werden Sie in anderen Anleitungen fündig.
Die zweite Möglichkeit, die Kernel-Konfiguration einzurichten, benutzt mehr von Guix’ Funktionalitäten und sie ermöglicht es Ihnen, Gemeinsamkeiten von Konfigurationen zwischen verschiedenen Kernels zu teilen. Zum Beispiel wird eine Reihe von EFI-Konfigurationsoptionen von allen Maschinen, die EFI benutzen, benötigt. Wahrscheinlich haben all diese Kernels eine Schnittmenge zu unterstützender Dateisysteme. Indem Sie Variable benutzen, können Sie leicht auf einen Schlag sehen, welche Funktionalitäten aktiviert sind, und gleichzeitig sicherstellen, dass Ihnen nicht Funktionalitäten des einen Kernels im anderen fehlen.
Was wir hierbei nicht erläutert haben, ist, wie Guix’ initrd und dessen Anpassung funktioniert. Wahrscheinlich werden Sie auf einer Maschine mit eigenem Kernel die initrd verändern müssen, weil sonst versucht wird, bestimmte Module in die initrd einzubinden, die Sie gar nicht erstellen haben lassen.
Nächste: Die Image-Schnittstelle von Guix System, Vorige: Automatisch an virtueller Konsole anmelden, Nach oben: Systemkonfiguration [Inhalt][Index]