¿Por qué necesito initramfs?

17

Descubrí que si elijo jffso sdcomo sistema de archivos (y no initramfs), el tamaño del kernel será muy pequeño (1.4 MB en comparación con initramfs3.4 MB). Significa que initramfsocupa un espacio considerablemente grande. Entonces, si puedo, lo eliminaría por completo y, por lo tanto, tendré un núcleo muy pequeño, que es lo que quiero.

La pregunta básica que surge en mi mente es: ¿Por qué necesito initramfs? ¿No puede arrancar un kernel de Linux sin tener un sistema de archivos inicial?

Mi aplicación final solo hará cálculo y comunicación, sin almacenamiento en absoluto. Por lo tanto, un sistema operativo sin un sistema de archivos tiene sentido, al menos para mi aplicación.

gpuguy
fuente
2
No puedes prescindir de initramfs. Es posible prescindir del archivo initramfs adicional, pero independientemente de lo que haga, el núcleo incluye su propio vacío o no. Así que no entiendo tu pregunta: ¿de qué distribución estás hablando? ¿Cómo estás construyendo tu núcleo? ¿Puede proporcionar el archivo .config del kernel? Estos son muy importantes. Sospecho que su distribución está compilando sus initramfs directamente en el kernel, y por lo tanto llenando los initramfs que de otro modo estarían vacíos, pero no puedo saber en base a la información que ha proporcionado.
mikeserv
2
@mikeserv, obviamente, un initramfs incorporado pero vacío / sin usar no cuenta.
psusi
Bueno, @psusi los documentos del kernel no están de acuerdo. Y soy tan inflexible porque no tiene por qué haber ningún misterio, es solo /rooteso. Lo único que hace de manera diferente es switch_rootpero incluso eso, siempre que se tomen las precauciones adecuadas con ciertos módulos de kernel cargados, se puede hacer en cualquier momento. Initramfs no es más que una imagen de disco: rebosante o no, está ahí. Y nunca estás sin él, es tu raíz después de todo. Simplemente no debería ser un misterio, es lo que pienso, y no me gusta toda la confusión innecesaria que lo rodea.
mikeserv
2
@mikeserv, no, / root es el directorio de inicio para el usuario root. El rootfs es /, que luego tiene la raíz real montada sobre él. Solo estás discutiendo la semántica. Para los propósitos de esta discusión, no tener un initramfs significa no tener un archivo en el disco que su cargador de arranque tiene que cargar y pasar al kernel.
psusi
Eso es cierto, solo usé / root por razones de claridad, pero te lo daré. Pero no, no son semánticas, son la mecánica fundamental de su kernel de Linux. Estas son cosas básicas. Solo tratemos de hacerlo bien.
mikeserv

Respuestas:

12

El aumento de tamaño de tener un initramfs no se debe al controlador ramfs (es solo unos pocos KB, y de todos modos es necesario para otras cosas), sino al propio initramfs. Initramfs contiene programas que son necesarios para ensamblar y montar el sistema de archivos raíz real.

Initramfs hace que sea mucho más fácil, y en algunos casos posible (por ejemplo, encriptado /), iniciar el sistema. Se recomienda encarecidamente mantenerlo en hardware estilo PC con muchos periféricos conectables en caliente. Por otro lado, tiene mucho sentido arrancar un dispositivo incrustado sin ningún initramfs, con un núcleo que solo admita la configuración de hardware particular para la que está construido.

El núcleo, por supuesto, debe iniciarse en un sistema de archivos: tiene que haber alguna forma de cargar cualquier aplicación que desee ejecutar. Si no va a ejecutar nada, es mejor que mantenga la máquina apagada.

Si no quieres usar un initramfs, solo dile a tu gestor de arranque que no pase uno. Tampoco incluya uno en la salida de la construcción del núcleo, por supuesto, cómo sucede esto si depende de la arquitectura y del cargador de arranque: por ejemplo, vmlinuxy bzImageno incluya initramfs (son el núcleo sin procesar y comprimido respectivamente ), pero uImage(para U-Boot) empaqueta tanto el núcleo como el initramfs si hay uno.

(Técnicamente, como señala mikeserv , siempre hay un initramfs, pero de manera predeterminada, es un archivo vacío de 134 bytes. Lo que está viendo y desea deshacerse de él es un initramfs "verdadero", no vacío creado por su proceso de compilación y herramientas que luego se utilizan para montar el sistema de archivos raíz).

Eso sí, un initramfs puede ser una forma razonable de hacer un sistema de aplicación única sin datos persistentes: coloque toda su aplicación en initramfs, inicie eso y guárdelo. Esto facilita la organización de su almacenamiento persistente o imagen de arranque (todo lo que necesita es el kernel y initramfs, que se pueden agrupar). Sin embargo, este enfoque tiene desventajas: todos los datos en initramfs se almacenarán en la RAM de forma permanente, y no puede modificar fácilmente los archivos en la imagen de arranque, debe reconstruir el archivo.

Gilles 'SO- deja de ser malvado'
fuente
Si está utilizando un kernel de Linux 2.6 o más reciente, tiene initramfs. Si utiliza o no una imagen secundaria initramfs, como es habitual, es otra cuestión, pero initramfs no es opcional.
mikeserv
2
@mikeserv Tienes uno, sí. Pero un initramfs vacío es maní. No tiene que usarse (lo que requiere que contenga suficientes programas para montar la raíz real, lo que aumenta el tamaño de una manera no despreciable en un sistema embebido típico).
Gilles 'SO- deja de ser malvado'
Maní obligatorio de todos modos. ¡Y no sé cuándo dije lo contrario! El autor de la pregunta solicitaba información sobre cómo eliminarlo como un sistema de archivos, lo que no es posible.
mikeserv
Y sí, tiene que usarse, sin initramfs no hay raíz. Nunca.
mikeserv
8

De LFS :

El único propósito de un initramfs es montar el sistema de archivos raíz. Initramfs es un conjunto completo de directorios que encontrará en un sistema de archivos raíz normal. Se incluye en un único archivo cpio y se comprime con uno de varios algoritmos de compresión.

...

Solo hay cuatro razones principales para tener un initramfs en el entorno LFS: cargar los rootfs desde una red, cargarlos desde un volumen lógico LVM, tener un rootfs cifrado donde se requiere una contraseña, o por la conveniencia de especificar los rootfs como ETIQUETA o UUID. Cualquier otra cosa generalmente significa que el núcleo no se configuró correctamente.

...

Para la mayoría de las distribuciones, los módulos del núcleo son la razón más importante para tener un initramfs. En una distribución general, hay muchas incógnitas, como los tipos de sistemas de archivos y los diseños de disco. En cierto modo, esto es lo contrario de LFS, donde se conocen las capacidades y el diseño del sistema y normalmente se construye un núcleo personalizado. En esta situación, rara vez se necesita un initramfs.

Otra fuente www.kernel.org

Además de esto, hay muchos sistemas Linux a los que les gustan los enrutadores que no usan initramfs.


fuente
1

Necesita un initramfs para configuraciones más complejas, como arranque de red, o lvm o raid, ya que requieren algunas utilidades de modo de usuario para configurar el acceso a la raíz fs. Para una partición simple y convencional en un disco, siempre que tenga los controladores de disco integrados en el kernel y especifique el argumento raíz por la ruta del dispositivo en lugar de UUID, puede hacerlo sin un initramfs. Por supuesto, la ruta del dispositivo está sujeta a cambios, dependiendo de los dispositivos plug and play (es decir, usb) que haya conectado, o incluso de las variaciones de temporización aleatorias, razón por la cual casi todos usan uuids y un initramfs para mayor confiabilidad.

psusi
fuente
Esto también es incorrecto.
mikeserv
66
@mikeserv, tu comentario es inútil. Si va a reclamar eso, debe explicar por qué.
psusi
He hecho, o más bien, la documentación del núcleo que compone aproximadamente el 99% de mi respuesta.
mikeserv
@mikeserv, es correcto. Estoy ejecutando Gentoo Linux desde hace años sin initramfs.
Tim
1

Esta es una pregunta antigua, pero aún no parece tener una respuesta aceptada, así que la arrojaré (no soy un experto aquí, estoy tratando de resolverlo por mí mismo).

Desde https://www.kernel.org/doc/Documentation/early-userspace/README (hasta el final, que dice que no se ha actualizado desde 2004).

El núcleo tiene actualmente 3 formas de montar el sistema de archivos raíz:

a) todos los controladores de dispositivo y sistema de archivos necesarios compilados en el kernel, sin initrd. init / main.c: init () llamará a prepare_namespace () para montar el sistema de archivos raíz final, basado en la opción root = y init = opcional para ejecutar algún otro binario init que no se encuentre al final de init / main.c: init ()

b) algunos controladores de dispositivos y sistemas de archivos construidos como módulos y almacenados en un initrd. El initrd debe contener un '/ linuxrc' binario que se supone que carga estos módulos de controlador. También es posible montar el sistema de archivos raíz final a través de linuxrc y usar el syscall pivot_root. El initrd se monta y ejecuta a través de prepare_namespace ().

c) usando initramfs. Se debe omitir la llamada a prepare_namespace (). Esto significa que un binario debe hacer todo el trabajo. Dicho binario se puede almacenar en initramfs ya sea modificando usr / gen_init_cpio.c o mediante el nuevo formato initrd, un archivo cpio. Debe llamarse "/ init". Este binario es responsable de hacer todo lo que prepare_namespace () haría.

Para mantener la compatibilidad con versiones anteriores, el binario / init solo se ejecutará si viene a través de un archivo initramfs cpio. Si este no es el caso, init / main.c: init () ejecutará prepare_namespace () para montar la raíz final y ejecutar uno de los binarios de inicio predefinidos.

Por lo que vale, creo que los dispositivos / distribuciones como Raspberry Pi, etc. no usan initramfs; en algunos casos el núcleo está en la partición raíz (montado por el gestor de arranque que tiene los módulos fs necesarios). En otros casos donde el núcleo está, por ejemplo, en una /bootpartición, se puede acceder a initramfs en la misma partición directamente antes de montar el rootfs como otros Ha establecido.

En algunos casos, initramfs puede integrarse en el mismo archivo que el kernel, pero este no es siempre el caso. (a) parece indicar con bastante claridad que, en algunos casos, initramfs no es necesario.

thom_nic
fuente
0

Encuentro la siguiente explicación más clara,

initramfses un sistema de archivos raíz que está incrustado en el núcleo y cargado en una etapa temprana del proceso de arranque. Es el sucesor de initrd. Proporciona un espacio de usuario temprano que puede hacer cosas que el núcleo no puede hacer fácilmente por sí mismo durante el proceso de arranque.

Usar initramfs es opcional. Por defecto, el núcleo inicializa el hardware utilizando controladores integrados, monta la partición raíz especificada, carga el sistema init de la distribución Linux instalada. El sistema init luego carga módulos adicionales e inicia servicios hasta que eventualmente le permite iniciar sesión. Este es un buen comportamiento predeterminado y suficiente para muchos usuarios. initramfs es para usuarios con requisitos avanzados; para usuarios que necesitan hacer las cosas lo antes posible, incluso antes de que se monte la partición raíz.

Estos son algunos ejemplos de lo que puede hacer con initramfs:

  • Montar la partición raíz (para particiones cifradas, lógicas y de otra manera especiales);
  • Proporcione un shell de rescate minimalista (si algo sale mal);
  • Personalice el proceso de arranque (por ejemplo, imprima un mensaje de bienvenida, arranque, etc.);
  • Cargar módulos (por ejemplo, controladores de terceros);
  • Cualquier cosa que el núcleo no pueda hacer (siempre que pueda hacerlo en el espacio del usuario, por ejemplo, ejecutando comandos). Si no tiene requisitos avanzados, no necesita initramfs.
Sufiyan Ghori
fuente
-1

No importa lo que hagas, tienes initramfs. No se puede prescindir de él: es el único sistema de archivos que se le impone. Desde kernel.org :

¿Qué es rootfs?

Rootfses una instancia especial de ramfs(o tmpfs, si está habilitada), que siempre está presente en los sistemas 2.6. No puede desmontarrootfs aproximadamente por la misma razón por la que no puede eliminar el proceso de inicio; en lugar de tener un código especial para verificar y manejar una lista vacía, es más pequeño y sencillo para el núcleo asegurarse de que ciertas listas no puedan quedar vacías.

La mayoría de los sistemas simplemente montan otro sistema de archivos rootfsy lo ignoran. La cantidad de espacio que ocupa una instancia vacía de ramfs es pequeña.

Si * CONFIG_TMPFS * está habilitado, rootfsse usará en tmpfslugar de ramfspor defecto. Para forzar ramfs, agregue "rootfstype=ramfs"a la línea de comando del núcleo.

¿Qué es initramfs?

Todos los núcleos 2.6 de Linux contienen un"cpio"archivo de formato comprimido, que se extrae rootfscuando se inicia el núcleo. Después de extraer, el núcleo verifica sirootfscontiene un archivoy"init" , de ser así, lo ejecuta como PID 1. Si se encuentra, esteinitproceso es responsable de llevar el sistema al resto, incluyendo la ubicación y el montaje del dispositivo raíz real ( Si alguna). Sirootfsno contiene uninitprograma después de que elcpioarchivoincrustadose extrae, el núcleo pasará al código anterior para ubicar y montar una partición raíz, y luego/sbin/initejecutaráalguna variantede eso.

Todo esto difiere del antiguo initrd de varias maneras:

  • El viejo initrd siempre fue un archivo separado, mientras que el archivo initramfs está vinculado a la imagen del kernel de Linux. (El directorio linux - * / usr está dedicado a generar este archivo durante la compilación).

  • El antiguo archivo initrd era una imagen del sistema de archivos comprimido (en algún formato de archivo, como ext2, que necesitaba un controlador integrado en el núcleo), mientras que el nuevo archivo initramfs es un archivo comprimido de cpio (como tar, más simple, vea cpio (1) y Documentation / early-userspace / buffer-format.txt). El código de extracción cpio del núcleo no solo es extremadamente pequeño, sino que también contiene texto y datos que pueden descartarse durante el proceso de arranque.

  • El programa ejecutado por el antiguo initrd (que se llamaba / initrd, no / init) realizó una configuración y luego regresó al kernel, mientras que no se espera que el programa init de initramfs regrese al kernel. (Si / init necesita transferir el control, puede sobremontarse / con un nuevo dispositivo raíz y ejecutar otro programa de inicio. Consulte la utilidad switch_root, a continuación).

  • Al cambiar otro dispositivo raíz, initrd pivot_root y luego desmontaría el ramdisk. Pero initramfs es rootfs: no se puede pivot_root rootfs, ni desmontarlo. En su lugar, elimine todo de rootfs para liberar el espacio (find -xdev / -exec rm '{}' ';'), superponga rootfs con la nueva raíz (cd / newmount; mount --move. /; Chroot.), adjunte stdin / stdout / stderr a la nueva / dev / console y ejecute el nuevo init.

Dado que este es un proceso notablemente perspicaz (e implica eliminar comandos antes de que pueda ejecutarlos), el paquete klibc introdujo un programa auxiliar (utils / run_init.c) para hacer todo esto por usted. La mayoría de los otros paquetes (como busybox) han llamado a este comando "switch_root".

Poblar initramfs:

El proceso de compilación del kernel 2.6 siempre crea un archivo initramfs en formato cpio comprimido y lo vincula al binario del kernel resultante. Por defecto, este archivo está vacío (consume 134 bytes en x86).

La opción de configuración CONFIG_INITRAMFS_SOURCE (en Configuración general en menuconfig, y viviendo en usr / Kconfig) se puede usar para especificar una fuente para el archivo initramfs, que se incorporará automáticamente al binario resultante. Esta opción puede apuntar a un archivo cpio gzipped existente, un directorio que contiene archivos para archivar o una especificación de archivo de texto como el siguiente ejemplo:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Ejecute "usr / gen_init_cpio" (después de la compilación del núcleo) para obtener un mensaje de uso que documente el formato de archivo anterior.

Una ventaja del archivo de configuración es que no se requiere acceso a la raíz para establecer permisos o crear nodos de dispositivo en el nuevo archivo. (Tenga en cuenta que esas dos entradas de "archivo" de ejemplo esperan encontrar archivos llamados "init.sh" y "busybox" en un directorio llamado "initramfs", en el directorio linux-2.6. *. Consulte Documentación / early-userspace / README para más detalles.)

El kernel no depende de herramientas externas de cpio. Si especifica un directorio en lugar de un archivo de configuración, la infraestructura de compilación del núcleo crea un archivo de configuración a partir de ese directorio (usr / Makefile llama a scripts / gen_initramfs_list.sh), y procede a empaquetar ese directorio utilizando el archivo de configuración (al alimentarlo a usr / gen_init_cpio, que se crea a partir de usr / gen_init_cpio.c). El código de creación de cpio en tiempo de compilación del núcleo es completamente autónomo, y el extractor de tiempo de arranque del núcleo también es (obviamente) autónomo.

mikeserv
fuente
1
Puede arrancar sin un initramfs. Su respuesta explica los méritos de initramfs, pero eso no se aplica a los sistemas embebidos típicos, e incluso en escritorios o servidores donde se recomienda un initramfs, no es obligatorio.
Gilles 'SO- deja de ser malvado'
@Gilles: no, no puedes. Independientemente de lo que hagas, tienes initramfs. Está compilado en el núcleo, ahora mismo, su núcleo, mi núcleo, todos nuestros núcleos. Lea los documentos del kernel: toda mi publicación fue copiar y pegar. Eres incorrecto ¿Cómo se puede disputar la documentación oficial?
mikeserv
1
No disputo la documentación oficial, disputo las conclusiones que extraes de ella. Estás leyendo documentación que explica cómo usar un initramfs. En ninguna parte indica que se debe usar initramfs.
Gilles 'SO- deja de ser malvado'
@Gilles Si esto no es lo suficientemente bueno: "El proceso de compilación del kernel 2.6 siempre crea un archivo initramfs de formato cpio comprimido y lo vincula al binario del kernel resultante. Por defecto, este archivo está vacío (consume 134 bytes en x86) ... " Puedo hacerlo mejor. Lo anterior fue una búsqueda web de 2 o 3 minutos.
mikeserv
3
He leido la documentación. Hago esto para vivir. No es una cuestión de opinión. Siempre hay un initramfs, pero no necesariamente se usa para arrancar. No puedo encontrar una explicación decente de la estructura del núcleo para ese caso, presumiblemente porque es el caso clásico que se cree que no justifica una explicación. La lógica principal está en do_mounts.c- específicamente prepare_namespace, en la que saved_root_nameviene poblada con el root=argumento de línea de comando.
Gilles 'SO- deja de ser malvado'