En la antigüedad, el núcleo estaba codificado para conocer el número mayor / menor del dispositivo de la raíz fs y lo montó después de inicializar todos los controladores de dispositivo, que se integraron en el núcleo. La rdev
utilidad podría usarse para modificar el número de dispositivo raíz en la imagen del núcleo sin tener que volver a compilarlo.
Finalmente llegaron los cargadores de arranque y pudieron pasar una línea de comando al núcleo. Si root=
se pasó el argumento, eso le dijo al núcleo dónde estaba la raíz fs en lugar del valor incorporado. Los controladores necesarios para acceder a eso todavía tenían que estar integrados en el núcleo. Si bien el argumento se ve como un nodo de dispositivo normal en el /dev
directorio, obviamente no hay un /dev
directorio antes de que se monte la raíz fs, por lo que el núcleo no puede buscar un nodo de desarrollo allí. En cambio, ciertos nombres de dispositivos bien conocidos están codificados en el núcleo para que la cadena se pueda traducir al número de dispositivo. Debido a esto, el núcleo puede reconocer cosas como /dev/sda1
, pero no cosas más exóticas como /dev/mapper/vg0-root
un UUID de volumen.
Más tarde, initrd
entró en escena. Junto con el kernel, el gestor de arranque cargaría la initrd
imagen, que era una especie de imagen de sistema de archivos comprimido (imagen ext2 comprimida, imagen romfs comprimida, finalmente los squashfs se volvieron dominantes). El núcleo descomprimiría esta imagen en un disco RAM y montaría el disco RAM como la raíz fs. Esta imagen contenía algunos controladores adicionales y secuencias de comandos de arranque en lugar de una real init
. Estos scripts de arranque realizaron varias tareas para reconocer el hardware, activar elementos como matrices de incursiones y LVM, detectar UUID y analizar la línea de comando del núcleo para encontrar la raíz real, que ahora podría especificarse por UUID, etiqueta de volumen y otras cosas avanzadas. Luego montó la raíz real fs /initrd
, luego ejecutó la pivot_root
llamada al sistema para que el kernel se intercambie /
y/initrd
, luego ejecute /sbin/init
en la raíz real, que luego desmontaría /initrd
y liberaría el ramdisk.
Finalmente, hoy tenemos el initramfs
. Esto es similar al initrd
, pero en lugar de ser una imagen del sistema de archivos comprimido que se carga en un disco RAM, es un archivo comprimido de cpio. Se monta un tmpfs como raíz, y el archivo se extrae allí. En lugar de usar pivot_root
, lo que se consideraba un truco sucio, los initramfs
scripts de arranque montan la raíz real /root
, eliminan todos los archivos en la raíz tmpfs, luego chroot
en /root
y ejecutan /sbin/init
.