En los sistemas Linux , initrd
( inicial ramdisk ) es un esquema para cargar un sistema de archivos raíz temporal en la memoria , para ser utilizado como parte del proceso de inicio de Linux . initrd
y initramfs
(de INITial RAM File System) se refieren a dos métodos diferentes para lograr esto. Ambos se utilizan comúnmente para hacer preparativos antes de que se pueda montar el sistema de archivos raíz real .
Muchas distribuciones Linux incluyen una única imagen genérica del núcleo Linux , que los desarrolladores de la distribución crean específicamente para arrancar en una amplia variedad de hardware. Los controladores de dispositivos para esta imagen genérica del núcleo se incluyen como módulos de núcleo cargables porque compilar estáticamente muchos controladores en un núcleo hace que la imagen del núcleo sea mucho más grande, quizás demasiado grande para arrancar en computadoras con memoria limitada, o en algunos casos causa fallos en el arranque u otros problemas debido a la búsqueda de hardware inexistente o conflictivo. Este enfoque de compilación estática del núcleo también deja módulos en la memoria del núcleo que ya no se usan ni se necesitan, y plantea el problema de detectar y cargar los módulos necesarios para montar el sistema de archivos raíz en el momento del arranque, o para el caso, deducir dónde o qué es el sistema de archivos raíz. [1]
Para complicar aún más las cosas, el sistema de archivos raíz puede estar en un volumen RAID de software, LVM , NFS (en estaciones de trabajo sin disco) o en una partición cifrada. Todos estos requieren preparaciones especiales para su montaje. [2]
Otra complicación es la compatibilidad del núcleo con la hibernación , que suspende la computadora en el disco volcando una imagen de todo el contenido de la memoria en una partición de intercambio o en un archivo normal y luego apagándola. En el siguiente arranque, esta imagen debe estar accesible antes de poder volver a cargarse en la memoria.
Para evitar tener que codificar en el núcleo el manejo de tantos casos especiales, se utiliza una etapa inicial de arranque con un sistema de archivos raíz temporal (ahora denominado espacio de usuario inicial ). Este sistema de archivos raíz puede contener ayudantes de espacio de usuario que realizan la detección de hardware, la carga de módulos y el descubrimiento de dispositivos necesarios para montar el sistema de archivos raíz real. [2]
Se debe almacenar una imagen de este sistema de archivos raíz inicial (junto con la imagen del núcleo) en algún lugar al que pueda acceder el gestor de arranque de Linux o el firmware de arranque de la computadora. Puede ser el propio sistema de archivos raíz, una imagen de arranque en un disco óptico , una pequeña partición en un disco local (una partición de arranque , que normalmente utiliza sistemas de archivos ext2 o FAT ) o un servidor TFTP (en sistemas que pueden arrancar desde Ethernet ).
El gestor de arranque cargará el núcleo y la imagen inicial del sistema de archivos raíz en la memoria y luego iniciará el núcleo, pasando la dirección de memoria de la imagen. Al final de su secuencia de arranque, el núcleo intenta determinar el formato de la imagen a partir de sus primeros bloques de datos, lo que puede conducir al esquema initrd o initramfs.
En el esquema initrd , la imagen puede ser una imagen del sistema de archivos (opcionalmente comprimida), que se pone a disposición en un dispositivo de bloque especial ( /dev/ram ) que luego se monta como el sistema de archivos raíz inicial. [3] El controlador para ese sistema de archivos debe compilarse estáticamente en el núcleo. Muchas distribuciones usaban originalmente imágenes comprimidas del sistema de archivos ext2 , mientras que otras (incluida Debian 3.1) usaban cramfs para arrancar en sistemas con memoria limitada, ya que la imagen cramfs se puede montar en el lugar sin requerir espacio adicional para la descompresión. Una vez que el sistema de archivos raíz inicial está en funcionamiento, el núcleo ejecuta /linuxrc como su primer proceso; [4] cuando sale, el núcleo asume que el sistema de archivos raíz real se ha montado y ejecuta /sbin/init para comenzar el proceso de arranque normal del espacio de usuario. [3]
En el esquema initramfs (disponible desde el kernel Linux 2.6.13), la imagen puede ser un archivo cpio (opcionalmente comprimido) o una concatenación de dichos archivos. El kernel descomprime el archivo en una instancia especial de un tmpfs que se convierte en el sistema de archivos raíz inicial. Este esquema tiene la ventaja de no requerir que se compile un sistema de archivos intermedio o controladores de bloques en el kernel. [5] Algunos sistemas utilizan el paquete dracut para crear una imagen initramfs. [6] En el esquema initramfs, el kernel ejecuta /init como su primer proceso que no se espera que salga. [5] Para algunas aplicaciones, initramfs puede utilizar la utilidad casper para crear un entorno escribible utilizando unionfs para superponer una capa de persistencia sobre una imagen de sistema de archivos raíz de solo lectura. Por ejemplo, los datos de superposición se pueden almacenar en una unidad flash USB , mientras que una imagen de solo lectura comprimida de SquashFS almacenada en un CD en vivo actúa como un sistema de archivos raíz. [7] [8]
Dependiendo de qué algoritmos se compilaron estáticamente en él, el núcleo puede descomprimir imágenes initrd/initramfs comprimidas con gzip , bzip2 , LZMA , XZ , LZO , LZ4 , [9] y zstd .
Algunas distribuciones de Linux, como Debian, generan una imagen initrd personalizada que contiene solo lo necesario para arrancar una computadora en particular, como ATA , SCSI y módulos del núcleo del sistema de archivos . Estos suelen incluir la ubicación y el tipo del sistema de archivos raíz.
Otras distribuciones de Linux (como Fedora y Ubuntu ) generan una imagen initrd más genérica. Estas comienzan solo con el nombre del dispositivo del sistema de archivos raíz (o su UUID ) y deben descubrir todo lo demás en el momento del arranque. En este caso, el software debe realizar una compleja cascada de tareas para montar el sistema de archivos raíz:
Algunas distribuciones utilizan un agente hot plug controlado por eventos como udev , que invoca programas auxiliares a medida que se conectan dispositivos de hardware, particiones de disco y volúmenes de almacenamiento que coinciden con ciertas reglas. Esto permite que el descubrimiento se ejecute en paralelo y que se conecte progresivamente en anidaciones arbitrarias de LVM, RAID o cifrado para llegar al sistema de archivos raíz.
Cuando el sistema de archivos raíz finalmente se vuelve visible, se realizan todas las tareas de mantenimiento que no se pueden ejecutar en un sistema de archivos raíz montado, el sistema de archivos raíz se monta como de solo lectura y todos los procesos que deben continuar ejecutándose (como el asistente de pantalla de inicio y su comando FIFO ) se elevan al sistema de archivos raíz recién montado.
El sistema de archivos raíz final no se puede montar simplemente sobre / , ya que eso haría que los scripts y herramientas en el sistema de archivos raíz inicial sean inaccesibles para cualquier tarea de limpieza final:
La mayoría de los sistemas de archivos raíz iniciales implementan /linuxrc o /init como un script de shell y, por lo tanto, incluyen un shell mínimo (generalmente /bin/ash ) junto con algunas utilidades esenciales para el espacio de usuario (generalmente el kit de herramientas BusyBox ). Para ahorrar aún más espacio, el shell, las utilidades y sus bibliotecas de soporte generalmente se compilan con optimizaciones de espacio habilitadas (como con el indicador "-Os" de gcc ) y se vinculan con klibc , una versión mínima de la biblioteca C escrita específicamente para este propósito. [11]
Los instaladores para distribuciones de Linux generalmente se ejecutan completamente desde un initramfs, ya que deben poder alojar la interfaz del instalador y las herramientas de soporte antes de que se haya configurado cualquier almacenamiento persistente. [ cita requerida ]
Tiny Core Linux [12] y Puppy Linux [13] [ verificación fallida ] pueden ejecutarse completamente desde initrd.
Desde Windows Vista, [14] Windows puede arrancar desde un archivo de imagen de disco WIM , para el cual se publica el formato de archivo; [15] es similar al formato ZIP excepto que admite enlaces duros, fragmentos deduplicados y utiliza compresión fragmento por fragmento. En este caso, todo el WIM se carga inicialmente en la RAM, seguido de la inicialización del núcleo. A continuación, el WIM cargado está disponible como SystemRoot con una letra de unidad asignada. El instalador de Windows utiliza esto para arrancar desde BOOT.WIM y luego utiliza INSTALL.WIM como la colección de los archivos de Windows que se instalarán.
Además, el entorno de preinstalación de Windows (Windows PE) utiliza lo mismo, siendo una base para versiones de arranque independientes de algunos antivirus y software de copia de seguridad/recuperación ante desastres.
También es posible instalar Windows de modo que siempre arranque desde un archivo WIM o VHD ubicado en una unidad física. Sin embargo, esto rara vez se utiliza, ya que el cargador de arranque de Windows es capaz de cargar los archivos .sys para los módulos del kernel en el momento del arranque, que es la tarea que requiere initrd en Linux.
Dracut utiliza parámetros del kernel enumerados en la línea de comandos del kernel de GRUB para configurar el sistema de archivos RAM initramfs sobre la marcha, lo que proporciona más flexibilidad y reduce aún más el código del sistema de archivos RAM.