EFIStub: startujeme linuxové jádro bez zavaděče GRUB

16. 6. 2026
Doba čtení: 15 minut

Sdílet

Start raketa Linux
Autor: Root.cz s využitím Duck.ai
Linuxové jádro se obvykle načítá při bootu pomocí zavaděče, ale jde to jinak. EFIStub je způsob, jak jádro nastartovat bez použití zavaděče jako je GRUB. Ukážeme si jak na to a k čemu je to dobré.

Co je EFIStub?

UEFI boot umožňuje start operačního systému na PC ze speciálního diskového oddílu. Oddíl využívá souborový systém VFAT a UEFI firmware na něm má zapsaný nějaký spustitelný systém. Tím systémem bývá zavaděč hlavního operačního systému. Jde o pomocný prográmek, který bychom mohli popsat jako miniaturní operační systém, který zavede linuxové jádro. Tradičním řešením je tu například GRUB.

GRUB je velmi mocný, ale pro mě, jako minimalistu, je velmi robustní a složitý. Dodnes, když mám opravit boot v grubu, se mi ježí vlasy. Dnes jej používají všechny linuxové distribuce jako hlavní zavaděč, ale kdysi byl hlavním zavaděčem jiný prográmek LiLo (LinuxLoader). Byl mi sympatický, protože byl malý a měl konfiguraci v jednom souboru. Ale LiLo je už minulostí a GRUB je na PC všude. Ale je asi málo známá věc, že tomu tak být nemusí. Linuxové jádro už nějakou dobu obsahuje vlastní zavaděč zvaný EFIStub.

Při instalaci GRUBu se do UEFI bootu přidá záznam, který jej spouští. Schválně si zkuste zadat příkaz:

efibootmgr -u
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0007,0003,0002,0008,0009,000A,0001
Boot0000* debian        HD(1,GPT,ed4ac21a-02cc-42b1-9ebb-3c70c7b768bb,0x800,0x8e800)/File(\EFI\debian\shimx64.efi)
Boot0001* UEFI: Built-in EFI Shell      VenMedia(5023b95c-db26-429b-a648-bd47664c8012)
...

Poznámka: Parametr -u doporučuji, výpis je pak v UTF místo výchozího ASCII, které je méně přehledné.

Jak vidíte, dostanete podobný výpis jako v bootovacím menu v BIOSu, jen podrobnější. Na prvním místě je právě zmiňovaný GRUB, další jsou boot ze sítě, z flash, CD-ROM a tak dále. Může tam zbýt třeba ještě záznam pro Windows, protože smazání z disku neodstraní jejich záznam z boot menu.

V UEFI můžete maximálně měnit pořadí položek boot menu, mazat je, ale ne přidávat nové. Na přidávání nových položek potřebujete efibootmgr. Přidáním vlastního záznamu do boot menu, s odkazem přímo na linuxové jádro, použijeme zmíněný EFIStub.

Používáme EFIStub

EFIStub je možné použít už při instalaci, ale to je trochu složitější. My začneme jedoduššeji s čerstvě nainstalovaným Debianem, který normálně používá GRUB. Čeká nás trocha manuální práce, pracujeme samozřejmě jako uživatel root.

UEFI boot umí pracovat jen s VFAT, neumí natáhnout jádro přímo z disku s EXT4, proto mu ho tam musíme nakopírovat, i s initramdiskem. Debian a jeho klony mají tu výhodu, že mají v kořeni souborového systému symbolický odkaz na nejnovější jádro, to nám kopírování usnadní. EFI boot disk je vždy v OS připojen do adresáře  /boot/efi.

cp /vmlinuz /initrd.img /boot/efi/

Upozornění: Než s celou procedurou začnete, zkontrolujte si, že máte na EFI disku dostatek místa! Při instalaci se doporučuje velikost alespoň 300 MB. Sám jsem se takhle nachytal, když jsem si dal jen velikost 100 MB. Na Debian 11 to původně stačilo, na upgrade na 12 také, ale na 13 už ne. Jádro je totiž stále větší a větší.

Pak potřebujeme zjistit hodnotu UUID našeho systémového svazku. Tu si vytáhneme ze souboru /etc/fstab nebo pomocí příkazu  blkid.

blkid /dev/nvme0n1p2
/dev/nvme0n1p2: UUID="7a62971d-be7a-4e64-847f-875cba948e47" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="27438dfc-b3f3-42ab-84ff-93c5ca2a0c57"

Poté můžeme přidat do boot menu záznam.

efibootmgr -c -g -L "nas EFIStub" --disk /dev/nvme0n1p1 -l 'vmlinuz' -u "root=UUID=7a62971d-be7a-4e64-847f-875cba948e47 rw quiet add_efi_memmap initrd=initrd.img"

Název položky za parametrem -L, si zvolíme sami libovolný, ale doporučuji se vyhnout diakritice. Parametr --disk říká, kde se nachází naše jádro a initramdisk, tedy dáme tam EFI disk. Kdybyste parametr disk vynechali, použije se výchozí hodnota /dev/sda1, takže tento parametr velice závisí na konfiguraci vašeho PC.

Kořenový oddíl je zadán pomocí UUID, které jsme získali z fstabu nebo pomocí blkid. Tohle je disk, kde se nachází operační systém. Ten už není uložen v souborovém systému VFAT, většinou dnes používá ext4. Pokud potřebujete jádru přidat další parametry, přidáte je za quiet oddělené mezerou, třeba  net.ifnames=0.

Poznámka: Pokud byste jádro a initramdisk nahráli do nějakého podadresáře, cesta k souborům se musí escapovat. Třeba pokud použijeme adresář co vytvořil GRUB – /boot/efi/EFI/debian, bude náš příkaz vypada takto:

efibootmgr -c -g -L "nas EFIStub" --disk /dev/nvme0n1p1 -l '/EFI\debian\vmlinuz' -u "root=UUID=7a62971d-be7a-4e64-847f-875cba948e47 rw quiet add_efi_memmap initrd=\\EFI\\debian\\initrd.img"

To escapování je trochu zvláštní, je na to třeba pamatovat. Sám jsem na to přišel metodou pokus-omyl.

Nyní máme přidaný záznam v boot menu. Už při jeho zápisu jsme dostali výpis aktuálního stavu a vidíme tam svůj nově přidaný záznam.

efibootmgr -u
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0003,0000,0007,0002,0008,0009,000A,0001
Boot0000* debian        HD(1,GPT,ed4ac21a-02cc-42b1-9ebb-3c70c7b768bb,0x800,0x8e800)/File(\EFI\debian\shimx64.efi)
Boot0001* UEFI: Built-in EFI Shell      VenMedia(5023b95c-db26-429b-a648-bd47664c8012)
Boot0002* (B129/D0/F0) UEFI PXE IPv4 Broadcom Network Device - 90:5A:08:24:16:36(MAC:905a08241636)   PciRoot(0x2)/Pci(0x1,0x1)/Pci(0x0,0x0)/MAC(905a08241636,1)/IPv4(0.0.0.00.0.0.0,0,0)
Boot0003* nas EFIStub   HD(1,GPT,ed4ac21a-02cc-42b1-9ebb-3c70c7b768bb,0x800,0x8e800)/File(vmlinuz)root=UUID= 7a62971d-be7a-4e64-847f-875cba948e47 rw quiet add_efi_memmap initrd=initrd.img

Hodnota bootnum se nám přiřadí automaticky, bude to první volné číslo. Nikdy jsem nepotřeboval řešit konkrétní hodnotu při přidávání záznamu. Náš záznam se v pořadí bootu nastaví jako první.

Nyní můžeme restartovat a uvidíme, jestli nám systém nabootuje bez zavaděče. Pokud by se boot nezdařil kvůli naší chybě, záznam s GRUBem je hned na druhém místě a pro boot se použije ten. Nebo můžeme vybrat v UEFI boot menu položku ručně sami.

Záznamy v boot menu se nedají upravovat. Pokud chceme změnu, musíme původní záznam smazat a přidat znovu už změněný. První příkaz smaže položku v boot menu, parametr -b určí bootnum které chceme smazat. Druhý příkaz je změna pořadí bootování, v ukázce je návrat k původnímu GRUBu.

efibootmgr -b 0003 -B
efibootmgr -o 0000,0003,0007,0002,0008,0009,000A,0001

Aktuální jádro pro EFIStub

Protože jsme jádro i initramdisk na EFI disk kopírovali ručně, při aktualizaci jádra nedojde automaticky k jeho aktualizaci také na boot disku. Běžně se o to stará GRUB, ale my si musíme poradit jinak. Vytvoříme si dva aktualizační skripty, které nám budou aktuálnost udržovat. Využijeme automaticky udržované symbolické odkazy na jádro a initramdisk, které nám připravuje sám Debian.

echo -e '#!/bin/sh\ncp /vmlinuz /boot/efi/' > /etc/kernel/postinst.d/zz-update-efistub
chmod +x /etc/kernel/postinst.d/zz-update-efistub
mkdir -p /etc/initramfs/post-update.d/
echo -e '#!/bin/sh\ncp /initrd.img /boot/efi/' > /etc/initramfs/post-update.d/zz-update-efistub
chmod +x /etc/initramfs/post-update.d/zz-update-efistub

Poznámka: Nevím proč, ale v Debianu 13 post-update adresář pro initramdisk chybí, musíme ho ručně vytvořit. 

Skripty jsou dva, jeden pro jádro a druhý pro initramdisk. Jeden nestačí, protože při instalaci nějakých balíčků dochází k aktualizaci initramdisku aniž by se měnilo jádro. Zkuste si třeba nainstalovat iSCSI.

Celý EFIStub, i se skripty, přežije distribuční upgrade Debianu a normálně funguje dál v nové verzi Debianu.

K čemu je to dobré?

Tady se dostáváme na dost filozofickou rovinu, ale uvedu svůj názor: Zbavíme se tím GRUBu při bootu. I když ne jeho nainstalovaného balíčku na disku – kvůli závislostem jej nemůžeme odstranit. Občas se totiž setkám s případem, kdy mi GRUB selhal a já musel opravovat jeho instalaci. Není to těžké udělat, ale zdlouhavé. Především, když právě nemáte po ruce záchranný disk a nemáte ho v potřebné verzi Debianu.

Takový boot je taky o něco rychlejší, což asi využijeme jen u stroje, který denně spouštíme.

Naopak přijdeme o snadnou možnost obnovení hesla. Bez GRUBu k tomu budete potřebovat nějaký záchranný disk. Bez GRUBu také nemůžete využít boot ze zašifrovaného disku. Systémový kořenový svazek být zašifrovaný může, ale ne adresář boot s jádrem a ramdiskem.

Boot ze SW RAID

Dokud se na PC bootovalo starým způsobem, nebyl problém bootovat z disků, na kterém byl SW RAID. I když na bootovacím oddíle to mohl být jen RAID1, zavaděč se zapsal do MBR a jelo se. Jenže novější servery už tento boot nepodporují a už se mi stalo, že vůbec nefungoval. Nový UEFI boot tohle všechno velmi změnil. Jak jsem psal na začátku, EFI disk musí být jen jednoduchý VFAT a ten se s RAIDem špatně snáší a GRUB se na něj odmítá instalovat.

Dostal jsem na instalaci nový server, který měl sice disky pro RAID, ale už v něm nebyl příslušný řadič. Bohužel na specifikaci nákupu jsem neměl vliv, ale musel jsem se s tím nějak vypořádat. Softwarový RAID je sice levnější než ten hardwarový, ale platíme za jeho používání výkonem stroje. Softwarové řešení redukuje rychlost zápisu na disk na polovinu, rychlost čtení ovlivněna není.

Tady velice záleží na účelu serveru. Pokud mám výpočetní stroj, který intenzivně zapisuje na disk své výsledky (třeba Gausian), rozhodně to chce jít do hardwarového řešení. Ale u souborového serveru, kde výpočty neběží, to už takový problém být nemusí. Nebo u domácího serveru na úsporné desce, kde je hlavní prioritou spotřeba při dlouhodobém provozu, než rychlost zápisu disků. Celkově, ale určitě platí, že je hardwarový RAID obvykle lepší variantou.

Když jsem na internetu hledal, jestli existuje návod jak se s tím vypořádat, našel jsem dva směry řešení. První způsob: instalovat na normální EFI boot disk a pak z něj násilně udělat RAID tak, aby zůstala zachována VFAT. Druhý způsob: manuálně instalovat GRUB na oba disky. Poté pravidelně kontrolovat, jestli jsou správně zkopírovaná jádra a GRUB je po upgradu na obou bootovacích discích. Tohle není nic moc.

Ale co ve skutečnosti potřebujeme? Na obou discích oddíl s VFAT, na nich jádro a initramdisk. EFIStub nám nabootuje a pak spustí systém ze softwarového RAID disku. Takže jsem provedl normální instalaci Debianu. Na obou discích serveru jsem si připravil oddíly EFI boot ( /dev/sda1 a /dev/sdb1), kořenový souborový systom jsem nainstaloval na SW RAID a GRUB se nainstaloval na disk /dev/sda1. Po bootu systému z disku jsem začal dělat úpravy.

Odpojil jsem původní mount /boot/efi. Vytvořil jsem dva nové adresáře /boot/efiA a /boot/efiB a do nich připojil oba disky. Samozřejmě jsem si upravil fstab, aby odpovídal novým adresářům a diskům. Původní adresář /boot/efi jsem chtěl smazat po odinstalaci GRUBu, ale tady jsem narazil. GRUB jako core balíček mi balíčkovací systém APT nedovolil odinstalovat. Násilí jsem nechtěl použít, tak jsem ho tam nechal a jen mu pro jistotu překopíroval obsah původního EFI boot disku do nyní prázdného adresáře /boot/efi, aby při upgradech GRUB nebyl příliš zmatený. Kopírování jádra a initramdisku je stejné jako v předchozím případě.

umount /boot/efi
mkdir /boot/efiA /boot/efiB
chmod 700 /boot/efiA /boot/efiB
blkid /dev/sda1 /dev/sdb1
vim /etc/fstab
mount /boot/efiA
mount /boot/efiB
cp -r /boot/efiA/EFI /boot/efi/
cp /vmlinuz /initrd.img /boot/efiA/
cp /vmlinuz /initrd.img /boot/efiB/

Přidání položky do UEFI boot menu je také téměř stejné, jen je dvakrát. Dejte si pozor na pořadí bootu, položka na boot sdb musí být hned za položkou  sda.

efibootmgr -c -g -L "sdb" --disk /dev/sdb1 -l 'vmlinuz' -u "root=UUID=11cadbb9-650c-42a7-af4c-0c064e879f8c rw quiet add_efi_memmap initrd=initrd.img"
efibootmgr -c -g -L "sda" --disk /dev/sda1 -l 'vmlinuz' -u "root=UUID=11cadbb9-650c-42a7-af4c-0c064e879f8c rw quiet add_efi_memmap initrd=initrd.img"

efibootmgr -u
BootCurrent: 0003
Timeout: 1 seconds
BootOrder: 0003,0007
Boot0003* sda   HD(1,GPT,ed4ac21a-02cc-42b1-9ebb-3c70c7b768bb,0x800,0x8e800)/File(vmlinuz)root=UUID=11cadbb9-650c-42a7-af4c-0c064e879f8c rw quiet add_efi_memmap initrd=initrd.img
Boot0007* sdb   HD(1,GPT,113a0e99-65bf-4080-accb-0594ae405475,0x800,0x8e800)/File(vmlinuz)root=UUID=11cadbb9-650c-42a7-af4c-0c064e879f8c rw quiet add_efi_memmap initrd=initrd.img

Kopírovací skripty pro upgrade jádra a initramdisku mají logicky o řádek navíc.

echo -e '#!/bin/sh\ncp /vmlinuz /boot/efiA/\ncp /vmlinuz /boot/efiB/' > /etc/kernel/postinst.d/zz-update-efistub
chmod +x /etc/kernel/postinst.d/zz-update-efistub
mkdir -p /etc/initramfs/post-update.d/
echo -e '#!/bin/sh\ncp /initrd.img /boot/efiA/\ncp /initrd.img /boot/efiB/' > /etc/initramfs/post-update.d/zz-update-efistub
chmod +x /etc/initramfs/post-update.d/zz-update-efistub

To je vše, nyní můžete systém restartovat a už nabootujete bez GRUBu. Samozřejmostí by měl být test pomocí UEFI boot menu, kdy ručně vyberete disk  sdb.

NFS root

Před časem po mě chtěl kolega server na otestování provozu vlastního LLM (nebo-li nesprávně řečeno AI). Mělo to být na samostatném serveru, aby se dalo udělat testování napojení na naše služby v reálné síti. Díval jsem se na cenu hardwaru, který by na to byl případně potřeba a pod 200 tisíc korun jsem se nedostal. To mi na test nikdo nekoupí. Tak zkusíme Ollamu v CPU režimu na nějakém vyřazeném stroji z VMware, CPU jsou tam slušné a hlavně je tam dostatek RAM.

Vyskytl se tam ale jeden problém, v serveru je jen 16GB flash disk. Operační systém se tam sice vejde, ale provozem ty flash za chvíli zničím a stejně tam budu muset připojit něco po síti, aby se mi tam ten LLM vešel. Ideální pro návrat k začátkům unixů, kdy se provozovaly bezdiskové stanice. Budu mít bezdiskový server na NFS. Boot budu mít pomocí EFIStubu a na lokálním úložišti budu mít jen jádro a initramdisk.

Jako vzor jsem si vzal článek na Rootu: Bootujte ze sítě plnohodnotný systém. Je sice starší, ale stále platný a v přípravě systému tedy poukáži pouze na rozdíly.

Připravíme si na NFS serveru adresář s novou instalací.

debootstrap --arch=amd64 trixie /mnt/debianNFS
mount --bind /dev /mnt/debianNFS/dev
mount --bind /sys /mnt/debianNFS/sys
mount --bind /proc /mnt/debianNFS/proc
chroot /mnt/debianNFS /bin/bash

Pak doděláme konfiguraci a instalaci balíčků, protože úvodní instalace je opravdu velmi chudá.

passwd
apt-get install vim htop openssh-server chrony bash-completion locales nfs-common file man curl wget efibootmgr
dpkg-reconfigure locales
dpkg-reconfigure tzdata
vim /etc/apt/sources.list
vim /etc/resolv.conf
apt-get install firmware-linux firmware-linux-free firmware-linux-nonfree firmware-bnx2 linux-image-amd64

V případě fstabu je jedna odlišnost oproti původnímu článku, nemusíme řešit adresáře připojené do tmpfs, stejně jako proc. Tyto věci už ve fstabu nejsou. Ve fstabu nám tak zůstanou jen dva řádky, kořenový svazek a EFI disk, ten doplníme později.

/etc/fstab
/dev/nfs       /         nfs  _netdev,hard,async,noatime,nolock            1 1

Upravíme konfiguraci initramdisku.

/etc/initramfs-tools/initramfs.conf
MODULES=netboot

Aktualizujeme initramdisk a můžeme opustit přípravný chroot a odpojíme.

exit
umount /mnt/debianNFS/dev /mnt/debianNFS/sys /mnt/debianNFS/proc

Musíme si jádro z té instalace na NFS, stejně jako initramdisk, nakopírovat na nějakou USB flash, abychom ho mohli nakopírovat na EFI boot disk serveru.

Server nejprve nabootujeme z Debian live CD, ne z normálního instalačního netinstu. Ten bohužel v záchranném režimu nemá všechny potřebné nástroje. Například neobsahuje efibootmgr a my pak nemáme jak přidat položku do boot menu.

Poznámka: Při bootu na mém serveru Dell R740 jsem musel z jádra odstranit parametry memtest noapic a všechny další parametry s no na začátku, jinak live cd ve fail-safe nebootovalo. Dělá se to tak, že vyberete fail-safe a klávesou e spustíte malý editor, kterým parametry smažete.

Doporučuji live CD variantu standard, je nejmenší a my potřebujeme stejně jen konzoli. Nabootujeme do záchranného režimu a rozchodíme síťové připojení, tím zjistíme název rozhraní, který pak použijeme při přidávání položky do bootmenu. Bohužel se vám z live Cd spustí dhcpcd na každém rozhraní. Pokud budete síť konfigurovat staticky, musíte konfiguraci DHCP odstranit z každého rozhraní ( dhcpcd -k název), jinak nezadáte novou výchozí bránu.

apt install efibootmgr dosfstools

Doinstalujeme potřebné balíčky a vytvoříme EFI boot disk. V nástroji fdisk to je typ 1, EFI System, na oddílu vytvoříme souborový systém VFAT. Nakopírujeme tam jádro a initramdisk. Nyní můžeme přidat položku do UEFI boot menu.

efibootmgr -c -g -L "debianNFS" --disk /dev/sda1 -l 'vmlinuz' -u "root=/dev/nfs rootfstype=nfs nfsroot=203.0.113.22:/mnt/debianNFS,tcp rw ip=198.51.100.22::198.54.100.1:255.255.255.0:debianNFS:ens2f1np1::203.0.113.20:203.0.113.21 add_efi_memmap initrd=initrd.img"

Pozor jestli váš bootovací disk je opravdu /dev/sda1. Formát konfigurace ip adresy – statika nebo dhcp.

ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>
ip=dhcp

Přiznám se, nezkoušel jsem, jestli by to vzalo i IPv6 adresy. Na firewallu, který případně leží mezi NFS diskem a vaším serverem musíte mít povoleny porty TCP 111 a 2049, na začátku to něco řeší přes RPC, přestože po bootu se NFS přepne do verze 4.2, kde už RPC není třeba.

Školení Kubernetes

Teď můžeme zkusit nabootovat. Pokud se boot povedl, musíme doladit ještě pár věcí. Vytvořit nové machine id, nastavit ve fstabu EFI boot disk a připojit ho. Síťové rozhraní lze přejmenovat, ale nezkoušel jsem, jestli by bylo možné použít také etherchannel. Samozřejmě nesmíme zapomenout vytvořit skripty na kopírování jádra a initramdisku.

rm /etc/machine-id
systemd-machine-id-setup

/etc/network/interfaces
rename ens2f1np1=eth0

blkid /dev/sda1
/etc/fstab
UUID=D2F6-1E24 /boot/efi vfat umask=0077

mount /boot/efi
echo -e '#!/bin/sh\ncp /vmlinuz /boot/efi/' > /etc/kernel/postinst.d/zz-update-efistub
chmod +x /etc/kernel/postinst.d/zz-update-efistub
mkdir -p /etc/initramfs/post-update.d/
echo -e '#!/bin/sh\ncp /initrd.img /boot/efi/' > /etc/initramfs/post-update.d/zz-update-efistub
chmod +x /etc/initramfs/post-update.d/zz-update-efistub

Máme hotovo. Popsané řešení je takovou alternativou ke klasickému použití DHCP a TFTP. Stejná metoda by měla být použitelná také pro iSCSI. Zkoušel jsem to, ale zatím bez úspěchu. Na další laborování jsem už neměl čas, doufám že se k němu ještě vrátím.

Autor článku

V současné době pracuje jako správce linuxových systémů na Univerzitě Pardubice.