El proceso de arranque de Linux implica múltiples etapas y es en muchos aspectos similar a BSD y otros procesos de arranque de estilo Unix , de los cuales deriva. Aunque el proceso de arranque de Linux depende en gran medida de la arquitectura de la computadora, esas arquitecturas comparten etapas y componentes de software similares, [1] incluido el inicio del sistema, la ejecución del gestor de arranque , la carga y el inicio de una imagen del kernel de Linux y la ejecución de varios scripts y demonios de inicio . [2] Estos se agrupan en 4 pasos : inicio del sistema , etapa del gestor de arranque , etapa del kernel y proceso de inicio . [3] Cuando un sistema Linux se enciende o se reinicia, su procesador ejecutará un firmware/programa específico para la inicialización del sistema , como la autoprueba de encendido , invocando el vector de reinicio para iniciar un programa en una dirección conocida en flash/ ROM (en dispositivos Linux integrados), luego cargue el gestor de arranque en la RAM para su posterior ejecución. [2] En las computadoras personales (PC), no solo limitadas a las PC con distribución de Linux, este firmware/programa se llama BIOS y se almacena en la placa base. [2] En el sistema Linux integrado, este firmware/programa se llama ROM de arranque . [4] [5] Después de cargarse en la RAM, el gestor de arranque (también llamado gestor de arranque de primera etapa o gestor de arranque primario ) se ejecutará para cargar el gestor de arranque de segunda etapa [2] (también llamado gestor de arranque secundario ). [6] El gestor de arranque de segunda etapa cargará la imagen del kernel en la memoria, la descomprimirá e inicializará y luego pasará el control a esta imagen del kernel. [2] El cargador de arranque de segunda etapa también realiza varias operaciones en el sistema, como verificar el hardware del sistema, montar el dispositivo raíz, cargar los módulos del kernel necesarios, etc. [2] Finalmente, se inicia el primer proceso de espacio de usuario ( init
proceso) y Se realizan otras inicializaciones del sistema de alto nivel (que involucran scripts de inicio). [2]
Para cada una de estas etapas y componentes, existen diferentes variaciones y enfoques; por ejemplo, GRUB , coreboot o Das U-Boot se pueden usar como cargadores de arranque (los ejemplos históricos son LILO , SYSLINUX o Loadlin ), mientras que los scripts de inicio pueden ser de estilo init tradicional o la configuración del sistema se puede realizar a través de alternativas modernas como como systemd o Upstart .
El inicio del sistema tiene diferentes pasos según el hardware en el que se inicia Linux, especialmente entre Linux integrado y una PC con Linux. [7] Como se mencionó anteriormente en la parte de introducción, durante la etapa de inicio del sistema, se llama al firmware del BIOS . El hardware compatible con IBM PC es una arquitectura en la que se usa comúnmente Linux; En estos sistemas, el BIOS juega un papel importante. El BIOS realizará respectivamente una autoprueba de encendido (POST), que consiste en verificar el hardware del sistema, luego enumerar el dispositivo local y finalmente inicializar el sistema . [7] Para la inicialización del sistema, el BIOS comenzará buscando el dispositivo de arranque en el sistema que almacena el sistema operativo. Un dispositivo de arranque puede ser un dispositivo de almacenamiento como un disquete, un CD-ROM, una unidad flash USB, una partición en un disco duro (donde un disco duro almacena varios sistemas operativos, por ejemplo, Windows y Fedora), un dispositivo de almacenamiento en una red local, etc. 7] Un disco duro para iniciar Linux almacena el Master Boot Record ( MBR ), que contiene el gestor de arranque primario/de primera etapa para cargarse en la RAM. [7] Compatible con IBM PC reemplaza BIOS por UEFI. En los sistemas UEFI , el kernel de Linux se puede ejecutar directamente mediante el firmware UEFI a través de EFISTUB, [8] pero generalmente usa GRUB 2 o systemd-boot como gestor de arranque. [9] [10]
La etapa de inicio del sistema en un sistema Linux integrado comienza ejecutando el firmware/programa en la ROM de arranque en el chip , que se almacena en el dispositivo de almacenamiento del sistema, como unidad flash USB, tarjeta SD, eMMC, flash NAND, flash NOR, etc. [5] Las secuencias de inicio del sistema en la ROM de arranque en chip varían según los procesadores [5] pero todas incluyen pasos de inicialización del hardware y prueba del hardware del sistema . [7] Por ejemplo, en un sistema con un procesador i.MX7D y un dispositivo de arranque que almacena el sistema operativo (incluido U-Boot, un cargador de arranque externo), la ROM de arranque en el chip configura el controlador de memoria DDR al principio, lo que permite la programa de arranque ROM para obtener los datos de configuración del SoC del cargador de arranque externo en el dispositivo de arranque. [5] La ROM de arranque en el chip luego carga el U-Boot en la RAM para la etapa del gestor de arranque. [11]
El gestor de arranque de primera etapa , que forma parte del MBR, es una imagen de 512 bytes que contiene el código del programa específico del proveedor y una tabla de particiones . [6] Como se mencionó anteriormente en la parte de introducción, el cargador de arranque de la primera etapa encontrará y cargará el cargador de arranque de la segunda etapa . [6] Lo hace buscando en la tabla de particiones una partición activa. [6] Después de encontrar una partición activa, el gestor de arranque de la primera etapa seguirá escaneando las particiones restantes en la tabla para asegurarse de que estén todas inactivas. [6] Después de este paso, el registro de inicio de la partición activa se lee en la RAM y se ejecuta como el gestor de arranque de segunda etapa. [6] El trabajo del gestor de arranque de la segunda etapa es cargar la imagen del kernel de Linux en la memoria y en el disco RAM inicial opcional . [12] La imagen del kernel no es un kernel ejecutable, sino un "archivo comprimido" del kernel , comprimido en formatos zImage o bzImage con zlib . [13]
En la PC x86, los cargadores de arranque de primera y segunda etapa se combinan en GRand Unified Bootloader ( GRUB ), y anteriormente Linux Loader ( LILO ). [12] GRUB 2 , que se utiliza ahora, se diferencia de GRUB 1 por ser capaz de detectar automáticamente varios sistemas operativos y configurarlos automáticamente. El stage1 se carga y ejecuta mediante el BIOS desde el registro de arranque maestro (MBR). El cargador de etapa intermedia (stage1.5, generalmente core.img) es cargado y ejecutado por el cargador de etapa1. El cargador de segunda etapa (etapa 2, los archivos /boot/grub/) lo carga el stage1.5 y muestra el menú de inicio de GRUB que permite al usuario elegir un sistema operativo o examinar y editar los parámetros de inicio. Después de elegir una entrada del menú y proporcionar parámetros opcionales, GRUB carga el kernel de Linux en la memoria y le pasa el control. GRUB 2 también es capaz de cargar en cadena otro gestor de arranque. En los sistemas UEFI , stage1 y stage1.5 suelen ser el mismo archivo de aplicación UEFI (como grubx64.efi para sistemas UEFI x64 ).
Además de GRUB, existen algunos gestores de arranque más populares:
Los cargadores de arranque históricos, que ya no son de uso común, incluyen:
/etc/lilo.conf
se crea un archivo de configuración ( ) en un sistema en vivo que asigna información de compensación sin procesar (herramienta de mapeo) sobre la ubicación del kernel y los discos ram (initrd o initramfs). El archivo de configuración, que incluye datos como la partición de arranque y la ruta del kernel para cada uno, así como opciones personalizadas si es necesario, se escribe junto con el código del cargador de arranque en el sector de arranque MBR. Cuando BIOS lee este sector de arranque y le da control, LILO carga el código del menú y lo dibuja, luego usa los valores almacenados junto con la entrada del usuario para calcular y cargar el kernel de Linux o cargar en cadena cualquier otro cargador de arranque .La etapa del kernel ocurre después de la etapa del gestor de arranque. El kernel de Linux maneja todos los procesos del sistema operativo, como la administración de memoria , la programación de tareas , la E/S , la comunicación entre procesos y el control general del sistema. Esto se carga en dos etapas: en la primera etapa, el kernel (como un archivo de imagen comprimido) se carga en la memoria y se descomprime , y se configuran algunas funciones fundamentales, como la administración básica de la memoria y una cantidad mínima de configuración de hardware. [13] Vale la pena señalar que la imagen del kernel se autodescomprime , lo cual es parte de la rutina de la imagen del kernel . [13] Para algunas plataformas (como ARM de 64 bits), la descompresión del kernel debe ser realizada por el gestor de arranque, como U-Boot. [dieciséis]
Para obtener detalles de esos pasos, tome un ejemplo con el microprocesador i386 . Cuando se invoca su bzImage, se llama a la función start()
(de ./arch/i386/boot/head.S
) para realizar alguna configuración básica del hardware y luego llama startup_32()
(ubicada en ./arch/i386/boot/compressed/head.S
). [13] startup_32()
realizará la configuración básica del entorno (pila, etc.), borrará el bloque iniciado por símbolo (BSS) y luego invocará decompress_kernel()
(ubicado en ./arch/i386/boot/compressed/misc.c
) para descomprimir el kernel. [13] El inicio del kernel se ejecuta a través de una startup_32()
función diferente ubicada en ./arch/i386/kernel/head.S
. [13] La función de inicio startup_32()
del kernel (también llamada swapper o proceso 0) establece la administración de la memoria (tablas de paginación y paginación de memoria), detecta el tipo de CPU y cualquier funcionalidad adicional, como capacidades de punto flotante , y luego cambia a modo no- funcionalidad específica del kernel de Linux a través de una llamada a start_kernel()
ubicada en ./init/main.c
. [13]
start_kernel()
ejecuta una amplia gama de funciones de inicialización. Configura el manejo de interrupciones ( IRQ ), configura aún más la memoria, monta el disco RAM inicial (" initrd ") que se cargó previamente como sistema de archivos raíz temporal durante la etapa del cargador de arranque. [13] El initrd, que actúa como un sistema de archivos raíz temporal en la RAM, permite que el kernel se inicie por completo y que los módulos del controlador se carguen directamente desde la memoria, sin depender de otros dispositivos (por ejemplo, un disco duro). [13] initrd contiene los módulos necesarios para interactuar con periféricos, [13] por ejemplo, controlador SATA, y admite una gran cantidad de configuraciones de hardware posibles. [13] Esta división de algunos controladores compilados estáticamente en el kernel y otros controladores cargados desde initrd permite un kernel más pequeño. [13] initramfs , también conocido como espacio de usuario inicial , ha estado disponible desde la versión 2.5.46 del kernel de Linux, [17] con la intención de reemplazar tantas funciones como sea posible que anteriormente el kernel habría realizado durante el proceso de inicio. Los usos típicos del espacio de usuario inicial son detectar qué controladores de dispositivo se necesitan para cargar el sistema de archivos del espacio de usuario principal y cargarlos desde un sistema de archivos temporal . Muchas distribuciones utilizan dracut para generar y mantener la imagen initramfs.
Posteriormente, el sistema de archivos raíz se cambia mediante una llamada pivot_root()
que desmonta el sistema de archivos raíz temporal y lo reemplaza con el real, una vez que se puede acceder a este último. [13] Luego se recupera la memoria utilizada por el sistema de archivos raíz temporal. [ se necesita aclaración ]
Finalmente, se llama a kernel_thread
(in arch/i386/kernel/process.c
) para iniciar el proceso Init (el primer proceso del espacio de usuario) y luego inicia la tarea inactiva a través de cpu_idle()
. [13]
Por lo tanto, la etapa del kernel inicializa los dispositivos, monta el sistema de archivos raíz especificado por el gestor de arranque como de solo lectura y ejecuta Init ( /sbin/init
), que está designado como el primer proceso ejecutado por el sistema ( PID = 1). [18] El kernel imprime un mensaje al montar el sistema de archivos y Init al iniciar el proceso de Init. [18]
Según Red Hat , el proceso detallado del núcleo en esta etapa se resume de la siguiente manera: [14]
En este punto, con las interrupciones habilitadas, el programador puede tomar el control de la gestión general del sistema, para proporcionar multitarea preventiva, y se deja el proceso de inicio para continuar iniciando el entorno del usuario en el espacio del usuario.
Una vez que el kernel se ha iniciado, inicia el proceso de inicio , [19] un demonio que luego inicia el espacio del usuario , por ejemplo verificando y montando sistemas de archivos , e iniciando otros procesos . El sistema de inicio es el primer demonio que se inicia (durante el arranque) y el último demonio que termina (durante el apagado ).
Históricamente, este era el "init SysV", que simplemente se llamaba "init". Es probable que las distribuciones de Linux más recientes utilicen una de las alternativas más modernas, como systemd . A continuación se muestra un resumen de los principales procesos de inicio:
"/etc/rc..."
. El archivo de configuración de nivel superior para init está en /etc/inittab
. [20] Durante el arranque del sistema, verifica si se especifica un nivel de ejecución predeterminado en /etc/inittab y, en caso contrario, solicita que el nivel de ejecución ingrese a través de la consola del sistema . Luego procede a ejecutar todos los scripts de arranque relevantes para el nivel de ejecución determinado, incluida la carga de módulos , la verificación de la integridad del sistema de archivos raíz (que se montó como de solo lectura) y luego lo vuelve a montar para obtener acceso completo de lectura y escritura, y configura el red . [18] Después de haber generado todos los procesos especificados, init queda inactivo y espera a que ocurra uno de tres eventos: procesos que comenzaron a finalizar o morir, una señal de falla de energía, [ se necesita aclaración ] o una solicitud vía /sbin/telinit
para continuar cambiar el nivel de ejecución. [21]