...taky si přisadím, do téhle přátelské debaty nad draním peří:
Boot linuxu začíná zhruba tím, že bootloader loadne do RAMky jádro a spustí ho (skočí na nějakou startovní adresu). Tohle natažení jádra do RAMky se děje sice z disku, ale ještě pomocí služeb BIOSu - tzn. "ovladačem diskového řadiče" je vlastně podpora tohoto hardwaru zabudovaná v BIOSu. Proto to funguje jednak z onboard IDE/SATA řadičů, jednak z USB flashek (i pro boot z těchto zařízení musí být podpora v BIOSu), jednak z přídavných karet, třeba SCSI/SAS apod., které si nesou ssebou svůj vlastní modul do BIOSu (tzv. "option ROM"). Podpora disků v BIOSu je primitivní, není příliš výkonná = není vhodná pro trvalý běh OS, ale pro natažení kernelu postačí.
Start jádra podle mého cca končí tím, že se jádro pokusí "mountnout kořenový svazek" (root) - což činí už prostřednicvím svých vlastních ovladačů pro diskové řadiče, které se budou za běhu naostro používat.
Tzn. ovladač diskového řadiče, potřebný pro kořenový svazek, musel nastartovat někde mezi odskokem z bootloaderu a mountem rootu - v době, kdy ještě nejsou přimountované žádné svazky a neběží žádné user-space procesy.
Jinými slovy, ovladač pro diskový řadič, skrz který se má jádro dostat ke kořenovému svazku, musí být v kernelu zakompilovaný monoliticky. Jako modul uložený na kořenovém svazku v /lib/modules by byl jádru platný jak žábě gumovky, protože brejle se bez brejlí těžko hledají, jak praví Mach a Šebestová.
Problém obecně je, že různých modelů čipů diskových řadičů je spousta. Na domácím počítači Vám to tak třeba nepřipadá, protože přece bootujete vždycky z nějakého SATA zařízení na onboard SATA řadiči, který je v dnešní době nejspíš od Intelu (ano rejpu naschvál do tábora AMD). Ten jeden-dva ovladače by snad kernel monoliticky pobral? Představte si, že byly doby, kdy PC čipsety vyrábělo třeba 5 a více firem. A základní legacy IDE sice bylo nějak kompatibilní, ale s příchodem SATA vzala kompatibilita do značné míry zasvé (čest výjimkám, kde se SATA řadič uměl tvářit jako prastaré generické IDE). Kromě toho Linux je dodnes doména spíš serverů, a v tomhle prostředí je kupodivu spousta nepochopitelných fajnšmekrů, kteří chtějí bootovat ze SCSI, různých RAIDů, FibreChannel SANů apod. Takže prostě těch ovladačů jsou ve zdrojákách jádra k dispozici obecně desítky. Binární bootovatelný image jádra bez diskových ovladačů může mít třeba nízké jednotky MB, s dvaceti základními ovladači jste snadno na dvoj- až trojnásobku. (V dnešní době pořád legrace, ale prosím abstrahujme od toho.)
Chci říct, že je docela velká a rozumná motivace, nemít monoliticky v kernelu všecky diskové ovladače, kolik jich jenom pánbůh stvořil.
A přesně proto vznikl "initial RAMdisk". Kernel nemountuje přímo finální kořenový svazek. Přibyl mezikrok, kdy kernel napřed mountne dočasný root FS právě z RAMdisku. Potřebuje tedy ovladač pouze pro RAMdisk - jistě triviální. A potřebný ovladač pro skutečný diskový řadič už si dotáhne z RAMdisku. Následně může skript běžící z initial RAMdisku remountnout root na finální fyzický oddíl a spustit plnohodnotný $INIT (dosaďte si každý svou pohanskou modlu). A pokračuje plnohodnotný user-space boot.
Aby byl initial RAMdisk k dispozici a zabydlený dřív, než se mountnou fyzické disky, musí se o jeho vytvoření postarat bootloader (Grub, LILO, Syslinux, PXElinux, ISOlinux, RedBoot, Uboot...). Proto v konfiguraci bootloaderu vidíte tradičně dva řádky těsně za sebou: kernel, a initrd.
Kdysi dávno, snad v minulém století, neměl jsem rád initrd. Připadal mi neprůhledný a nepřehledný. Byl jsem radši, když kernel mountoval rovnou konečný root device. Takhle "přímo" totiž kdysi první distra startovala zcela normálně. Abych toho dosáhl, kompiloval jsem si svůj vlastní kernel, ve kterém jsem potřebný ovladač pro můj konkrétní diskový řadič zakompiloval monoliticky.
Už mnoho let je tomu, co jsem si zvykl na "neprůhlednost" initial RAMdisku, naučil jsem se těch pár zaklínadel, pochopil jsem základní principy fungování a odhadl mantinely... a nakonec mi vyhovuje boot skrz initrd. Distro mi tu vypolstrovanou samotku hezky nastele a navoní, takže když nedělám vylomeniny, je ta nevědomost nakonec docela pohodlná. Znám zhruba obrysy, jak to funguje, a pod kapotu už koukat nepotřebuju.
Prvotní podobu initrd připraví instalátor (ať už standardní CDčkový apod., nebo třeba debootstrap) a jednou z jeho základních povinností je, aby už v této počáteční podobě initrd byl přítomen driver pro diskový řadič, ze kterého tento konkrétní stroj bude bootovat. Tzn. ani v initial RAMdisku nejsou *všechny* ovladače, ale jenom ten, který je pro daný počítač potřeba. Případně pokud jste hraví, máte svobodu přidat si do initrd všechny ovladače (nejen diskové), které tam chcete mít - třeba protože chcete, aby Linux z tohoto disku byl ochoten nastartovat v mnoha různých počítačích. Jsou na to skripty, třeba v Debianu update-initramfs a jeho konfigurace v /etc/initramfs-tools . Přídavné moduly vyjmenujete v souboru "modules" v tomto adresáři. Existuje také standardní možnost (už v instalátoru), nacpat do do initrd *všechny* ovladače - asi pro lidi, kteří nešetří každým gigabajtem RAMky (a nevadí jim, čekat při startu pár desítek sekund navíc na bootloader).
Pro jistotu podotýkám, že do initrd nemusíte cpát ani všechny moduly, které opravdu potřebujete na daném HW. Třeba modul pro zvukovou kartu nebo síťovky si jádro může natáhnout už z fyzického disku v normální fázi user-space bootu. Schválně se na standardně nainstalovaném linuxu podívejte přes lsmod, co všecko je nataženo jako modul, a pak porovnejte s obsahem /lib/modules v initial RAMdisku (viz níže).
V initrd jsou nějaké další věci... třeba zmíněný Plymouth, který se snaží o bezešvý high-res graphics vzhled od bootloaderu až do Xwindows, nebo hlouběji pod kapotou "udev", protože už velmi základní systémové programy v user space, startující z initial ramdisku, potřebují nějaký minimální obsah adresáře /dev/ (přístup na systémová zařízení). V initrd míval konkrétně udev jenom jakýsi "preloader", plný udevd startoval až po mountnutí finálního rootu.
Popravdě, Linux, po remountnutí rootu z ramdisku na ostrý diskový oddíl, initial RAMdisk dealokuje a uvolní paměť. Dokonce je to
ještě trochu složitější (kdo chce, ať si počte). Prostě initial RAMdisk se za normálních okolností zřejmě nedožije ani konce kompletního user-space bootu :-) Je potřeba jenom pro rané fáze user-space bootu a když splní svou úlohu, tak po něm už pes neštěkne.
Jak už psali ostatní, jednou vytvořený obraz initrd leží v souboru pod /boot/ a při běžném rebootu do něj distro nijak nezasahuje, neukládá se do něj žádný "stav". Mění se pouze při změně konfigurace věcí v initrd.
Co je to vlastně za formát / souborový systém? Osobně jsem v nějaké své volné tvorbě kdysi používal obrazy RAMdisku ve formátu ext2 nebo minix, kernel si s nimi dodnes automaticky poradí (pokud má pro tyto fs ovladače). Takový obraz se dá klasicky mountnout ze souboru s argumentem "-o loop". Ovšem moderní distra tuším dodnes (už dlouhá desetiletí) používají initrd ve formátu .cpio.gz. V podstatě soubory poskládané za sebou a sbalené gzipem (nebo čím vlastně), při bootu z toho kernel tuším udělá nastojato tmpfs. Chcete-li si prohlédnout adresářovou strukturu initial RAMdisku, zkopírujte si ho někam bokem (nebo na něj udělejte symlink) a přidejte mu příponu ".cpio.gz". V této podobě do něj ochotně vleze "mc" a můžete se v něm brouzdat v read-only režimu.
To že každá verze image kernelu v /boot/ má k sobě svou vlastní verzi image initrd je dáno tím, že v daném imagi initrd jsou obsažené pouze moduly=drivery pro kýženou verzi kernelu. Opět kvůli tomu, aby nebylo třeba loadovat při bootu spoustu balastu (/lib/modules s verzemi modulů pro všechny kernely instalované na fyzickém disku v daném systému).
Závěrem nostalgická vzpomínka: v dobách, kdy se hra pro DOS vešla na disketu, ale počítače už měly třeba 4 MB RAM, kterou hry běžně celou neupotřebily, zato hra občas padla zpátky do DOSu, nebo bylo třeba kvůli loadnutí uložené pozice hru restartovat (civilizace?), dávalo velmi dobrý smysl, mít nakonfigurovanou buď velikou cache v RAMce, nebo právě RAMdisk (a hru do něj nakopírovat). Restart her v RAMdisku byl okamžitý :-) Tuším jsem to párkrát použil i v dobách, kdy 100MB HDD měl přenosovou rychlost asi 600 kBps...