El proceso de arranque de Linux implica varias etapas y es en muchos sentidos similar al BSD y otros procesos de arranque de estilo Unix , de los que deriva. Aunque el proceso de arranque de Linux depende mucho de la arquitectura de la computadora, esas arquitecturas comparten etapas y componentes de software similares, [1] incluyendo el inicio del sistema, la ejecución del gestor de arranque , la carga y el inicio de una imagen del núcleo de Linux y la ejecución de varios scripts y daemons de inicio . [2] Estos se agrupan en 4 pasos: inicio del sistema, etapa del gestor de arranque, etapa del núcleo y proceso init. [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 carga el gestor de arranque en la RAM para su posterior ejecución. [2] En las computadoras personales (PC) compatibles con IBM PC , este firmware/programa es un monitor BIOS o UEFI , y se almacena en la placa base. [2] En los sistemas Linux integrados, este firmware/programa se llama ROM de arranque . [4] [5] Después de cargarse en la RAM, el cargador de arranque (también llamado cargador de arranque de primera etapa o cargador de arranque primario) se ejecutará para cargar el cargador de arranque de segunda etapa [2] (también llamado cargador de arranque secundario). [6] El cargador de arranque de segunda etapa cargará la imagen del núcleo en la memoria, la descomprimirá e inicializará, y luego pasará el control a esta imagen del núcleo. [2] El cargador de arranque de segunda etapa también realiza varias operaciones en el sistema, como la verificación del hardware del sistema, el montaje del dispositivo raíz, la carga de los módulos del núcleo necesarios, etc. [2] Finalmente, se inicia el primer proceso de espacio de usuario ( proceso) y se realizan otras inicializaciones del sistema de alto nivel (que involucran scripts de inicio). [2]init
Para cada una de estas etapas y componentes, existen diferentes variaciones y enfoques; por ejemplo, se pueden utilizar GRUB , coreboot o Das U-Boot como cargadores de arranque (ejemplos históricos son LILO , SYSLINUX o Loadlin ), mientras que los scripts de inicio pueden ser del estilo init tradicional , o la configuración del sistema puede realizarse a través de alternativas modernas como systemd o Upstart .
Inicio del sistema
El inicio del sistema tiene diferentes pasos según el hardware en el que se inicia Linux. [7]
El hardware compatible con IBM PC es una arquitectura en la que Linux se utiliza comúnmente; en estos sistemas, el firmware BIOS o UEFI juega un papel importante.
En los sistemas BIOS, el BIOS realizará respectivamente una prueba automática de encendido (POST), que consiste en verificar el hardware del sistema, luego enumerar los dispositivos locales 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 la red local, etc. [7] Un disco duro para arrancar Linux almacena el Registro de arranque maestro (MBR), que contiene el cargador de arranque primario/de primera etapa para cargarse en la RAM. [7]
En los sistemas UEFI , el kernel de Linux puede ser ejecutado directamente por el firmware UEFI a través del stub de arranque EFI, [8] pero normalmente utiliza GRUB 2 o systemd-boot como cargador 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 chip , que luego carga el gestor de arranque/sistema operativo desde el dispositivo de almacenamiento como eMMC, eUFS, NAND flash, etc. [5] Las secuencias de inicio del sistema varían según los procesadores [5] pero todas incluyen pasos de inicialización de hardware y prueba de hardware del sistema. [7] Por ejemplo, en un sistema con un procesador i.MX7D y un dispositivo de arranque que almacena el SO (incluido U-Boot), la ROM de arranque en chip configura primero el controlador de memoria DDR , lo que permite que el programa de la ROM de arranque obtenga los datos de configuración del SoC del gestor de arranque externo en el dispositivo de arranque. [5] La ROM de arranque en chip luego carga el U-Boot en la DRAM para la etapa del gestor de arranque. [11]
Etapa del cargador de arranque
El gestor de arranque de primera etapa, que forma parte del MBR, es una imagen de 512 bytes que contiene el código de programa específico del proveedor y una tabla de particiones. [6] Como se mencionó anteriormente en la parte de introducción, el gestor de arranque de primera etapa encontrará y cargará el gestor de arranque de segunda etapa. [6] Para ello, busca en la tabla de particiones una partición activa. [6] Después de encontrar una partición activa, el gestor de arranque de primera etapa seguirá escaneando las particiones restantes de la tabla para asegurarse de que todas estén inactivas. [6] Después de este paso, el registro de arranque de la partición activa se lee en la RAM y se ejecuta como gestor de arranque de segunda etapa. [6] El trabajo del gestor de arranque de segunda etapa es cargar la imagen del núcleo de Linux en la memoria y, opcionalmente, en el disco RAM inicial. [12] La imagen del núcleo no es un núcleo ejecutable, sino un "archivo comprimido" del núcleo , comprimido en formatos zImage o bzImage con zlib . [13]
En 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 configurarse automáticamente. La etapa 1 se carga y ejecuta mediante el BIOS desde el registro de arranque maestro (MBR). El cargador de la etapa intermedia (stage1.5, normalmente core.img) se carga y ejecuta mediante el cargador de la etapa 1. El cargador de la segunda etapa (stage2, los archivos /boot/grub/) se carga mediante el stage1.5 y muestra el menú de inicio de GRUB que permite al usuario elegir un sistema operativo o examinar y editar parámetros de inicio. Después de elegir una entrada del menú y proporcionar parámetros opcionales, GRUB carga el núcleo de Linux en la memoria y le pasa el control. GRUB 2 también es capaz de cargar en cadena otro cargador de arranque. En los sistemas UEFI , stage1 y stage1.5 generalmente son el mismo archivo de aplicación UEFI (como grubx64.efi para sistemas UEFI x64 ).
Además de GRUB, existen otros cargadores de arranque más populares:
- systemd-boot (anteriormente Gummiboot), un cargador de arranque incluido con systemd que requiere una configuración mínima ( solo para sistemas UEFI ).
- SYSLINUX/ISOLINUX es un gestor de arranque que se especializa en arrancar instalaciones completas de Linux desde sistemas de archivos FAT. Se suele utilizar para disquetes de arranque o de rescate, USB en vivo y otros sistemas de arranque ligeros. ISOLINUX se utiliza generalmente en CD en vivo de Linux y CD de instalación de arranque.
- rEFInd , un administrador de arranque para sistemas UEFI .
- Coreboot es una implementación gratuita de UEFI o BIOS y, por lo general, se implementa con la placa base y con actualizaciones de campo proporcionadas por el proveedor, si es necesario. Partes de Coreboot se convierten en el BIOS del sistema y permanecen en la memoria después del arranque.
- Das U-Boot es un gestor de arranque para sistemas integrados. Se utiliza en sistemas que no tienen BIOS/UEFI, sino que emplean métodos personalizados para leer el gestor de arranque en la memoria y ejecutarlo.
Los cargadores de arranque históricos que ya no se usan comúnmente incluyen:
- LILO no entiende ni analiza la disposición del sistema de archivos. En su lugar,
/etc/lilo.confse crea un archivo de configuración ( ) en un sistema en vivo que asigna información de desplazamiento sin procesar (herramienta de asignación) sobre la ubicación de los discos de kernel y 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 se lee este sector de arranque y la BIOS le otorga el 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 . - GRUB 1 incluye lógica para leer sistemas de archivos comunes en tiempo de ejecución para poder acceder a su archivo de configuración. [14] Esto le da a GRUB 1 la capacidad de leer su archivo de configuración desde el sistema de archivos en lugar de tenerlo incrustado en el MBR, lo que le permite cambiar la configuración en tiempo de ejecución y especificar discos y particiones en un formato legible para humanos en lugar de depender de desplazamientos. También contiene una interfaz de línea de comandos , lo que facilita la reparación o modificación de GRUB si está mal configurado o dañado. [15]
- Loadlin es un gestor de arranque que puede sustituir un núcleo de DOS o Windows 9x en ejecución por el núcleo de Linux en tiempo de ejecución. Esto puede resultar útil en el caso de hardware que necesite encenderse mediante software y para el que dichos programas de configuración sean propietarios y solo estén disponibles para DOS. Este método de arranque es menos necesario hoy en día, ya que Linux tiene controladores para una multitud de dispositivos de hardware, pero ha tenido cierto uso en dispositivos móviles . Otro caso de uso es cuando Linux se encuentra en un dispositivo de almacenamiento que no está disponible para el arranque del BIOS: DOS o Windows pueden cargar los controladores adecuados para compensar la limitación del BIOS y arrancar Linux desde allí.
Núcleo
La etapa del núcleo ocurre después de la etapa del cargador de arranque. El núcleo 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 núcleo (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 la cantidad mínima de configuración del hardware. [13] Vale la pena señalar que la imagen del núcleo se descomprime automáticamente, lo que es parte de la rutina de la imagen del núcleo. [13] Para algunas plataformas (como ARM de 64 bits), la descompresión del núcleo debe ser realizada por el cargador de arranque, como U-Boot. [16]
Para conocer los detalles de estos pasos, tomemos un ejemplo con el microprocesador i386 . Cuando se invoca su bzImage, se llama a la función start()(de ) para realizar una configuración básica del hardware y luego llama a (ubicado en ). [13] realizará la configuración básica del entorno (pila, etc.), borrará el Bloque iniciado por símbolo (BSS) y luego invocará a (ubicado en ) para descomprimir el núcleo. [13] Luego, el inicio del núcleo se ejecuta a través de una función diferente ubicada en . [13] La función de inicio para el núcleo (también llamada intercambiador o proceso 0) establece la gestió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 la funcionalidad del núcleo de Linux no específica de la arquitectura a través de una llamada a ubicado en . [13]./arch/i386/boot/head.Sstartup_32()./arch/i386/boot/compressed/head.S startup_32()decompress_kernel()./arch/i386/boot/compressed/misc.cstartup_32()./arch/i386/kernel/head.Sstartup_32()start_kernel()./init/main.c
start_kernel()ejecuta una amplia gama de funciones de inicialización. Configura el manejo de interrupciones ( IRQs ), configura aún más la memoria, monta el disco RAM inicial ("initrd") que se cargó previamente como el 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 RAM, permite que el núcleo se inicie completamente 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 los periféricos, [13] por ejemplo, el controlador SATA, y admite una gran cantidad de posibles configuraciones de hardware. [13] Esta división de algunos controladores compilados estáticamente en el núcleo y otros controladores cargados desde initrd permite un núcleo más pequeño. [13] initramfs , también conocido como espacio de usuario temprano, ha estado disponible desde la versión 2.5.46 del núcleo Linux, [17] con la intención de reemplazar tantas funciones como sea posible que anteriormente el núcleo habría realizado durante el proceso de inicio. Los usos típicos del espacio de usuario inicial son detectar qué controladores de dispositivos 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.
El sistema de archivos raíz se cambia posteriormente a través de una llamada a pivot_root()que desmonta el sistema de archivos raíz temporal y lo reemplaza con el uso del real, una vez que este último es accesible. [13] Luego se recupera la memoria utilizada por el sistema de archivos raíz temporal. [ aclaración necesaria ]
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]
De esta manera, la etapa del núcleo inicializa los dispositivos, monta el sistema de archivos raíz especificado por el gestor de arranque como de sólo lectura y ejecuta Init ( /sbin/init), que está designado como el primer proceso ejecutado por el sistema ( PID = 1). [18] El núcleo imprime un mensaje al montar el sistema de archivos y Init al iniciar el proceso Init. [18]
Según Red Hat , el proceso detallado del kernel en esta etapa se resume de la siguiente manera: [14]
- "Cuando se carga el núcleo, éste inicializa y configura inmediatamente la memoria del ordenador y configura los distintos componentes de hardware conectados al sistema, incluidos todos los procesadores, subsistemas de E/S y dispositivos de almacenamiento. A continuación, busca la imagen initrd comprimida en una ubicación predeterminada de la memoria, la descomprime, la monta y carga todos los controladores necesarios. A continuación, inicializa los dispositivos virtuales relacionados con el sistema de archivos, como LVM o RAID de software, antes de desmontar la imagen de disco initrd y liberar toda la memoria que ocupaba la imagen de disco. A continuación, el núcleo crea un dispositivo raíz, [ aclaración necesaria ] monta la partición raíz en modo de solo lectura y libera toda la memoria no utilizada. En este punto, el núcleo se carga en la memoria y está operativo. Sin embargo, dado que no hay aplicaciones de usuario que permitan una entrada significativa al sistema, no se puede hacer mucho con él". Un arranque de estilo initramfs es similar, pero no idéntico al arranque initrd descrito.
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 el proceso de inicio queda a cargo de continuar iniciando el entorno del usuario en el espacio del usuario.
Proceso de inicialización
Una vez que el núcleo se ha iniciado, inicia el proceso init , [19] un demonio que luego arranca el espacio de usuario , por ejemplo, comprobando y montando sistemas de archivos e iniciando otros procesos . El sistema init es el primer demonio que se inicia (durante el arranque) y el último en terminar (durante el apagado ).
Históricamente, este era el "SysV init", que se llamaba simplemente "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 incluye un resumen de los principales procesos de inicio:
- SysV init ( también conocido simplemente como "init") es similar a los procesos init de Unix y BSD , de los que deriva. En un sistema Linux estándar, init se ejecuta con un parámetro, conocido como nivel de ejecución , que toma un valor de 0 a 6 y determina qué subsistemas se hacen operativos. Cada nivel de ejecución tiene sus propios scripts que codifican los diversos procesos involucrados en la configuración o salida del nivel de ejecución dado, y son estos scripts los que se referencian como necesarios en el proceso de arranque. Los scripts de inicio se guardan normalmente en directorios con nombres como
"/etc/rc...". El archivo de configuración de nivel superior para init está en/etc/inittab. [20] Durante el arranque del sistema, comprueba si se especifica un nivel de ejecución predeterminado en /etc/inittab, y solicita al nivel de ejecución que ingrese a través de la consola del sistema si no es así. Luego procede a ejecutar todos los scripts de arranque relevantes para el nivel de ejecución dado, incluyendo la carga de módulos , la comprobación de la integridad del sistema de archivos raíz (que se montó como de solo lectura) y luego volver a montarlo para obtener acceso completo de lectura y escritura, y configura la red . [18] Después de haber generado todos los procesos especificados, init queda inactivo y espera que ocurra uno de tres eventos: los procesos que comenzaron a finalizar o morir, una señal de falla de energía, [ aclaración necesaria ] o una solicitud a través de/sbin/telinitpara cambiar aún más el nivel de ejecución. [21]
- systemd es una alternativa moderna a SysV init. Al igual que init, systemd es un demonio que administra otros demonios. Todos los demonios, incluido systemd, son procesos en segundo plano . Lennart Poettering y Kay Sievers , ingenieros de software que desarrollaron inicialmente systemd, [22] buscaron superar la eficiencia del demonio init de varias maneras. Querían mejorar el marco de software para expresar dependencias, permitir que se realice más procesamiento en paralelo durante el arranque del sistema y reducir la sobrecarga computacional del shell . Las instrucciones de inicialización de systemd para cada demonio se registran en un archivo de configuración declarativo en lugar de un script de shell. Para la comunicación entre procesos , systemd pone a disposición de los demonios en ejecución los sockets de dominio Unix y D-Bus . Systemd también es capaz de una paralelización agresiva.
Véase también
Referencias
- ^ M. Tim Jones 2006, "Introducción", "El proceso de arranque de un sistema Linux® consta de varias etapas. Pero, independientemente de si se arranca un escritorio x86 estándar o un objetivo PowerPC® profundamente integrado, gran parte del flujo es sorprendentemente similar".
- ^ abcdefg M. Tim Jones 2006, "Descripción general", "Figura 1. Vista general del proceso de arranque de Linux"
- ^ M. Tim Jones 2006, "El proceso de arranque de Linux se agrupa en 4 etapas, según la fuente de IBM"
- ^ Bin, Niu; Dejian, Li; Zhangjian, LU; Lixin, Yang; Zhihua, Bai; Longlong, He; Sheng, Liu (agosto de 2020). "Investigación y diseño de Bootrom que admita el modo de arranque seguro". Simposio internacional de 2020 sobre ingeniería informática y comunicaciones inteligentes (ISCEIC) . págs. 5–8. doi :10.1109/ISCEIC51027.2020.00009. ISBN 978-1-7281-8171-4. Número de identificación del sujeto 231714880.
- ↑ abcd Alberto Liberal De Los Ríos 2017, p. 28, "Proceso de arranque de Linux".
- ^ abcdef M. Tim Jones 2006, , "Cargador de arranque de etapa 1".
- ^ abcde M. Tim Jones 2006, , "Inicio del sistema".
- ^ "Núcleo de stub EFI - Wiki de Gentoo". wiki.gentoo.org . Consultado el 2 de noviembre de 2020 .
- ^ Kinney, Michael (1 de septiembre de 2000). "Resolución de problemas de arranque del BIOS con EFI" (PDF) . pp. 47–50. Archivado desde el original (PDF) el 23 de enero de 2007. Consultado el 14 de septiembre de 2010 .
- ^ "MS niega que el arranque seguro excluya a Linux". The Register. 23 de septiembre de 2011. Consultado el 24 de septiembre de 2011 .
- ↑ Alberto Liberal De Los Ríos 2017, pág. 29, "Proceso de arranque de Linux".
- ^ ab M. Tim Jones 2006, , "Cargador de arranque de etapa 2".
- ^ abcdefghijklmn M. Tim Jones 2006, "Núcleo".
- ^ ab "Documentación del producto". Redhat.com. 30 de septiembre de 2013. Archivado desde el original el 30 de agosto de 2008. Consultado el 22 de enero de 2014 .
- ^ "Documentación del producto". Redhat.com. 30 de septiembre de 2013. Consultado el 22 de enero de 2014 .
- ↑ Alberto Liberal De Los Ríos 2017, pág. 20, , "Cargador de arranque".
- ^ "Llega Initramfs" . Consultado el 14 de noviembre de 2011 .
- ^ abc http://oldfield.wattle.id.au/luv/boot.html Proceso de arranque de Linux - por Kim Oldfield (2001)
- ^ M. Tim Jones 2006, , "Inicio".
- ^ "Desde el encendido hasta el indicador de Bash: Init". users.cecs.anu.edu.au .
- ^ "inicio". man.he.net .
- ^ "systemd README". freedesktop.org . Consultado el 9 de septiembre de 2012 .
Obras citadas
- M. Tim Jones (31 de mayo de 2006). «Dentro del proceso de arranque de Linux». IBM . Archivado desde el original el 11 de octubre de 2007. Consultado el 14 de enero de 2024 .
- Alberto Liberal De Los Ríos (2017). Desarrollo de controladores de Linux para procesadores integrados (2ª ed.). Editorial Círculo Rojo; 1.ª edición (publicada el 3 de marzo de 2017). ISBN 978-8491600190.
Enlaces externos
- Lectura de las fuentes del kernel de Linux, Wikiversidad
- Greg O'Keefe - From Power Up To Bash Prompt en Wayback Machine (archivado el 23 de octubre de 2009)
- Bootchart: visualización del rendimiento del proceso de arranque
- El proceso de arranque en sistemas EFI, LWN.net , 11 de febrero de 2015, por Matt Fleming