Kernel bauen

Der Kernel kontrolliert die Hardware und bietet den Anwendungsprogrammen abstrakte Schnittstellen in Form von Gerätedateien. Man unterscheidet Block- und Stromgeräte. Blockgeräte (wie zum Beispiel die Festplatte und der Arbeitsspeicher) erlauben Lese- und Schreibzugriffe an jeder Position (Random Access. Stromgeräte (wie zum Beispiel die Tastatur oder eine Netzwerkverbindung) hingegen erlauben nur sequentielles Lesen und/oder Schreiben.

Abstraktionsschichten diverser Subsystemen
Eingabe Grafik Audio Dateisystem Netzwerk Speicher Prozess
Anwendung libevdev libdrm libalsa libc
Gerät /dev/input /dev/dri /dev/snd /dev/disk /dev/net /dev/mem /dev/cpu
Kernel-API EVDEV DRM ALSA VFS NET MM PM
Bus USB PCI PCI SCSI, SATA, IDE MMU, RAM CPU
Treiber xHCI GT3e ALC233 AHCI CNVi SRAM Intel i3-8109U
Peripherie Tastatur, Maus Bildschirm Headset Festplatte Ethernet, WiFi Speicher Prozessor

Parameter übergeben

Der Bootlader teilt dem Kernel über eine Kommandozeile mit, wo er die Initiale Ramdisk und das Wurzeldateisystem findet und welchen Prozess er als erstes im Benutzermodus ausführt. Auch Programme auf der Anwendungsschicht, wie zum Beispiel systemd und plymouth, lesen für sie bestimmte Parameter aus.

cat /proc/cmdline
initrd=\58a1af54a6c1458ca2a4655aa1bf9a38\6.1.0-30-amd64\initrd.img-6.1.0-30-amd64
root=/dev/mapper/vg-root
ro quiet splash
Liste ausgewählter Kernel-Parameter
Parameter Vorgabe Beispiel Beschreibung
acpi on off ACPI
apic quiet verbose APIC
console tty0 ttyUSB0 Gerät für Systemkonsole
debug Fehlersuchmodus
efi - nochunk EFI Einstellungen
enforcing 0 1 SELINUX aktivieren
gpt GPT-Sicherungskopie verwenden
hd C,H,S 1023,255,63 CHS-Adressierung
init /sbin/init /bin/bash Pfad zum Startprozess
initrd \initrd.img Pfad zur Initialen Ramdisk
loglevel 4 7 Meldungen auf Systemkonsole ausgeben
nfsroot /tftpboot/%s 10.0.0.7:/root Wurzeldateisystem für Rechner ohne Festplatte
root /dev/sda2 Pfad zum Wurzeldateisystem
rootwait Warte auf den Datenträger
force enable ACPI if default was off
on enable ACPI but allow fallback to DT [arm64]
off disable ACPI if default was on
noirq do not use ACPI for IRQ routing
strict Be less tolerant of platforms that are not strictly ACPI specification compliant.
rsdt prefer RSDT over (default) XSDT
copy_dsdt copy DSDT to memory
quiet
verbose
debug
ttyN Use the virtual console device. Virtuelle Konsole
ttySN[,Optionen] Serielle Konsole
ttyUSB0[,Optionen] USB Schnittstelle
uart[8250],[mm]io{16,32},Adresse[,Optionen] UART Serielle Schnittstelle
hvcN Hypervisor, z.B. Xen und PowerPC
old_map switch to the old ioremap-based EFI runtime services mapping. 32-bit still uses this one by default.
nochunk disable reading files in "chunks" in the EFI boot stub, as chunking can cause problems with some firmware implementations.
noruntime disable EFI runtime services support
debug enable misc debug output
0 Protokollieren
1 Durchsetzen
C Cylinders
H Heads
S Sectors
0 KERN_EMERG Systemausfall
1 KERN_ALERT Aktion nötig
2 KERN_CRIT Kritischer Zustand
3 KERN_ERR Fehler
4 KERN_WARNING Warnung
5 KERN_NOTICE Wichtig
6 KERN_INFO Information
7 KERN_DEBUG Fehlersuche

Nachrichten verarbeiten

Der Kernel meldet den Anschluss und die Entfernung von Geräten, sogenannte Hotplug-Ereignisse, per netlink(7)-Sockel an den udev(7)-Daemon. Dieser legt Gerätedateien unter /dev an und informiert den dbus-daemon(1). Der upowerd(8) überwacht den Batteristatus und der udisksd(8) montiert Wechseldatenträger. So kann zum Beispiel die grafische Oberfläche beim Einstecken eines USB-Geräts ein Symbol auf der Arbeitsfläche anzeigen.

Benachrichtigung beim Einstecken eines Geräts
Programm Kommando Operand Beschreibung
udevadm help Hilfe anzeigen
info /dev/... Geräteinformationen aus Datenbank
trigger /dev/... Ereignisse vom Kernel anfragen
settle Auf anstehendes Ereignis warten
control Daemon steuern
monitor Ereignisse beobachten
test Ereignis auslösen
test-builtin Kommando auslösen
udisksctl help Hilfe anzeigen
status Liste aller Geräte
info -b /dev/... Eigenschaften eines Geräts
dump Eigenschaften aller Geräte
monitor Ereignisse beobachten
mount Dateisystem montieren
unmount Dateisystem entfernen
unlock Verschlüsseltes Gerät entsperren
lock Verschlüsseltes Gerät sperren
loop-setup Schleifengerät einrichten
loop-delete Schleifengerät entfernen
power-off Gerät ausschalten
smart-simulate SMART Werte simulieren
busctl help Hilfe anzeigen
list Registrierte Namen auflisten
status [Service] Eigenschaften eines Dienstes anzeigen
monitor [Service …] Nachrichten eines Dienstes beobachten
capture [Service …] Nachrichten im pcap-Format aufzeichnen
tree [Service …] Baumstruktur eines Dienstes anzeigen
introspect Service Object [Interface]
call Service Object Interface Method [Signature [Argument …]]
set-property Service Object Interface Property Signature Argument
get-property Service Object Interface Property ...

Beispiel

busctl tree org.freedesktop.UPower
└─/org
  └─/org/freedesktop
    └─/org/freedesktop/UPower
      ├─/org/freedesktop/UPower/KbdBacklight
      ├─/org/freedesktop/UPower/Wakeups
      └─/org/freedesktop/UPower/devices
        ├─/org/freedesktop/UPower/devices/DisplayDevice
        ├─/org/freedesktop/UPower/devices/battery_BAT0
        └─/org/freedesktop/UPower/devices/line_power_AC

Prozesse isolieren

Ein Namensraum isoliert die Ressourcen, die ein Prozess und seine Kindprozesse sehen. Mit dieser Technik werden unter anderem Container umgesetzt.

mnt
Montierte Dateisysteme
pid
Prozessnummern
net
Schnittstellen, Adressen, Routen und Filterregeln
ipc
Interprozesskommunikation
uts
Hostname (UTS = Unix Timesharing System)
user
Benutzerkennungen
cgroup
Kontrollgruppe
time
Systemzeit

Ressourcen limitieren

Eine Kontrollgruppe beschränkt den Ressourcenverbrauch einer Gruppe von Prozessen bezüglich folgende Aspekte:

blkio
Zugriff auf Blockgeräte
cpu
Priorisierung
cpuacct
Rechenzeit
cpuset
Affinität für Prozessgruppen
devices
Sichtbarkeit von Geräten (mknod und open)
freezer
Anhalten von Prozessen
hugetlb
Große Speicherseiten
memory
Speicherverwaltung
net_cls
Klassifizierung von Paketen
net_prio
Priorisierung von Paketen
perf_event
Zugriff auf Leistungs-Ereignisse

Das Paket cgroup-tools enthält Programme zum Anzeigen lscgroup(1), Erzeugen cgcreate(1), Ausführen cgexec(1) und Löschen cgdelete(1) von Kontrollgruppen. Systemd erzeugt ebenfalls Kontrollgruppen für Daemonen und Sitzungen. Diese lassen sich mit systemd-cgls(1) auflisten oder mit systemd-cgtop(1) beobachten. Selbst ps(1) kann die Kontrollgruppe anzeigen.

alias psc='ps xawf -eo pid,user,cgroup,args'

Priviliegien einschränken

Capabilities schränken die Rechte von privilegierten Prozessen ein. Das im Paket libcap-ng-utils enthaltene Kommando pscap(8) zeigt alle Capabilities an. Dokumentation siehe capabilities(7).

audit_control
Ereignis-Protokoll des Kernels ein- und ausschalten, Filterregeln lesen und ändern
audit_read
Ereignis-Protokoll via Netlink-Sockel lesen
audit_write
Datensätze ins Ereignis-Protokoll schreiben
block_suspend
Suspendierung des Systems blockieren
bpf
Privilegierte BPF-Operationen ausführen
checkpoint_restore
Container einfrieren und auftauen
chown
Besitzer und Gruppe von Dateien beliebig ändern
dac_override
Zugriffsrechte von Dateien umgehen
DAC = Discretionary Access Control
dac_read_search
Zugriffsrechte von Verzeichnissen umgehen
fowner
ACLs und Flags auf Dateien setzen und einiges mehr
fsetid
Set-User- und -Group-ID-Bit beibehalten und ignorieren
ipc_lock
Speicherzugriff sperren
ipc_owner
Zugriffsrechte für System V IPC-Objekte umgehen
kill
Zugriffsrechte für das Senden von Signalen umgehen
lease
Beliebige Dateien beobachten (Signal erhalten)
linux_immutable
Dateien unveränderlich oder nur erweiterbar machen
mac_admin
Zugriffskontrollen ändern
MAC = Mandatory Access Control
mac_override
Zugriffskontrollen entkräften
mknod
Gerätedateien erzeugen
net_admin
Schnittstellen, Adressen und Routen konfigurieren
net_bind_service
Ports unter 1024 belauschen
net_broadcast
Rundmeldungen empfangen und senden
net_raw
Kommunikation auf Paketebene steuern
perfmon
Leistung beobachten
setgid
Gruppe hinzufügen oder ändern
setuid
Benutzer wechseln
setfcap
Rechte einer ausführbaren Datei setzen
setpcap
Rechte eines Ausführungsstrangs vererben
sys_admin
Sammelbecken für Diverse Systemaufrufe
sys_boot
Neustart einleiten
sys_chroot
Namensraum des Dateisystems verschieben
sys_module
Kernel-Module laden
sys_nice
Ressourcen an Prozessen zuteilen
sys_pacct
Prozess-Accounting erlauben
sys_ptrace
Andere Prozesse untersuchen
sys_rawio
Direkt auf Speicher zugreifen
sys_resource
Reservierten Speicher auf ext2-Dateisystemen nutzen
sys_time
Systemzeit und Echtzeitihr setzen
sys_tty_config
Virtuelle Terminals steuern und auflegen
syslog
Systemprotokoll schreiben

Kernel selbst bauen

Für besonders neue Hardware braucht man manchmal einen aktuellen Kernel. Dann nehmen wir die Sache selbst in die Hand und installieren zuerst Compiler, Werkzeuge und Bibliotheken.

apt install build-essential flex bison lib{elf,ssl,ncurses}-dev

Quellen herunterladen, entpacken, konfigurieren, übersetzen und installieren.

url=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
curl $url/snapshot/linux-6.2-rc6.tar.gz
tar xzf linux-6.2-rc6.tar.gz 
make nconfig
make clean
make bindeb-pkg
apt install ../linux-image-*.deb

Literatur

  1. Kernel.org: The kernel’s command-line parameters (v6.12)
  2. Simon McVittie: Why polkit (or, how to mount a disk on modern Linux) (2015)
  3. Debian Linux Kernel Handbook: Building a custom kernel from the "pristine" kernel source