¿Cómo monta un núcleo la partición raíz?

29

Mi pregunta es con respecto al arranque de un sistema Linux desde una partición separada / de arranque. Si la mayoría de los archivos de configuración se encuentran en una partición / separada, ¿cómo lo monta el núcleo correctamente en el momento del arranque?

Cualquier explicación sobre esto sería genial. Siento que me falta algo básico. Me preocupa principalmente el proceso y el orden de las operaciones.

¡Gracias!

EDITAR: Creo que lo que necesitaba preguntar era más en la línea del archivo de desarrollo que se utiliza en el parámetro del núcleo raíz. Por ejemplo, digamos que doy mi parámetro raíz como root = / dev / sda2. ¿Cómo tiene el núcleo una asignación del archivo / dev / sda2?

Sr. Shickadance
fuente
Aunque las personas a continuación cubren initrd, hay poca discusión sobre por qué se usa initrd. Mi impresión es que las distribuciones como Debian quieren usar un núcleo en muchas máquinas diferentes de la misma arquitectura, pero posiblemente hardware muy diferente. Esto es posible al modularizar el soporte de hardware a través de los módulos del núcleo. El initrd no requiere mucho soporte de hardware para arrancar, y una vez que lo hace, carga los módulos de hardware necesarios para continuar. Se agradecen las elaboraciones / correcciones a esto.
Faheem Mitha
No puede montar / boot sin tener / montado primero, ya que no hay un directorio / boot sin /.
psusi

Respuestas:

20

Inicialmente, Linux arranca con un initrddisco RAM (denominado "RAMDisk INICIAL") como /. Este disco tiene lo suficiente para poder encontrar la partición raíz real (incluidos los controladores y los módulos del sistema de archivos necesarios). Monta la partición raíz en un punto de montaje temporal en el initrd, luego invoca pivot_root(8)para intercambiar los puntos de montaje raíz y temporal, dejando la initrdposición para ser umounteditada y el sistema de archivos raíz real activado /.

geekosaur
fuente
2
¿Qué pasa si no tiene un initrd como LFS (linuxfromscratch.org)?
Sr. Shickadance el
@Señor. Shickadance: sin haber analizado cómo LFS hace las cosas, supongo que se aseguran de que el núcleo tenga todos los módulos necesarios compilados (o cargados a través de GRUB 2, posibilidad que es lo suficientemente nueva como para que muchas distribuciones aún no lo hayan notado). puede comenzar en la partición raíz real.
geekosaur
44
@señor. Shickadance No es solo LFS que no tiene un initrd. Cualquiera que compile su propio núcleo tiene la opción de no usar un initrd, que es lo que hago en Gentoo.
jonescb
1
@Faheem: los módulos grub2 no son lo mismo que los módulos del núcleo. Veo cierta capacidad para que grub2 cargue módulos del kernel, pero una cosa que no sé es si eso funcionará para el kernel de Linux o solo para * BSD (donde el cargador de arranque carga los módulos del kernel es normal). Sospecho que el núcleo necesita que se le enseñe dónde encontrar el mapa de direcciones para los módulos cargados, y todos necesitan pasar a grub2 (grub1 sigue siendo estándar en algunas distribuciones).
geekosaur
1
El initrd ha sido reemplazado por initramfs, ya que pivot_root se consideraba un hack sucio.
psusi
41

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 rdevutilidad 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 /devdirectorio, obviamente no hay un /devdirectorio 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-rootun UUID de volumen.

Más tarde, initrdentró en escena. Junto con el kernel, el gestor de arranque cargaría la initrdimagen, 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_rootllamada al sistema para que el kernel se intercambie /y/initrd, luego ejecute /sbin/initen la raíz real, que luego desmontaría /initrdy 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 initramfsscripts de arranque montan la raíz real /root, eliminan todos los archivos en la raíz tmpfs, luego chrooten /rooty ejecutan /sbin/init.

psusi
fuente
1
Después del chroot, ¿se desmonta automáticamente el tmpfs? ¿Simplemente desaparece?
jiggunjer
@jiggunjer, no, todavía está allí, solo está vacío (aparte de contener el directorio / root) y ya no se usa.
psusi
Aprendí algo nuevo sobre cada iteración de root fs que mencionaste. ¡Gran respuesta!
jpaugh
3

Parece que está preguntando cómo "sabe" el núcleo qué partición es la partición raíz, sin acceso a los archivos de configuración en / etc.

El núcleo puede aceptar argumentos de línea de comando como cualquier otro programa. GRUB, o la mayoría de los otros gestores de arranque pueden aceptar argumentos de línea de comandos como entrada del usuario, o almacenarlos y hacer que varias combinaciones de argumentos de línea de comandos estén disponibles a través de un menú. El gestor de arranque pasa los argumentos de la línea de comandos al kernel cuando lo carga (no sé el nombre o la mecánica de esta convención, pero probablemente sea similar a cómo una aplicación recibe argumentos de la línea de comandos de un proceso de llamada en un kernel en ejecución).

Una de esas opciones de línea de comandos es root, donde puede especificar el sistema de archivos raíz, es decir root=/dev/sda1.

Si el kernel usa un initrd, el gestor de arranque es responsable de decirle al kernel dónde está, o colocar el initrd en una ubicación de memoria estándar (creo), esa es al menos la forma en que funciona en mi Guruplug.

Es completamente posible no especificar uno y luego hacer que el núcleo entre en pánico inmediatamente después de comenzar a quejarse de que no puede encontrar un sistema de archivos raíz.

Puede haber otras formas de pasar esta opción al kernel.

LawrenceC
fuente
3
Esta es la explicación correcta cuando no hay initrd / initramfs, pero le falta una pieza del rompecabezas. Normalmente, el núcleo identifica un dispositivo, como /dev/sda1porque es una entrada en un sistema de archivos. Podría hacer cp -p /dev/sda1 /tmp/fooy /tmp/foorepresentaría el mismo dispositivo. En la línea de comando del núcleo, el núcleo utiliza un analizador incorporado que sigue la convención de nomenclatura habitual del dispositivo: sda1significa la primera partición del primer disco similar a SCSI.
Gilles 'SO- deja de ser malvado'
@Gilles, ¿los núcleos modernos aún no pueden manejar el montaje de un volumen basado en UUID? sin initrdo initramfsquiero decir. Tiene que ser una partición "simple" en el /dev/sdxformulario?
jiggunjer
1
@jiggunjer Los núcleos modernos admiten la búsqueda de un volumen por UUID. Ver init/do_mounts.c.
Gilles 'SO- deja de ser malvado'
1

Grub monta la /bootpartición y luego ejecuta el núcleo. En la configuración de Grub, le dice al núcleo qué usar como dispositivo raíz.

Por ejemplo en Grub's menu.lst:

kernel /boot/linux root=/dev/sda2
jonescb
fuente
1

Vamos, GRUB no "monta" / arranca, solo lee 'menu.lst' y algunos módulos, tampoco forma parte del núcleo LINUX. Cuando llame al núcleo, pasará un argumento "raíz" con la partición raíz. En el peor de los casos, el núcleo sabe que solo / boot ha sido montado (LOL).

A continuación: geekosaur tiene razón, Linux usa un disco RAM inicial en formato de imagen comprimido, y luego monta el sistema de archivos raíz real llamando pivot_root. Entonces, Linux comienza a ejecutarse desde una imagen, y luego desde su unidad de disco local.

D4RIO
fuente
1
Grub definitivamente tiene la capacidad de 'montar' un sistema de archivos, especialmente en grub2. Por supuesto, todo lo que es capaz de / hacer / con él es buscar núcleos de arranque de una raya u otra, pero eso sigue aumentando. Además, Linux no requiere un initrd a menos que el núcleo compile los controladores cruciales para su disco duro como módulos.
Shadur
55
ibm.com/developerworks/linux/library/l-linuxboot Este es un resumen bastante conciso de lo que hace el kernel de Linux al arrancar.
jsbillings
2
@Shadur, desde la página de manual de montaje : todos los archivos accesibles en un sistema Unix están organizados en un gran árbol, la jerarquía de archivos, enraizados en /. Estos archivos se pueden distribuir en varios dispositivos. El comando de montaje sirve para adjuntar el sistema de archivos encontrado en algún dispositivo al gran árbol de archivos. - Dado que los sistemas de archivos utilizados por GRUB no están vinculados a la jerarquía de archivos, NO se está montando .
D4RIO
1
@Shadur, por cierto: es obvio que initrd no es necesario ya que es solo otro sistema de archivos raíz, pero generalmente se usa como raíz de tiempo de arranque pequeña, ya que el núcleo carga lo necesario para arrancar, luego arranca y finalmente carga todo lo demás.
D4RIO
1
@ d4rio Están montados por GRUB, no por Linux; se hace más fácil de comprender cuando se considera a grub como un sistema operativo de microkernel propio en lugar de solo un gestor de arranque.
Shadur
1

El gestor de arranque, ya sea grub o lilo o lo que sea, le dice al kernel dónde mirar con la root=bandera, y opcionalmente carga un ramdisk inicial en la memoria initrdantes de arrancar el kernel.

Luego, el kernel se carga, prueba sus controladores de hardware y dispositivo y busca en el sistema lo que puede ver (puede revisar esta información de diagnóstico escribiendo dmesg; hoy en día probablemente se desplaza demasiado rápido para ver) y luego intenta montar la partición mencionada en El root=parámetro.

Si hay un initrd, primero se monta y cualquier módulo / controlador de dispositivo se carga y se prueba antes de montar el sistema de archivos raíz. De esta manera, puede compilar los controladores de sus discos duros como módulos y aún así poder arrancar.

Shadur
fuente