¿Cómo carga Linux la image 'initrd'?

He estado tratando de entender el process de arranque, pero solo hay una cosa que está pasando por mi cabeza.

Tan pronto como se haya iniciado el kernel de Linux y se haya montado el sistema de files raíz (/), se podrán ejecutar progtwigs y se podrán integrar más modules de kernel para proporcionar funciones adicionales. Para montar el sistema de files raíz, se deben cumplir ciertas condiciones. El kernel necesita los controlleres correspondientes para acceder al dispositivo en el que se encuentra el sistema de files raíz (especialmente los controlleres SCSI). El núcleo también debe contener el código necesario para leer el sistema de files (ext2, reiserfs, romfs, etc.). También es concebible que el sistema de files raíz ya esté encriptado. En este caso, se necesita una contraseña para montar el sistema de files.

El ramdisk inicial (también llamado initdisk o initrd) resuelve precisamente los problemas descritos anteriormente. El kernel de Linux proporciona una opción de tener un pequeño sistema de files cargado en un disco RAM y ejecutar progtwigs allí antes de que se monte el sistema de files raíz. La carga de initrd es manejada por el gestor de arranque (GRUB, LILO, etc.). Los cargadores de arranque solo necesitan rutinas BIOS para cargar datos desde el medio de arranque. Si el gestor de arranque puede cargar el kernel, también puede cargar el ramdisk inicial. No se requieren conductores especiales.

Si / boot no es una partición diferente, pero está presente en la partición /, ¿no debería el cargador de arranque requerir los controlleres SCSI para acceder a la image 'initrd' y a la image del kernel? Si puede acceder directamente a las imágenes, ¿por qué necesitamos exactamente los controlleres SCSI?

Nighpher, intentaré responder a tu pregunta, pero para una descripción más completa del process de arranque, testing el artículo de IBM .

De acuerdo, supongo que está utilizando GRUB o GRUB2 como su gestor de arranque para una explicación. En primer lugar, cuando el BIOS accede a su disco para cargar el gestor de arranque, hace uso de sus rutinas integradas para el acceso al disco, que se almacenan en la famosa interrupción de 13h. Bootloader (y kernel en la fase de configuration) hacen uso de esas rutinas cuando acceden al disco. Tenga en count que el BIOS se ejecuta en modo real (16 bits) de procesador, por lo que no puede tratar más de 2 ^ 20 bytes de RAM (2 ^ 20 no 2 ^ 16 porque cada dirección en modo real se compone de segment_address * 16 + offset , donde tanto la dirección del segmento como el desplazamiento son de 16 bits, consulte http://en.wikipedia.org/wiki/X86_memory_segmentation ). Por lo tanto, estas rutinas no pueden acceder a más de 1 MiB de RAM, que es una limitación estricta y un inconveniente importante.

El BIOS carga el código del gestor de arranque directamente desde el MBR, los primeros 512 bytes del disco y lo ejecuta. Si está utilizando GRUB, ese código es GRUB etapa 1. Ese código carga GRUB etapa 1.5, que se encuentra en los primeros 32 KiB de espacio en disco, llamado región de compatibilidad de DOS o desde una dirección fija del sistema de files. No necesita entender el sistema de files para hacer esto, porque incluso la etapa 1.5 está en el sistema de files, es un código "en bruto" y puede cargarse directamente en la RAM y ejecutarse: http://www.pixelbeat.org/ docs / disk / . La carga de la etapa 1.5 desde el disco a la RAM hace uso de las rutinas de acceso al disco de la BIOS.

enter image description here

Stage1.5 contiene las utilidades del sistema de files, por lo que puede leer el stage2 del sistema de files (bueno, todavía usa el BIOS 13h para leer desde el disco a la RAM, pero ahora puede descifrar información del sistema de files sobre inodos, etc. y get código sin procesar del disco). Es posible que las BIOS anteriores no puedan acceder a toda la HD debido a las limitaciones en el modo de direccionamiento del disco; pueden usar el sistema Cylinder-Head-Sector, que no puede abordar más de los primeros 8 GiB de espacio en disco: http: //en.wikipedia. org / wiki / Cylinder-head-sector .

Stage2 carga kernel en la RAM (de nuevo, utilizando utilidades de disco BIOS). Si es 2.6+ kernel, también tiene initramfs comstackdos, por lo que no es necesario cargarlo. Si se trata de un kernel más antiguo, el gestor de arranque también carga una image initrd independiente en la memory, para que el kernel pueda montarla y get controlleres para montar el sistema de files real desde el disco.

El problema es que kernel (y ramdisk) pesan más de 1 MiB, por lo tanto, para cargarlos en la RAM, debes cargar kernel en el primer 1 MiB, luego saltar al modo protegido (32 bit), mover el kernel cargado a la memory alta (gratis el primer 1 MiB para el modo real), luego regrese al modo real (16 bit) nuevamente, obtenga ramdisk del disco al primer 1 MiB (si es un initrd separado y kernel más antiguo), posiblemente cambie al modo protegido (32 bit) nuevamente, ponerlo donde pertenece, posiblemente volver al modo real (o no: https://stackoverflow.com/questions/4821911/does-grub-switch-to-protected-mode ) y ejecutar el código del kernel. Advertencia: no estoy del todo seguro sobre la minuciosidad y la precisión de esta parte de la descripción.

Ahora, cuando finalmente ejecuta el kernel, ya lo tiene y ramdisk cargado en la RAM por el gestor de arranque , por lo que kernel puede usar las utilidades de disco de ramdisk para montar su sistema de files raíz real y pivotear en él. Los controlleres de ramfs están presentes en el kernel, por lo que puede comprender el contenido de initramfs, por supuesto.

Creo que todo se networkinguce a las características que admite un gestor de arranque particular. P.ej. no tiene que conocer el sistema de files particular de su partición combinada (boot + root). En ese caso, solo debe crear una partición de arranque separada en condiciones tales que funcione con su gestor de arranque, y cualquier otra complejidad de cómo montar su partición raíz se deja en el kernel y la image initrd arranca desde la partición de inicio. Bootloader sabe cómo acceder a los dispositivos SCSI (y también a otros dispositivos, dependiendo de qué gestor de arranque se use) ya sea mediante el uso de sus propios controlleres o mediante el uso de rutinas BIOS. Además, sabe cómo leer algunos filesystems, etc.

Considera por ej. Manera de arranque UEFI, donde el firmware UEFI ya sabe cómo acceder a la partición EFI, leerla y cargar Linux kernel desde allí sin necesidad de un gestor de arranque intermedio. En ese caso, la image de Linux está separada de la partición raíz y el firmware UEFI no tiene que conocer todos los filesystems exóticos para acceder a ella. Creo que la separación de las imágenes de "arranque" de la partición "raíz" tiene mucho sentido. Si no fuera por algo más, entonces esto es necesario al configurar el encryption del sistema de files raíz.

Solo para el logging, si un gestor de arranque no carga initrd vale la pena probar otro gestor de arranque; Acabo de encontrarme en una situación como esta cuando LILO ignoró silenciosamente un initrd de tamaño mediano adecuadamente especificado (<4Mb; rootfs únicos ext4 en un SSD SATA; GPT) y GRUB 2.00 tuvo éxito.

El process de arranque finalizó rápidamente con un típico

 RAMDISK: Couldn't find valid RAM disk image starting at 0. Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)