UEFI/Bootloader
UEFI geeignete Bootloader
Bootloader sind kleine Programme, die beim Systemstart von der Firmware des Rechners gestartet werden können und deren Aufgabe es ist, ein Betriebssystem zu starten. In der Vergangenheit waren eine Vielzahl von Bootloadern in der Linuxwelt möglich, über eine lange Zeit war GRUB bei vielen Distributionen der Standard und wegen seiner Möglichkeiten und einfachen Konfiguration auch sehr beliebt.
Unter UEFI hat sich nicht nur die Art des Bootvorganges geändert, auch das Binärformat für den Bootloader und eine Reihe von weiteren notwendigen Anforderungen machte es erforderlich, für UEFI neue Bootloader zu entwickeln.
Inhaltsverzeichnis
UEFI kann Linuxkernel direkt booten
UEFI kann den Kernel für das Betriebssystem auch ohne die Benutzung eines Bootloaders selbst laden (Efi Boot Stub), und auch die für den Startvorgang eventuell zusätzlich notwendigen Kernel Optionen können in den UEFI Boot Konfiguration angegeben werden. Der Linux Kernel muss dazu allerdings entsprechend konfiguriert werden, damit er auch in einem von UEFI akzeptierten Binary-Layout vorliegt. Diese Erweiterungen sind im Linuxkernel schon längere Zeit enthalten und die dafür notwendige Kernelkonfiguration "CONFIG_EFI_STUB enabled" ist in den meisten Kerneln auch per default gesetzt. Es sind nicht alle möglichen Komprimierungsverfahren des fertigen Kernels geeignet und es werden dafür nur vmlinuz und bzImage als Kernel-Verpackungen unterstützt.
Der fertige vmlinuz oder bzImage Kernel braucht jetzt nur im Dateinamen den Prefix ".efi" und muss vom UEFI lesbar abgelegt sein. Auch die meistens benötigte initrd muss von UEFI lesbar abgelegt sein. Damit ist ein direkter UEFI Boot schon möglich.
Nachteile
Da UEFI per default nur VFAT Dateisysteme lesen kann, müsste der Kernel in einem solchem abgelegt werden, typischerweise auf der UEFI-Partiton. VFAT kennt keine UNIX Dateirechte, die Dateirechte von solchen Dateisystemen müssen für Linux immer simuliert werden und sind nicht wirklich kompatibel, womit für den Kernel und die initrd keine sicheren Zugriffsrechte vorhanden sind. Der Kernel und die initrd sind auch oftmals große Dateien und das dort typischerweise angelegte Dateisystem nicht sehr groß. Für Linux ist /boot als Kernelverzeichnis typisch und wird von allen Scripten und Programmen auch dort gesucht. Unter /boot/efi wird das UEFI-Dateisystem zusätzlich gemountet. Der Kernel und die initrd müssten also irgendwie immer zusätzlich umbenannt und noch in das UEFI Filesystem zusätzlich hinein kopiert werden, damit existieren dann aber auch immer 2 eigentlich gleiche Dateien. Für Kernel Updates, Erzeugen von initrd und ähnlichem ist dieses sehr unpraktisch. Auch ist der Kernel und die initrd dort in dieser UEFI-Partition nicht wirklich sicher vor Manipulationen. Erweiterungen von UEFI durch weitere UEFI Filesystemtreiber zu konfigurieren, um so den Kernel und die Initrd direkt aus dem orginal /boot Verzeichnis von Linux zu lesen, ist theoretisch möglich, jedoch wegen der Komplexität und der Problematiken von Secureboot wohl nur bei Spezilafällen sinnvoll.
Secure Boot
Die Linux Kernel aus den Distributionen werden mit dem Zertifikat der Distribution signiert, könnten aber auch zusätzlich mit einem privaten Zertifikat signiert werden. Allerdings sind typischerweise im UEFI nur die Zertifikate des Herstellers und von Microsoft enthalten. Secure Boot ist also nur dort möglich, wo es möglich ist, entweder das Zertifikat der Distribution oder das private Zertifikat in die Secure-Datenbank des UEFI zu bekommen. Der Umweg über shim ist hier nur mit einem weiteren Bootloader dazwischen möglich, da mit shim alleine dem kernel keine Optionen mitgegeben werden können. Bedeutet in Summe, Secure Boot ist beim Booten des Kernels direkt von UEFI nur möglich, wenn zum Kernel passende Zertifikate im UEFI hinterlegt sind.
GRUB Legacy
Der Quellcode von grub legacy wird schon seit langen nicht mehr gewartet und die Verwendbarkeit seit Jahren nur mit immer mehr Patches aufrechterhalten. Es gibt massenweise Patches, auch für die Unterstützung von GPT und EFI. Unter Suse sind aber keine ernsthaften Bemühungen zu erkennen, den alten grub UEFI-tauglich zu erhalten. Patches und Pakete in diese Richtung sind vor allem aus der Umgebung von Fedora-Redhat-CentOs zu finden, aber auch dort hat man Grub schon aufgegeben.
Da die Binary von Bootloadern vollkommen unabhängig vom Betriebssystem funktionieren, ist es aber möglich diese Dateien auch aus Paketen einer anderen Distribution auf seinem eigenen Rechner einzusetzen. Möglich ist z.B. die 2 Pakete grub und grub-efi von Fedora17 dafür zu verwenden. Möglich, dass die eine oder andere Distribution derzeit noch einen UEFI fähigen grub legacy anbietet, eine Zukunft dafür gibt es sicher nicht mehr. Es ist leider an der Zeit, uns von unserem guten alten GRUB endgültig zu verabschieden. Es ist noch mit einiger Handarbeit möglich, Grub unter UEFI einzusetzen - es wird aber dringend davon abgeraten. Der Quell-Code von Grub ist zu alt und größtenteils explizit für 32 Bit CPUs geschrieben, schlecht gewartet und nur elementar an die Erfordernisse und Gegebenheiten von UEFI angepasst.
Experimenteller Test
- Voraussetzung /boot ist auf ext2 ext3 oder ext4 und nicht etwa btrfs
- Folgende 2 Pakete von Fedora17 downloaden grub und grub-efi
- diese beide Pakete zB mit ark öffnen und aus dem Grub Paket alle Dateien unterhalb /usr/share/grub/x86_64-redhat/ nach /boot/grub kopieren
- aus der grub-efi die /boot/efi/EFI/redhat/grub.efi nach /boot/efi/EFI/redhat/grub.efi in unser System kopieren.
- aus dem grub Paket noch unter /usr/share/doc/grub-0.97 die Datei menu.lst nach /boot/efi/EFI/redhat/ kopieren und umbennen in grub.conf
- /boot/efi/EFI/redhat/grub.conf konfigurieren, (Syntax wie bei menu.lst, hat hier nur einen anderen Namen)
Beispiel:
default 0 timeout 8 title Test openSUSE 13.1 mit grub-0.97 unter UEFI root (hd0,2) kernel (hd0,2)/boot/vmlinuz root=/dev/sda3 resume=/dev/sda2 splash=silent quiet showopts initrd (hd0,2)/boot/initrd
Aus Linux heraus einen entsprechenden Booteintrag erzeugen
efibootmgr -c -d /dev/sda -p 1 -L grublegacy -l \\EFI\\redhat\\grub.efi
Grub sollte sich bei ausgeschaltetem Secure Boot von UEFI aus starten lassen und wenn die grub.conf passt, sollte das Betriebssystem booten.
Secure Boot
Für Secure Boot ist Grub Legacy absolut nicht geeignet. Das grub.efi Binary von fedora 17 lässt sich auch nicht mit einem Zertifikat signieren. Damit könnte man Grub Legacy nicht einmal hinter Shim im Secure Boot Modus betreiben.
GRUB2
GRUB_2 ist schon seit einigen Jahren im Umfeld des Bootens vom BIOS bekannt. Für die Funktionalität auch im UEFI Umfeld zu arbeiten werden Grub2-Binaries auf der ESP hinterlegt, mit denen der Bootvorgang dann analog angestoßen wird. Es sind 2 Binaries zu unterscheiden grub.efi und grubx64.efi. Der Unterschied liegt hier in der Anzahl und Auswahl der Module die mit in das binary gepackt sind. Ohne Secureboot könnte von beiden gestartet werden, bei Secureboot wird grub.efi benötigt und auch automatisch von Shim aufgerufen.
Neben diesen beiden Grub-Binary gibt es dort noch eine grub.cfg, sie enthält nur wenige Zeilen und beinhaltet das Laufwerk und die Bezeichnung der richtigen grub.cfg mit der Grub Konfiguration für das booten.
Die Dateien am Beispiel OpenSuse:
# ls -l EFI/opensuse/gru* -rwxrwxr-x 1 root root 125 22. Feb 2015 EFI/opensuse/grub.cfg -rwxrwxr-x 1 root root 887416 22. Feb 2015 EFI/opensuse/grub.efi -rwxrwxr-x 1 root root 122864 14. Mai 23:58 EFI/opensuse/grubx64.efi # cat EFI/opensuse/gru*.cfg search --fs-uuid --set=root dd1b2dc0-ec67-48cc-9251-d31678bf322a set prefix=(${root})/boot/grub2 configfile $prefix/grub.cfg
Grub2 wird von den meisten Distributionen derzeit als Standard für UEFI Boot verwendet, dementsprechend gut ist auch die Unterstützung mit Konfigurationstools (zB YAST) und bei der Installation, so das in diesem Zusammenhang in aller Regel nichts manuell konfiguriert werden muss.
ELILO
elilo ist ein einfacher UEFI Bootloader der nicht nur mit dem Namen an LILO erinnert. Er ermöglicht nur das booten von Linux und hat ähnliche Möglichkeiten wie viele Bootloader die wir in den letzten Jahren als Bootloader auf Install-DVDs gesehen haben. Er kann beim Booten einen Defaulteintrag booten, (auch Netzwerkboot ist möglich) und kann mit einem Fallback Booteintrag konfiguriert werde, der dann bootet, wenn der Defaulteintrag fehl schlägt.
Darüber hinaus kann er so konfiguriert werden, dass beim booten aus mehreren Booteinträgen mittels Textmenü ein Eintrag ausgewählt werden kann, und auch diesen Eintrag ändern zu können.
Derzeit wird elilo noch von einigen Distributionen als Paket angeboten, doch da sich die meisten großen Distributionen auf andere UEFI-Bootloader eingeschossen haben, ruht die Entwicklung von elilo derzeit eingestellt.
Nutzungsmöglichkeiten
Bei elilo müssen sowohl das Bootloaderbinary sowie eine Konfigurationsdatei, und ebenfalls Kernel und initrd vom UEFI lesbar sein, also entweder sich auf der UEFI-Partition oder eines anderen VFAT-Dateisystems befinden. Alternativ müssten im UEFI erst Treiber für andere Dateisysteme geladen werden um zB Kernel und initrd aus den Linuxdateisystemen direkt heraus nutzen zu können. Dieses beschränkt die praktikable Nutzbarkeit von elilo ein, da in einem aktiven Linux System zB nach Kernelupdates oder nach dem Erstellen einer neuen initrd die elilo-Konfiguration erst wieder angepasst werden müsste, dazu sind entweder intelligente Scripte notwendig oder dieses per Hand erledigt werden müsste
Ideal ließe sich elilo überall einsetzen, wo es keine solchen Kernel Updates geben wird, oder geben kann. zB auf bootbaren DVDs und ähnlichen. Praktisch auch gut einsetzbar bei einem System welches remote administriert wird und normalerweise über das Netz gebootet werden soll. Sollte der Netzboot einmal nicht funktionieren, würde elilo einen für solche Fälle konfigurierbaren Alternativen Booteintrag booten, somit das System danach remote hoffentlich trotzdem wieder erreichbar sein.
Installation manuell
Bei Opensuse 13.1) ist elilo per default bei einer Installation auf UEFI nicht mit installiert, das Paket aber vorhanden
Eine Installation des Paketes ist sehr einfach z.B mittels "zypper in elilo"
Im Paket bei Opensuse 13.1 sind neben sehr dürftigen Manpages und den (einigermaßen hilfreichen) normalen Paketdokumentationen nur 3 Dateien:
- der UEFI Bootloader als Binary /usr/lib64/efi/elilo.efi
- Perlscript /sbin/elilo gedacht für die Verwaltung der Booteinträge
- Perlscript /sbin/eliloalt gedacht für die Verwaltung des Alternativen ( Fallback) Booteintrages.
Die beiden Perlscripte, die sich hier im Opensuse Paket befinden, stammen aus dem Umfeld von SLES, bitte mit Vorsicht zu genießen, Sie waren hier bei den Tests weder wirklich hilfreich für Installation noch für Konfiguration. Was sie zB bei einem Kernelupdate oder beim Erstellen einer neuen initrd bewirken oder nicht, wurde gar nicht erst untersucht.
Andere Distributionen haben eventuelle eigene Scripte dafür, die eventuell auch anderes und besser funktionieren. Sie weiteren Ausführungen auf dieser Seite gehen jedoch davon aus, dass diese Scripte überhaupt nicht benutzt werden, und die Installation und Konfiguration manuell erfolgt. Das wird hinsichtlich des aktuellen Projektstatus auch in Zukunft immer noch genauso funktionieren, auch wenn die Distributionen die offizielle Unterstützung vollkommen aufgeben.
Das Binary "/usr/lib64/efi/elilo.efi" sowie den oder die Kernel und initrd Dateien sind auf die UEFI-Partition zu kopieren, (zB. nach /boot/efi/EFI/opensuse/). In dieses Verzeichnis muss ebenfalls eine Konfigurationsdatei elilo.conf vorhanden sein. Diese kann relativ einfach manuell erstellt werden. (Weitere Konfigurationsdateien werden für eine optionale Konfiguration für eine Menüauswahl erforderlich und können zB mit Hilfe der Demo Dateien aus dem Projekt erstellt werden)
Konfiguration
Die Syntax der Konfigurationsdatei ist einfach und ähnlich wie sie auch schon bei LILO verwendet wurde.
Beispiel einer elilo.conf
# ELILO Konfiguration fuer den Textmenu-Chooser #---------------------------------------- #chooser=textmenu #message=textmenu-message.msg #f1=general.msg #f2=params.msg #----------------------------------------- default=linux image=atapi2:/boot/bzImage-3.11.10-4-desktop label="eigener_kernel" initrd=atapi2:/boot/initrd-3.11.10-4-desktop read-only root=/dev/sda3 append="resume=/dev/sda2 splash=silent quiet showopts" image=vmlinuz-3.11.6-4-desktop label="linux" initrd=initrd-3.11.10-4-desktop read-only root=/dev/sda3 append="resume=/dev/sda2 splash=silent quiet showopts"
Erklärungen zur Konfiguration:
Es sind 2 Bootoptionen konfiguriert, default ist hier die 2. Eintrag mit dem Label="linux". Der Kernel und die Konfiguration für diese Option befinden sich im selben Verzeichnis wie das Binary elilo.efi.
Die erste Bootoption mit Label "eigener_kernel" befindet sich auf einem anderem Dateisystem. ("atapi2:" ist dabei eine elilo eigene Bezeichnung für dieses Filesystem, siehe dazu die Doku und nutze den interaktiven Modus von elilo mit dem "chooser=simple" zum ermitteln der genauen Bezeichnung für deine spezielle Konfiguration.)
Im oberen Teil auskonfiguriert sind die Optionen für "chooser=textmenu" in diesem Fall hier wurden die elilo Demodateien verwendet.
Bei der Konfiguration des Bootloaders ist dann im UEFI-Syntax die Datei "\EFI\opensuse\elilo.efi" als Bootloadervariable anzulegen.
elilo startet den default-Eintrag oder den ersten Eintrag aus der Konfiguration nach Ablauf des timeout automatisch. Beim Betätigen einer Taste vom dem Ablauf des timeout wird der interaktive Mode gestartet. (welcher Mode entscheidet die Chooser-Option) Der Interaktive Mode kann aber durch die prompt Option entweder innerhalb der Konfiguration oder beim Start von elilo forciert werden
Ist die Option Chooser Textmenu konfiguriert mit den entsprechenden Konfigurationsdateien, dann wird die Menuauswahl gestartet, ansonsten ohne Chooser Konfiguration das interne "Simple", welches eine etwas gewöhnungsbedürftige Text-basierende Auswahl- und Konfigurationsmöglichkeit darstellt.
elilo kann auch mit Optionen direkt aus der EFI-Shell gestartet werden, oder dort mit Hilfe von elilo ein mit Optionen spezifizierter Bootvorgang eingeleitet werden, der nicht in der Konfiguration steht.
Hilfe zu allen Optionen der Konfigurationsdatei, und den Startoptionen von elilo sind in der Doku enthalten oder können auf der Projektseite nachgelesen werden.
Secure Boot
elilo kann mit shim im Secure Boot betrieben werden. Das Binary aus opensuse und shim aus opensuse sowie die orginal von opensuse signierten Kernel booten ohne Problem auch im Secure boot. (Allerdings ist im Opensuse shim "grub.efi" als einziger möglicher Bootloadernamen im shim binary fest hinterlegt. Die Datei elilo.efi müsste also für diesen Zweck in grub.efi umbenannt werden damit das funktioniert.) Andere oder eigene Kernel müssten signiert werden und das Zertifikat im MOK eingetragen werden. (siehe dazu shim)
rEFInd
rEFInd kommt ursprünglich aus der Mac OS X Welt, ist aber für Linux genauso gut geeignet. rEFInd sucht alles mögliche bootbare ob EFI oder MBR basierend, Bootmanager, Linux-Kernel, Windows-Bootloader und auch sonstigen UEFI-Applikatione die es finden kann. Dabei werden auch per default einige nützliche UEFI Tools gesucht und wenn vorhanden ebenfalls angezeigt, wie EFI-Shell MokManager Speichertest .....
Das alles wird dann im Bootmanager schön mit passenden Icons angezeigt und kann von dort gestartet werden. Es werden so alle möglichen Bootmanager angezeigt, die sich derzeit auf dem Rechner befinden, ob nun auf einer CD/DVD irgendwo in einem der MBR einer Platte oder alle gefunden UEFI-Bootloader sowie auch Kernel die er irgendwo finden kann und das alles automatisch ohne all dieses vorher zu konfigurieren. Es ist ein (schwarzer) Bildschirmschoner möglich, Icons für Reboot, Ausschalten und BIOS-Setup .... Ein echter Überflieger, wenn man viele Bootloader im System hat, oder sonst wie mit all seinen Bootmöglichkeiten den Überblick verloren hat.
rEFInd bringt eine ganze Reihe von UEFI-Treibern (read only) für unterschiedliche Dateisysteme mit (ext2 ext4 btrfs hfs iso9660 ntfs reiserfs)
Damit können auch Kernel und Bootloader gefunden werden, die sich nicht auf der UEFI-Partition oder in einem VFAT Dateisystem befinden.
Installation und Konfiguration
Einige Distributionen unterstützen rEFInd als default Bootloader, bei allen anderen kann man aber das Binär Paket von der Projektseite problemlos benutzen.
Bei Opensuse gibt es default keine Pakete. Es reicht das Standard-binär-Paket als zip (eventuell geht auch das rpm Paket, welches das Install-Script bei der Installation gleich mit ausführen würde). Aktuelle Version 0.8.7 downloaden, entpacken und in das Verzeichnis wechseln. Benötigt wird zum Installieren nur das install.sh Script. die beiden anderen Scripte (eines zum Konfigurieren des aktuellen Systems und eines zum Verschieben der rEFInd-Dateien auf die UEFI-Partition) werden automatisch dabei mit ausgeführt.
install.sh ausführen, und fertig. rebooten und staunen.
Das mkrlconf.sh könnte jederzeit von jedem Linux-System auf dem Rechner benutzt werden, um damit von jedem installiertem Linuxsystem eine refind config Datei in das entsprechende /boot der Installation zu schreiben. (bzw nach Umzug oder Plattentausch dieses wieder anzupassen) Damit werden die richtigen und speziellen Kernelparameter für dieses installierte System in eine refind Konfigdatei geschrieben, und refind kann anschließend den nackten Kernel booten und sich die weiteren Optionen für das Starten aus dieser Konfig-Datei holen. Beim booten eines solchen Kernels hat man dann damit auch über F2 noch zusätzlich die Auswahl auch in den SingleUserMode uÄ. zu booten.
Per default wir von den zusätzlichen UEFI-Dateisystemtreiber nur der passende Treiber für das Dateisystem installiert, aus dem refind installiert wird. Die anderen Treiber lassen sich aber jederzeit manuell in das Treiberverzeichnis von refind auf der UEFI-Partition kopieren und werden dann automatisch auch genutzt.
Mit der Konfigurationsdatei refind.conf kann man das Aussehen und die Funktionen gegebenenfalls auch noch anpassen. (siehe hierzu)
Netzwerkboot wird ebenfalls unterstützt (für diesen Artikel noch nicht getestet, eventuell müssten die beiden binaries ipxe_discovery.efi und ipxe.efi nach tools\ auf die UEFI-Partition kopiert werden)
Secure Boot
refind kann problemlos hinter shim verwendet werden, in dem das Zertifikat mit die Binardateien von refind signiert sind im MOK eingetragen werden. Das Zertifikat (sowie eine ganze Reihe weiterer gebräuchlicher public Zertifikate sind im Binärpaket mit enthalten.) SHIM von Opensuse verlangt allerdings grub.efi als Bootloadernamen den er aufruft. Die refind Binärdatei müsste also in diesen Namen umbenannt werden. Weitere Lizenzen müssten gegebenfalls für die einzelnen zu startenden Bootloader, Kernel und UEFI-Applikationen im MOK eingetragen werden, soweit sie in der Datenbank vom UEFI in Shim oder MOK nicht schon vorhanden sind.
Gummiboot SD-Boot Systemd-boot
Gummiboot ist, bzw. war ein minimalistischer UEFI Bootloader. Als optionales Paket in vielen Distributionen enthalten, wurde jedoch wenig genutzt. Ebenso wie ELILO ist auch er angewiesen darauf, das der Kernel und die Initrd im ESP oder auf einer weiteren VFAT Partition abgelegt ist, bzw. (aber nicht vorgesehen) die UEFI Funktionalität mit UEFI-Treibern auf andere Filesystemtypen erweitert wurde. Installation des Bootloaders einfach mit dem Befehl
gummiboot install
Weitere Optionen wie update, status und remove. Die Bootoptionen sind unterhalb von loader/entries/ auf der EFI-Partition oder einer weiteren VFAT Partition abgelegt und werden in der Regel mit Scripten erstellt. Diese Partitionen sind von Linux zu mounten. Die einzelnen Booteinträge haben im Namen die Maschinen-ID und die OS-ID, sowie die Endung "conf". Die Einträge innerhalb einer solchen Bootkonfiguration sind teilweise angelehnt an die grub-legacy Schreibweise. Gummiboot könnte auch hinter shim beim Secureboot verwendet werden. Eine komplette Übersicht über die Bootspezifikation von Gummiboot.
Anders als zB. bei Grub2 könnte auch durch die andere Lizenzierung der Software eventuell auch eine direkte Signierung für UEFI Secureboot angestrebt werden.
In der Zwischenzeit wurde das Projekt eingestampft. Alle Pakete wurden aus dem Git Repository für Gummiboot gelöscht und das Paket wurde als obsolet erklärt.
Allerdings bedeutet dieses noch nicht das Ende von Gummiboot, denn der Code wurde mit der fadenscheinigen Begründung, mehr Kontrolle über den UEFI Bootvorgang zu benötigen, in Systemd aufgenommen und die Funktion nennt sich jetzt SD-Boot oder nach einer weiteren Namensänderung systemd-boot. Um zu begründen warum systemd jetzt auch noch einen integrierten eigenen Bootloader braucht, wurde ein BootLoaderInterface erfunden mit dem ein paar Zeitinformationen an systemd übermittelt werden können. Na gut, wer's braucht. Interessanter dürfte sein, was man sich auf systemd Seite noch einfallen lassen wird, um die Distributionen zu zwingen/überreden auf grub2 zu verzichten und statt dessen per default auf systemd-boot zu setzen. Man darf durchaus gespannt sein, wann und wer diese durchgeknallte Entwicklung mit samt seinem Hauptentwickler hin zu einem undurchsichtigen und alles kontrollieren wollenden Riesenmonster Namens systemd endlich Einhalt gebieten will.
Syslinux
Syslinux ist eine Sammlung kleiner Bootloader für Spezialanwendungen. Häufig waren in der Vergangenheit diese Bootloader zB. beim Netzboot oder beim Booten von CD/DVD uÄ. anzutreffen. Die Funktionalität die Konfiguration und das Erscheinungsbild ähnelt LILO.
Auch hier wurde versucht das Booten mittels UEFI einzuarbeiten. Bei den Tests im Rahmen der Entwicklung dieses Artikels haben sich jedoch viele Versionsabhängikeiten, Ausnahmen und Einschränkungen gezeigt. Teils war das auch dem geschuldet, dass die meisten unserer Tests auf VMs gemacht wurden und dort die Unterstützung von Syslinux derzeit für UEFI nicht sehr umfassend ausfällt, im Klartext hat nicht viel funktioniert. Wer aus welchem Grund auch immer Bootloader aus Syslinux auch im UEFI-Umfeld einsetzen möchte, sollte sich besser vorher gründlich damit befassen und ausgiebig testen ob die benötigten Funktionen in den vorliegenden Versionen funktionieren.
SHIM
Bei shim handelt es sich nicht um einen Bootloader im eigentlichem Sinn, welcher ein Operatingsystem direkt booten kann. Vielmehr kann man sich shim vorstellen wie eine Unterlegscheibe unter einem Bootloader der die Kompatibilität des Bootloaders mit Secure Boot herstellt.
Beim Secure Boot können nur Treiber, Applikationen, Bootloader und Kernel geladen und gestartet werden, wenn sie mit einem Zertifikat signiert sind, das sich in der Secure Datenbank des UEFI befindet. Diese Tools signieren kann nur der, der den privaten Schlüssel eines dieser Zertifikate hat. Die Datenbank wird schon währende des Herstellungsprozesses angelegt und weitere Einträge in diese Datenbank kann nur jemand machen, der private Schlüssel zu dieser Datenbank hat. Praktisch kann also nur der HW-Hersteller und Microsoft dort Einträge machen, und auch nur diese sind damit in der Lage, mit ihrem Schlüssel einen Bootloader, UEFI-Treiber oder Kernel zu signieren, damit dieser im Secure Boot funktioniert. Dieses stellt ein Problem für Linux, da nicht nur die Bootloader sondern z.B. auch die Kernel welcher der Bootloader über UEFI laden will beim Booten gegen diese Datenbank überprüft werden.
OpenSuse und viele andere Distributionen haben sich derzeit bei Secure Boot für den "Umweg" über shim entschieden.
Arbeitsweise von shim
Shim bietet eine Art Erweiterung der UEFI-Datenbank. Shim selbst wird von den Distributionen eingereicht zum signieren mit einem der Microsoft Keys, bzw. es kann auch signiert von der Entwicklerseite downgeloadet werden. Shim kann mit diesem Schlüssel somit erst einmal im Secure Boot Modus starten. Die Aufgabe von Shim ist es, dann einen "richtigen" Bootloader zu laden und zu starten und zu überwachen, welchen Kernel dieser lädt. Der Bootloader, den shim aufruft, muss mit einem Zertifikat signiert sein, welches entweder die UEFI-Datenbank kennt (dann bräuchten wir shim auch nicht), oder welches shim bekannt ist. Das gleiche trifft dann auch auf den Kernel zu, der vom Bootloader geladen werden soll. Dieser muss ebenfalls signiert sein.
Hier liegt jetzt der Unterschied, Bootloader und Kernel müssen von Microsoft signiert werden, sondern es reicht wenn sie eine Signatur tragen die wir Shim bekannt geben.
In der Praxis wird ein shim-binary, welchem intern das Zertifikat des Build-Services der Distribution schon eingepflanzt ist, bei Microsoft zur Signierung eingereicht. Mit diesem signierten shim binary lassen sich dann der von der Distribution signierte Bootloader und auch alle von der Distribution signiert Kernel im Secure Boot Modus starten. Die Distribution kann Kernel und Bootloader patchen und braucht nur diese neuen Binaries mit ihrem eigenem Zertifikat zu signieren, und alles funktioniert im Secure Boot, auch ohne dass hierzu irgendwas wieder neu bei Microsoft signiert werden muß.
Was damit so erst einmal noch nicht geht, z.B. dem Bootloader einer andere Linuxdistribution starten oder eigene Kernel starten. Diese sind entweder nicht oder mit einem für die UEFI-Datenbank und ebenfalls für shim unbekanntem Zertifikat signiert.
Die MOK-Liste
Um auch andere Bootloader verwenden zu können, UEFI-Treiber oder andere UEFI-Tools die nicht von einem vom shim bekannten Zertifikat signiert sind, bzw. auch andere Kernel im Secure Boot starten zu können, gibt es mit shim eine Art Erweiterung der Secure UEFI-Datenbank. Diese Erweiterung funktioniert analog der WhiteList aus der UEFI-Secure Datenbank. In ihr können Zertifikate und Hash-Werte von Binaries hinterlegt werden, die shim akzeptieren soll. Diese shim eigene Erweiterung nennt sich MOK Liste (MOK Machine Owner Key). Eintragungen in diese Liste können mehr oder weniger nur vom einem physikalisch am Rechner befindlichen User vor dem Booten des Rechners vorgenommen werden. Die UEFI-Variable, welche diese Wert speichert, ist zwar bei jedem Start von UEFI bekannt, hat aber nur eine Lebenszeit bis der Bootloader den Start des Betriebssystems an den UEFI meldet, ist also später auf Betriebssystem-Ebene nicht mehr vorhanden und kann deshalb auch z.B. von Malware nicht manipuliert werden.
Das Programm, mit dem solche Eintragungen vom User bei Bedarf selbst vorgenommen werden können, trägt den Namen MokManager.efi und ist Bestandteil des shim-Paketes. Das Binary befindet sich im gleichem Verzeichnis wie shim auf der UEFI-Partition.
Installation und Konfiguration
Bei der Installation des Betriebssystems soweit "Secure boot" angekreuzt wird, bzw bei nachträglicher Installation des shim-paketes läuft die Installation und Konfiguration in Verbindung mit grub2 automatisch. Damit braucht man sich in aller Regel gar nicht zu befassen.
Möchte man später mit grub2 einen Kernel booten, der nicht von der Distribution signiert ist, muss dafür manuell der MokManager gestartet werden. Secure Boot ist in diesem Fall auszuschalten, da wir den MokManager in diesem Fall nicht über shim starten. Entweder das UEFI-Setup erlaubt es, manuell eine Applikation oder Bootloader direkt zu starten, oder man kann eine EFI-Shell dazu verwenden, oder man richtet sich von Linux aus mit Hilfe von efibootmgr einen temporären Booteintrag dafür ein.
MokManager.efi hat beim Start einen 10 Sekunden Timer, diesen mit irgend einer Cursor Taste abbrechen und dann hat man nebenstehenden Bildschirm. Zur Auswahl stehen Zertifikate (Key) in die MOK-List aufzunehmen oder Hash-Werte von ausführbaren Binärdateien in die MOK-List aufzunehmen.
Das Zertifikat, welches man in die MOK-List eintragen möchte (benötigt wird hierzu das DER-Format), muss man sich vorher schon auf ein FAT Verzeichnis kopiert haben. Hier kann man jetzt interaktiv die Partition auswählen und sich bis zur gewünschten Keydatei durch das Dateisystem hangeln.
Hat man die Keydatei ausgewählt, kann man mit "1" sich noch einmal an den Keydaten vergewissern, dass dieses auch das richtige Zertifikat ist, und dann nach "0" (weiter) und anschließend mit "y" oder "n" entscheiden, ob man dieses Zertifikat in die MOK-List ausrollen möchte. Danach entweder das Dateisystem wieder zurück bis Anfang oder noch mehr Keys ausrollen.
Bei den Hash ist es analog, dieses ist z.B. geeignet für UEFI-Programme, die nicht signiert sind und die man auch nicht mit einem eigenem Zertifikat signieren möchte.
Sollte man anstatt Grub2 hinter shim einen anderen Bootloader wünschen, ist dieses auch möglich z.B. für rEFInd oder ELILO. Die Konfiguration des gewünschten anderen Bootloaders bei ausgeschalteten Secure Boot komplett fertig machen und testen. Das Bootloaderbinary überprüfen mit welchem Key es signiert ist, bzw diese selbst signieren und das entsprechende Zertifikat auf ein VFAT-Dateisystem für den Import in die MOK-List vorbereiten. Danach shim.efi und MokManger.efi in das Verzeichnis dieses Bootloaders kopieren. Das Binärprogramm des Bootloaders muss umbenannt werden, da shim wahrscheinlich von den Distributionen so konfiguriert wurde, dass es nur den Namen grub.efi als Bootmanager akzeptiert. Also eine Kopie dieses Bootloader Binary als grub.efi dort im Verzeichnis anlegen. Danach muss nur ein Booteintrag für den Shim neu erstellt werden. Ist das alles so richtig, dann sollte das System mit ausgeschalteten Secure Boot jetzt auch schon über shim booten.
Nach dem Einschalten von Secure Boot wird shim dann aber gegebenenfalls feststellen, dass der neue Bootloader mit einem anderem Zertifikat signiert ist, und wird von sich aus gleich den MokManager starten. Hat man das Zertifikat jetzt schon im richtigen Format auf einer FAT-Partition im System, kann man es sofort hier in die MOK-List eintragen. Und nach einem Neustart im Secure Mode schauen, ob der Rechner jetzt über shim und dem anderem Bootloader sauber bootet.
Siehe hierfür auch Secure Boot.