Nei tempi antichi, il kernel era codificato per conoscere il numero maggiore/minore del dispositivo di root fs e montava quel dispositivo dopo aver inizializzato tutti i driver del dispositivo, che erano integrati nel kernel. Lo rdev
può essere usata per modificare il numero del dispositivo root nell'immagine del kernel senza doverlo ricompilare.
Alla fine arrivarono i boot loader che potevano passare una riga di comando al kernel. Se root=
è stato passato l'argomento, che ha detto al kernel dove si trovava la radice fs invece del valore integrato. I driver necessari per l'accesso dovevano ancora essere integrati nel kernel. Mentre l'argomento sembra un normale nodo di dispositivo nel /dev
directory, ovviamente non c'è /dev
directory prima che root fs sia montato, quindi il kernel non può cercare un nodo dev lì. Invece, alcuni nomi di dispositivi ben noti sono hardcoded nel kernel in modo che la stringa possa essere tradotta nel numero del dispositivo. Per questo motivo, il kernel può riconoscere cose come /dev/sda1
, ma non cose più esotiche come /dev/mapper/vg0-root
o un UUID del volume.
Successivamente, il initrd
è entrato in scena. Insieme al kernel, il boot loader caricherà il initrd
image, che era una sorta di immagine di filesystem compressa (immagine ext2 compressa con gzip, immagine romfs compressa con gzip, squashfs alla fine divenne dominante). Il kernel decomprimerebbe questa immagine in un ramdisk e monterebbe il ramdisk come root fs. Questa immagine conteneva alcuni driver aggiuntivi e script di avvio invece di un vero init
. Questi script di avvio eseguivano varie attività per riconoscere l'hardware, attivare cose come raid array e LVM, rilevare UUID e analizzare la riga di comando del kernel per trovare la vera radice, che ora poteva essere specificata da UUID, etichetta del volume e altre cose avanzate. Ha poi montato il vero root fs in /initrd
, quindi eseguito il pivot_root
chiamata di sistema per avere il kernel swap /
e /initrd
, quindi eseguire /sbin/init
sulla radice reale, che quindi smonterebbe /initrd
e libera il ramdisk.
Infine, oggi abbiamo il initramfs
. Questo è simile al initrd
, ma invece di essere un'immagine di filesystem compressa che viene caricata in un ramdisk, è un archivio cpio compresso. Un tmpfs viene montato come root e l'archivio viene estratto lì. Invece di usare pivot_root
, che era considerato uno sporco hack, il initramfs
gli script di avvio montano la vera radice in /root
, elimina tutti i file nella radice tmpfs, quindi chroot
in /root
ed exec /sbin/init
.
Linux inizialmente si avvia con un ramdisk (chiamato initrd
, per "INITial RamDisk") come /
. Questo disco contiene quanto basta per essere in grado di trovare la vera partizione di root (inclusi eventuali driver e moduli del filesystem richiesti). Monta la partizione root su un punto di montaggio temporaneo su initrd
, quindi invoca pivot_root(8)
per scambiare i punti di montaggio root e temporanei, lasciando initrd
in grado di essere umount
ed e l'effettivo filesystem root su /
.
Sembra che tu stia chiedendo come fa il kernel a "sapere" quale partizione è la partizione root, senza accesso ai file di configurazione su /etc.
Il kernel può accettare argomenti della riga di comando come qualsiasi altro programma. GRUB, o la maggior parte degli altri bootloader, può accettare argomenti della riga di comando come input dell'utente o memorizzarli e rendere disponibili varie combinazioni di argomenti della riga di comando tramite un menu. Il bootloader passa gli argomenti della riga di comando al kernel quando lo carica (non conosco il nome o il meccanismo di questa convenzione, ma è probabilmente simile a come un'applicazione riceve gli argomenti della riga di comando da un processo chiamante in un kernel in esecuzione).
Una di queste opzioni della riga di comando è root
, dove puoi specificare il filesystem root, cioè root=/dev/sda1
.
Se il kernel usa un initrd, il bootloader è responsabile di dire al kernel dove si trova, o di mettere l'initrd in una posizione di memoria standard (credo) - questo è almeno il modo in cui funziona sul mio Guruplug.
È del tutto possibile non specificarne uno e quindi avere il kernel panic immediatamente dopo aver iniziato a lamentarsi che non riesce a trovare un filesystem root.
Potrebbero esserci altri modi per passare questa opzione al kernel.