Linux starten met UEFI
De UEFI-start van Linux
Wil je je kunnen redden als er een keer iets misgaat bij de UEFI-boot van Linux? Maak je dan vertrouwd met de opstartprocedure.
UEFI is anders. De trucs die je hebt geleerd voor klassieke BIOS-versies helpen je dus niet als Linux niet op gang komt als het via UEFI opstart. Integendeel, de oude trucs kunnen de UEFIopstartproblemen zelfs verergeren. Bestudeer daarom liever de opstartprocedure van een Linux die met UEFI boot, zodat je de juiste trucs kent als het starten via UEFI eens een keer misgaat. Centraal staan de UEFI-boot-variabelen en de EFI-loader waarmee de moderne UEFIBIOS-systemen de besturingssystemen starten via UEFI-mechanismen (zie pagina 124). Het verraderlijke is dat de besturingssystemen de opstartvariabelen bij de installatie opslaan in een geheugengebied (in NVRAM) op het moederbord. Het kan dus gebeuren dat geïnstalleerde besturingssystemen niet meer opstarten als je dat vervangt of de systeemschijf in een andere pc plaatst. Met een truc starten veel Linux-distributies dan toch nog. Bij andere kun je het probleem makkelijk verhelpen met een live-Linux. Dat gaat zelfs aanzienlijk makkelijker dan GRUB opnieuw installeren, de gebruikelijke truc om een klassiek opstartende Linux weer op gang te helpen.
Startprocedure
Een UEFI-BIOS start een geïnstalleerde Linux via een opstartvermelding, die het genereert uit de inhoud van een UEFIvariabele. Zo'n variabele slaat de installer tijdens het installeren van het besturingssysteem op in een geheugengebied op het moederbord, dat gewoonlijk nietvluchtig is en daarom beschouwd kan worden als 'NVRAM' (Non-volatile RAM). De UEFI-variabele bevat onder andere de doorgaans unieke identifier (Universally Unique Identifier, UUID) van de EFI System Partition (ESP). Dat is de partitie waarop de installer de EFI-loader plaatst waarmee dat besturingssysteem start. Zo'n UUID wordt soms ook GUID (Globally Unique Identifier) genoemd en zorgt ervoor dat het BIOS de
met FAT-geformatteerde ESP ook nog probleemloos herkent als iemand nog een schijf inbouwt die een ESP bevat.
Doorverwijzen
De variabele met de UEFI-boot-ingang bevat ook het pad naar de EFI-bootloader, die het betreffende besturingssysteem op gang brengt. Die bevindt zich op de ESP in een directory die specifiek is voor een bepaalde fabrikant. Bij Ubuntu is dit \EFI\ ubuntu\shimx64.efi. Dat is in de eerste plaats bedoeld voor de ondersteuning van Secure Boot. De elementaire bootloader (shim) is ondertekend door Microsoft, zodat de moderne pc's hem vertrouwen en zonder protest uitvoeren. Linux-distributeurs schuwen dit handtekeningproces, omdat het tijd en geld kost. De shim-ontwikkelaars hebben deze EFI-loader daarom eenvoudig gehouden en zo gemaakt dat hij een krachtigere bootloader start, die distributies onafhankelijk van Microsoft kunnen bijwerken.
Bij Ubuntu is dat de in \EFI\ubuntu\ grubx64.efi opgeslagen Grub2. Voordat het die uitvoert, controleert shim de authenticiteit van het bestand met een ingebouwde verificatiesleutel van Canonical, om te voorkomen dat aanvallers de shim van Canonical misbruiken om kwaadaardige code te lanceren. Daardoor zou Ubuntu's shim op een zwarte lijst terecht kunnen komen.
Een via shim gestarte GRUB laadt op zijn beurt het configuratiebestand grub. cfg in dezelfde directory. In Ubuntu bevat dat slechts drie regels, die de UUID van het bestandssysteem en het pad specificeren waar GRUB zijn eigenlijke configuratie vindt: het bestand /boot/grub/grub. cfg, dat zich bevindt in het root-bestandssysteem van het actieve systeem, tenzij je een aparte opstartpartitie hebt gemaakt. Met dat configuratiebestand genereert GRUB zijn bootmenu. Later start het dan automatisch de door de gebruiker geselecteerde Ubuntu-kernel die zich op dezelfde partitie bevindt. Bij Ubuntu start GRUB momenteel willekeurige kernel-images; bij andere distributies die Secure Boot ondersteunen laadt GRUB alleen een kernel die door shim vertrouwd wordt door een handtekening of een hash. Dit om te voorkomen dat er kernels gestart worden die door aanvallers of malware zijn binnengesmokkeld.
Veel distributies starten net als Ubuntu. Bij Fedora bevindt het configuratiebestand van GRUB zich overigens direct op de ESP. De distributies die Secure Boot niet ondersteunen starten GRUB vaak direct, zonder shim.
Sommige Linuxen gebruiken ook andere EFI-bootloaders, bijvoorbeeld die van Systemd, die voorheen bekend stond als Gummiboot. Bovendien kun je de kernel en Initramfs ook direct op de ESP plaatsen. UEFI-BIOS-systemen kunnen die twee dankzij de Linux-technologie 'Efistub' zelfs direct laden via een EFI-boot-ingang, zodat de EFI-bootloader niet eens nodig is.
Standaard opstartprocedure
UEFI-BIOS-systemen proberen een besturingssysteem op een andere manier te starten als de standaard UEFI-boot-ingang niet werkt of als er geen opstartvariabelen zijn voor geïnstalleerde systemen. Daarvoor doorzoeken ze de systeemschijf en alle verwisselbare schijven (usb-sticks, dvd's en dergelijke) volgens de opstartvolgorde in de BIOS-instellingen op de EFI-loader \EFI\ Boot\Bootx64.efi, om die dan uit te voeren. Op de ESP bevindt zich dan meestal een EFI-loader in dat bestand, die het laatst geïnstalleerde besturingssysteem heeft achtergelaten voor het geval dat de bij de installatie gemaakte UEFI-boot-ingang ontbreekt of niet werkt.
De meeste Linux-distributies slaan shim op in dat bestand, maar zetten daar geen GRUB naast, maar de 'fallback'-loader Fbx64.efi. Die start dan geen besturingssysteem, maar zoekt in de map \EFI\ van de betreffende ESP naar submappen met
Distributies laten shim door Microsoft ondertekenen, zodat moderne pc's het zonder morren uitvoeren
het bestand Bootx64.csv. Linux-distributies die met shim starten, maken deze meestal aan. Hierin bevinden zich gegevens waarmee de fallback-loader vervolgens de UEFIboot-variabelen kan maken voor de daarin gespecificeerde loader.
Daarna geeft de fallback-loader de controle weer aan het UEFI-BIOS, dat een van de nieuw gemaakte ingangen probeert te starten.
Reparatie
Geïnstalleerde Linux-systemen starten dankzij de fallback-loader ook na het vervangen van het moederbord. In elk geval in theorie, want hard- en software bevatten fouten, dus gaat er af en toe iets mis. Bovendien ontbreekt bij sommige distributies de fallback-loader. In die en andere gevallen kan het handig zijn om de UEFI-opstartvariabelen zelf te maken. Neem daarvoor het installatiemedium of een live-Linux, die je start via UEFI. Open een commandlinevenster om daarin de ESP op te sporen. Dat kan door met lsblk te zoeken naar partities met het voor ESP's bedoelde partitietype:
lsblk -f -l -o NAME,PARTTYPE | grep
'.*00a0c93ec93b'
Het commando laat in de eerste kolom de naam van het apparaat zien, bijvoorbeeld 'sda2' of 'nvme0n1p1'. Mount dat apparaat ergens (bijvoorbeeld in /mnt/), en geef met find de inhoud van de ESP weer:
sudo mount /dev/sda2/mnt/ find /mnt/
Daar zie je de fabrikantspecifieke directory waarin de bootloaders van de geïnstalleerde besturingssystemen zich bevinden. Daar bevindt zich ook het CSV-bestand dat de EFI-loader specificeert die standaard wordt aangeroepen, meestal shimx64.efi. Met deze informatie heb je dan alles bij elkaar om zelf de UEFI-opstartvariabele voor de betreffende Linux te maken: efibootmgr --create --disk /dev/sda
--part 2 --label 'Mijn Ubuntu' --loader '\EFI\ubuntu\shimx64.efi'
Apparaatnamen als /dev/sda2 moet je opsplitsen in de gegevens voor de schijf (--disk /dev/sda) en het partitienummer (--part 2). Als de ESP op de eerste schijf op de eerste partitie staat (dus op /dev/sda1), kun je beide opties overslaan. Hoofd- en kleine letters maakt niet uit in het pad naar de EFI-loader, maar er zijn wel een aantal andere struikelblokken:
- Zet net als in het voorbeeld het pad naar de bootloader tussen enkele aanhalingstekens, want die beschermen de backslashes ertussen tegen interpretatie door de shell, die ze anders zou opslokken. - Specificeer het pad naar de bootloader ten opzichte van de hoofdmap van de ESP. - Gebruik de uit DOS en Windows bekende backslash ('\') als directoryscheiding, omdat een UEFI-BIOS de schuine streep uit de Linux/Unix-wereld ('/') niet begrijpt. Voer het commando efibootmgr -v uit nadat je de UEFI-ingang hebt gemaakt om de boot-variabele te controleren op plausibiliteit. Idealiter controleer je behalve het pad ook of de UUID van de partitie overeenkomt met die van de ESP. Dat kan met de bovenstaande lsblk-opdracht, als je tussen NAME en ,PARTTYPE ook nog ,PARTUUID invoegt. Let op: verwar de UUID van de partitie niet met het type van de partitie.
Nog iets: de UUID van een partitie heeft niets te maken met de UUID van een daarin gecreëerd bestandssysteem. Het genoemde lsblk-commando laat die zien als je de sectie na -o aanvult met ,UUID. Het gevaar van verwisseling bij deze twee
UUID's is bijzonder groot, omdat het BIOS de ESP vindt via de UUID van de partitie. Ubuntu's GRUB vindt zijn volledige configuratiebestand daarentegen niet via de UUID van de root- of opstartpartitie, maar via de UUID van het daarin aanwezige bestandssysteem.
Voor het geval dat
Overweeg om de uitvoer van efibootmgr -v voor noodgevallen af te drukken. Dan heb je de EFI-loader van de geïnstalleerde besturingssystemen zwart op wit en kun je hun bootvariabelen makkelijk weer maken. Als de bootloader op de ESP beschadigd is, kun je die bij veel distributies met de opdracht grub-install (soms ook grub2-install) opnieuw installeren. Daarbij wordt ook meteen een bootvariabele gemaakt voor het starten van de betreffende loader. Dat commando moet je echter starten vanuit de Linux-omgeving die de lader later moet starten. Daarvoor moet je eerst een reddings- of live-Linux starten met UEFI-mechanismen. Mount daarmee de root-partitie van de geïnstalleerde Linux (bijvoorbeeld in /mnt/) om daar de pseudobestandssystemen /dev/, / dev/ptc/, /sys/ en /proc/ onder te hangen met bind-mount, bijvoorbeeld met commando's als mount --bind /dev/ /mnt/ dev/. Schakel daarna met chroot over naar de bestandssysteemomgeving van de geinstalleerde Linux, om daar nog alle in de Fstab gedefinieerde bestandssystemen te mounten met mount -a. Pas dan bevindt de ESP zich ook op de aangewezen locatie en is alles gereed voor grub-install.
Rondkijken
Start als je wat tijd hebt ook rustig efibootmgr --help, om de verdere mogelijkheden van het EFI-configuratieprogramma te bekijken. Je kunt het bijvoorbeeld oproepen met -B -b 1 om de eerste opstartvariabele ('0001') te wissen. Het hulpprogramma kan ook de opstartvolgorde wijzigen en specificeren dat bij de volgende systeemstart eenmalig een bepaalde bootingang wordt gestart. Dat is bijvoorbeeld interessant voor de multi-bootsystemen uit het volgende artikel, om Windows eenmalig te starten zonder dat je het opstartmenu van GRUB hoeft aan te passen. (mdt)
Dankzij een fallback-loader starten veel Linuxen ook het vervangen van het moederbord