Start systému
Start systému: od zapnutí po přihlašovací výzvu
Zmáčkneš tlačítko a za dvacet vteřin máš přihlašovací obrazovku. Devětadevadesátkrát ze sta o tom nevíš nic a nemusíš.
Po sté dostaneš černou obrazovku a jeden řádek textu. Žádný nástroj z téhle wiki ti nepomůže, protože žádný ještě neběží - není shell, není journalctl. Start je jediná část systému, kterou musíš umět opravit poslepu.
Stránka řeší cestu od napájení k přihlašovací výzvě a diagnostiku toho, kde se přerušila. Neřeší, jak jádro funguje potom, co naběhne - na to je Architektury jádra. Předpokládá, že víš, co je proces (Procesy) a co znamená připojit souborový systém (VFS a montování).
Start je řetěz, ne jeden program
Nic takového jako „program, který nabootuje počítač" neexistuje. Existuje řada článků a každý umí přesně jednu věc: najít ten další, nahrát ho do paměti a předat mu řízení. Firmware nezná souborový systém tvého disku, jádro neví, kde má kořen.
Tohle je nejdůležitější věc na celé stránce: když stroj nenaběhne, neptáš se „co je rozbité", ale „kam až se to dostalo". Poslední řádek na obrazovce říká, který článek ještě fungoval. Rozbitý je ten hned za ním.
Šest článků řetězu
1. Firmware
Po zapnutí běží kód z paměti na základní desce, dnes UEFI, dřív BIOS. Otestuje a inicializuje paměť, jádra procesoru a řadiče, pak si z NVRAM přečte seznam zaváděcích položek a nahraje soubor, na který ukazují.
Když nevidíš ani logo výrobce, operační systém s tím nemá nic společného.
2. Zavaděč
GRUB umí to, co firmware ne: číst ext4 a rozumět tvému /boot. Najde jádro (vmlinuz-6.12...) a initramfs (initrd.img-6.12...), nahraje obojí do paměti a předá jádru textový řádek parametrů.
Je to poslední místo, kde do startu zasáhneš rukama - proto je sekce o parametrech níž nejpraktičtější část stránky.
3. Jádro
Obraz jádra je zabalený a začíná krátkým kódem, který rozbalí sám sebe. Pak jádro převezme řízení natrvalo: zapne stránkování (Virtuální paměť a stránkování), rozjede plánovač (Plánování procesů) a připojí /proc a /sys. Skutečný operační systém běží - jen zatím nemá jediný soubor na disku.
4. initramfs
Jádro rozbalí initramfs do paměti a použije ho jako dočasný kořen. Je v něm minimální sada modulů a nástrojů a jediný úkol: podle parametru root= najít skutečný kořenový systém, doplnit, co je potřeba (odemknout LUKS, sestavit RAID, aktivovat LVM), a připojit ho.
5. Přepnutí na skutečný kořen
Když je skutečný kořen připojený, initramfs ho přesune na /, zahodí sám sebe z paměti a spustí /sbin/init - na Debianu symlink na /lib/systemd/systemd. Ten proces dostane PID 1.
6. init
systemd zjistí cíl, kterého má dosáhnout, a paralelně spouští jednotky, na kterých závisí: připojení z /etc/fstab, síť, logování, nakonec přihlašovací výzvu. Tady řetěz končí.
UEFI versus starý BIOS: co se změnilo prakticky
BIOS uměl jedinou věc: načíst prvních 512 bajtů disku a skočit do nich. Do nich (446 bajtů na kód) se nevešlo skoro nic, takže se GRUB sekal na kousky schované do mezer mezi oddíly. Tabulka MBR navíc adresuje bloky 32 bity, což při 512bajtovém sektoru dává strop 2 TiB.
UEFI je proti tomu nudné, a to je jeho přednost. Firmware umí FAT sám, takže na disku stačí EFI systémový oddíl naformátovaný na FAT32, zavaděč je na něm obyčejný soubor s příponou .efi a tabulka oddílů je GPT - bez limitu 2 TiB a bez zaváděcího sektoru.
Secure Boot ověřuje podpis toho, co zavádí - zavaděče a přes něj i jádra. Není to ochrana proti tobě, ale proti kódu, který se chce zavést dřív než jádro a odtud ho obelhat. Cena je, že se zapnutým Secure Bootem ti jádro odmítne nahrát vlastní nepodepsaný modul.
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS # ten adresář existuje jen pod UEFI
mokutil --sb-state # zapnutý Secure Boot, nebo ne
Parametry jádra a jak je dopsat
Parametry jsou ten textový řádek, který GRUB předává jádru:
cat /proc/cmdline # přesně to, s čím tenhle systém nastartoval
root=UUID=... říká, který oddíl je kořen. UUID místo /dev/nvme0n1p2 proto, že jména zařízení se mezi starty mohou přeházet, UUID ne. ro připojí kořen jen pro čtení, aby ho šlo zkontrolovat; init ho pak přepne na zápis. quiet schová hlášky jádra a je první, co při ladění vyhodíš.
single naběhne do záchranného režimu bez služeb. init=/bin/bash je brzda o patro níž: přeskočí systemd a dá ti místo PID 1 shell. nomodeset zakáže jádru přepínat grafický režim - první rozumná reakce na start, který zčerná až po předání řízení jádru.
Do menu GRUBu se dostaneš držením Shiftu, pod UEFI opakovaným mačkáním Esc. Nad zvolenou položkou zmáčkni e, sjeď na řádek začínající linux, na jeho konec dopiš parametr a nastartuj přes Ctrl+X. Změna platí jen pro tenhle jeden start, takže nemáš co rozbít.
Proč initramfs vůbec existuje
Jádro musí připojit kořenový souborový systém. Ovladač řadiče toho disku je ale modul a ten modul leží na tom kořenovém systému. Totéž s LUKS, LVM a RAIDem: abys je otevřel, potřebuješ nástroje, které jsou uvnitř.
Slepice a vejce. initramfs ten kruh přeruší tím, že si moduly a nástroje přiveze s sebou v paměti.
lsinitramfs /boot/initrd.img-$(uname -r) | grep nvme # je uvnitř ovladač disku?
sudo update-initramfs -u -k all # přegenerovat pro všechna jádra
Na Fedoře dělá totéž dracut a obsah vypíše lsinitrd. Klasická chyba je vyměnit jádro, disk nebo šifrování a initramfs zapomenout přegenerovat. Systém běží dál a vypadá zdravě, protože initramfs se používá jedině při startu. Rozsype se to až za týden při restartu a příčinu už nikdo se změnou nespojí.
PID 1 a proč je systemd jiný než skripty
Proces s PID 1 je zvláštní ve dvou věcech. Adoptuje sirotky, tedy procesy, jejichž rodič skončil dřív než ony, a sklízí je, aby nezůstávaly zombie (Procesy). A nesmí skončit: když PID 1 zemře, jádro zpanikaří s hláškou „Attempted to kill init!".
SysV init spouštěl očíslované skripty jeden po druhém a čekal na každý. systemd, v Debianu výchozí od verze 8 (2015), to nahradil trojicí věcí: startuje paralelně podle deklarovaných závislostí, umí připravit soket dopředu a službu spustit až při prvním připojení, a procesy služby drží pohromadě v cgroup, takže je umí spolehlivě zabít i restartovat (Virtualizace a kontejnery).
Jednotka je jeden spravovaný objekt: .service je služba, .target jen pojmenovaný bod, kterého se má dosáhnout.
systemctl list-units --failed # čím vždycky začni
systemctl status sshd # stav jednotky včetně posledních řádků logu
journalctl -b -p err # chyby z aktuálního startu, bez šumu
systemd je kritizovaný za to, kolik věcí do sebe pobral. Ten spor je starý a nemá smysl ho tu otevírat.
Kdy to skončí panikou a kdy jen chybou
Panika znamená, že jádro běží - rozbalilo se, má paměť i plánovač - a narazilo na něco, bez čeho nemůže pokračovat. Nejčastěji na tohle:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
To není rozbité jádro. To je špatné root=, nebo initramfs bez ovladače toho disku. Naopak zaseknutí v emergency mode znamená, že jádro i systemd běží a rozsypal se jim /etc/fstab - typicky připojení, které selhalo a nemá volbu nofail (VFS a montování).
Tohle je nejužitečnější tabulka na stránce:
| Poslední, co vidíš | Selhal článek | Co s tím |
|---|---|---|
| Černo, ani logo | firmware | hardware, pořadí zavádění |
| Chybí zaváděcí zařízení | firmware → zavaděč | smazaný ESP, přepsaná NVRAM |
grub rescue> |
zavaděč | přeinstalovat GRUB zvenku |
| Menu GRUBu, pak černo | jádro | nomodeset, uber quiet |
Unable to mount root fs |
jádro → initramfs | špatné root=, chybějící ovladač |
Výzva (initramfs) |
initramfs | kořen nenalezen, neodemčený LUKS |
emergency mode, heslo roota |
init | rozbitý /etc/fstab |
| Naběhne, ale služba chybí | init | systemctl list-units --failed |
Záchrana z živého systému
Když se dovnitř nedostaneš ani přes init=/bin/bash, nastartuj z instalačního USB a vlez si do svého systému zvenku. Klíčové je připojit i /proc, /sys a /dev, jinak uvnitř nefunguje skoro nic.
sudo mount /dev/nvme0n1p2 /mnt # kořen rozbitého systému
sudo mount /dev/nvme0n1p1 /mnt/boot/efi # ESP, jinak nemá grub-install kam psát
sudo mount --rbind /dev /mnt/dev # rbind vezme i /dev/pts
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
sudo chroot /mnt /bin/bash
Uvnitř pak podle toho, co je rozbité: grub-install --target=x86_64-efi --efi-directory=/boot/efi a update-grub na zavaděč, update-initramfs -u -k all na initramfs, editace /etc/fstab na emergency mode. Souborový systém oprav naopak zvenku a odpojený - fsck -f /dev/nvme0n1p2 na připojeném oddílu ti data dorazí spolehlivěji než původní chyba.
Osm a půl milionu strojů, které se nedaly opravit na dálku
- července 2024 rozeslal CrowdStrike aktualizaci datového souboru pro svůj bezpečnostní ovladač běžící v režimu jádra. Soubor shodil ovladač, ovladač shodil systém a stroje spadly do smyčky, ve které padly dřív, než stihly stáhnout opravu. Microsoft odhadl zásah na zhruba 8,5 milionu strojů; odbavovací pulty aerolinek stály celý den.
Oprava byla triviální: nastartovat do nouzového režimu a smazat jeden soubor. Znamenalo to ale, že k 8,5 milionu strojů musel fyzicky přijít člověk. Poučení: co běží před přihlašovací výzvou, si opravu na dálku nedovolí.
Měření startu a co s výsledkem nedělat
systemd-analyze # rozpad na firmware, zavaděč, jádro a userspace
systemd-analyze blame # jednotky seřazené podle doby běhu
systemd-analyze critical-chain # co na sebe skutečně čekalo
dmesg -T # hlášky jádra s čitelnými časy
Ber vážně critical-chain, ne blame. V blame ti vyskočí třeba fstrim.service se třemi minutami, jenže na ten nikdo nečeká - běží stranou a start nezdržel ani o vteřinu.
Nejrychlejší způsob, jak zkrátit start, je nespouštět služby, které nepotřebuješ. systemctl disable na tiskový systém nebo Bluetooth na stroji, kde je nikdo nezapne, ušetří víc než jakékoli ladění. Do závislostí mezi jednotkami nesahej - odměnou je nedeterministický start, který se rozbije jednou za dvacet restartů.
Co si odnést
Start je řetěz šesti článků a každý umí jen najít ten další. Firmware, zavaděč, jádro, initramfs, přepnutí kořene, init.
Diagnostika je otázka „kam až se to dostalo". Poslední řádek na obrazovce určuje článek, ne příčinu.
Panika u Unable to mount root fs znamená zdravé jádro a špatný kořen. Chyba je v root= nebo v initramfs.
emergency mode je skoro vždycky /etc/fstab. Selhalo připojení bez nofail.
initramfs existuje kvůli slepici a vejci. Ovladač kořene leží na kořeni, musí tedy přijet zvlášť v paměti.
Umět v GRUBu zmáčknout e a dopsat parametr je nejcennější dovednost odsud. nomodeset, single a init=/bin/bash pokryjí většinu situací.
Zkracuj start rušením služeb, ne přehazováním závislostí.
Kam dál
- VFS a montování - co dělá
mounta proč jde/etc/fstabrozbít tak snadno - Procesy - PID 1, sirotci a zombie z druhé strany
- Virtualizace a kontejnery - cgroups, o které se systemd opírá
- Nástroje a diagnostika -
dmesgajournalctl, až systém naběhne - Práva a uživatelé - proč je
init=/bin/bashshell roota bez hesla