Arranque del sistema

TEMARIO:

Introducción

El proceso de arranque de una computadora se inicia con el bootloader, un programa que carga el núcleo del sistema operativo. El bootloader, a su vez, puede cargar un firmware preinstalado como BIOS o UEFI. El gestor de arranque permite personalizar el inicio del sistema, pasando parámetros al núcleo, como la partición que contiene el sistema de archivos raíz o el modo de ejecución del sistema operativo. Una vez cargado el núcleo, continúa identificando y configurando el hardware del sistema. Finalmente, el núcleo del sistema operativo llama a la utilidad responsable de iniciar y administrar los servicios del sistema. Este proceso asegura que la computadora esté lista para ser utilizada y que el sistema operativo pueda ejecutar las tareas necesarias. En algunas distribuciones de Linux, los comandos ejecutados en esta lección pueden requerir privilegios de root.

BIOS o UEFI

El proceso de arranque en las máquinas x86 varía según se utilice BIOS o UEFI. El BIOS, es un firmware almacenado en un chip de memoria no volátil en la placa base, se ejecuta al encender la computadora. Este programa busca los primeros 440 bytes del primer dispositivo de almacenamiento, conocido como MBR (Master Boot Record), que contiene la primera etapa del gestor de arranque y la tabla de particiones en sistemas con el esquema de partición estándar de DOS. Si el MBR no está correcto, el sistema no arranca. Este proceso es crucial y permite que la computadora se prepare para cargar el sistema operativo.

En términos generales, los pasos previos a la operación para iniciar un sistema equipado con BIOS son:

1.- El proceso de arranque de una computadora comienza con el POST (power-on self-test), que identifica fallos en dispositivos básicos al encender la máquina.
2.- Luego, el BIOS activa componentes esenciales como la salida de video, el teclado y los medios de almacenamiento.
3.- Desde el MBR, definido por la configuración del BIOS, el BIOS carga la primera etapa del gestor de arranque, que es responsable de iniciar el proceso de arranque.
4.- Esta primera etapa del gestor de arranque, a su vez, llama a la segunda etapa, encargada de presentar opciones de arranque y cargar el núcleo del sistema operativo, permitiendo que la computadora inicie correctamente.

El UEFI (Unified Extensible Firmware Interface) es un firmware avanzado que reemplaza a la BIOS. A diferencia del BIOS, el UEFI puede identificar particiones y leer diversos sistemas de archivos. No depende del MBR, sino que utiliza la configuración almacenada en su memoria no volátil (NVRAM) conectada a la placa base. Las aplicaciones EFI, ubicadas en particiones de almacenamiento convencionales, pueden ser gestores de arranque, selectores de sistema operativo o herramientas de diagnóstico. Este enfoque permite implementar herramientas más sofisticadas que las posibles con BIOS, mejorando la funcionalidad y flexibilidad del sistema de arranque.

La partición que contiene las aplicaciones EFI se llama EFI System Partition o simplemente ESP. Esta partición no debe compartirse con otros sistemas de archivos del sistema, como el sistema de archivos raíz o los sistemas de archivos de datos del usuario. El directorio EFI en la partición ESP contiene las aplicaciones señaladas por las entradas guardadas en la NVRAM.

En términos generales, los pasos de arranque del sistema preoperativo en un sistema con UEFI son:

1.- El proceso POST (power-on self-test) se ejecuta para identificar fallas de dispositivos simples tan pronto como se enciende la máquina.
2.- El UEFI activa los componentes básicos para cargar el sistema, como salida de video, teclado y medios de almacenamiento.
3.- El firmware de UEFI lee las definiciones almacenadas en NVRAM para ejecutar la aplicación EFI predefinida almacenada en el sistema de archivos de la partición ESP. Por lo general, la aplicación EFI predefinida es un gestor de arranque.
4.- Si la aplicación EFI predefinida es un gestor de arranque, cargará el núcleo para iniciar el sistema operativo.

El estándar UEFI también admite una característica llamada Secure Boot, que solo permite la ejecución de aplicaciones EFI firmadas, es decir, aplicaciones EFI autorizadas por el fabricante del hardware. Esta característica aumenta la protección contra software malicioso, pero puede dificultar la instalación de sistemas operativos no cubiertos por la garantía del fabricante.

El Cargador de Arranque

Cuando enciendes tu computadora, el BIOS o UEFI carga el gestor de arranque GRUB, que es comúnmente utilizado en sistemas Linux para iniciar el sistema operativo. GRUB muestra una lista de sistemas operativos disponibles para que el usuario seleccione. Si esta lista no aparece automáticamente, puedes hacer que aparezca presionando la tecla Shift (en BIOS) o la tecla Esc (en UEFI) mientras el gestor de arranque está cargando. Esto te permite elegir el sistema operativo que deseas iniciar en tu computadora.

En el menú de GRUB, tienes la opción de seleccionar qué kernel instalado deseas cargar y también puedes pasarle parámetros. Los parámetros del kernel generalmente siguen el formato option=value. Algunos de los parámetros del kernel de Linux más útiles incluyen:

  • acpi.- Habilita/deshabilita el soporte ACPI. acpi=off deshabilitará la compatibilidad con ACPI.
  • init.- Establece un iniciador de sistema alternativo. Por ejemplo, init=/bin/bash establecerá shell Bash como iniciador. Esto significa que se iniciará una sesión de shell justo después del proceso de arranque del kernel.
  • systemd.unit.- Configura systemd para activarse con una unidad específica. Por ejemplo, puedes usar systemd.unit=graphical.target. Systemd también acepta los niveles de ejecución numéricos definidos para SysV. Para activar el nivel de ejecución 1, por ejemplo, solo es necesario incluir el número 1 o la letra S (abreviatura de “single”) como parámetro del núcleo.
  • mem.- Establece la cantidad de RAM disponible para el sistema. Este parámetro es útil cuando se utilizan máquinas virtuales, limitando la cantidad de RAM disponible para cada una de ellas. El uso de mem=512M limitará a 512 megabytes la cantidad de RAM disponible para un sistema virtual en particular.
  • maxcpus.- Limita el número de procesadores (o núcleos de procesador) visibles para el sistema en máquinas simétricas multiprocesador. También es útil para máquinas virtuales. Un valor de 0 desactiva el soporte para máquinas multiprocesador y tiene el mismo efecto que el parámetro del núcleo nosmp. El parámetro maxcpus=2 limitará el número de procesadores disponibles para el sistema operativo a dos.
  • quiet .- Oculta la mayoría de los mensajes de arranque.
  • vga.- Selecciona un modo de video. El parámetro vga=ask mostrará una lista de los modos disponibles para elegir.
  • root.- Establece la partición raíz, distinta de la preconfigurada en el gestor de arranque. Por ejemplo, root =/dev/sda3.
  • rootflags.- Opciones de montaje para el sistema de archivos raíz.
  • ro.- Hace que el montaje inicial del sistema de archivos raíz sea de solo lectura.
  • rw.- Permite escribir en el sistema de archivos raíz durante el montaje inicial.

Modificar los parámetros del núcleo de Linux no suele ser necesario, pero puede ayudar a diagnosticar y solucionar problemas del sistema operativo. Para hacer cambios persistentes, se agregan al archivo /etc/default/grub en la línea GRUB_CMDLINE_LINUX y se genera un nuevo archivo de configuración del gestor de arranque con el comando grub-mkconfig -o /boot/grub/grub.cfg. Durante la ejecución del sistema operativo, los parámetros del núcleo utilizados están disponibles en el archivo /proc/cmdline.

Inicialización del Sistema

El sistema operativo, además de su núcleo, depende de otros componentes para proporcionar las características y funcionalidades esperadas. Durante el inicio del sistema, se cargan diversos componentes que van desde simples scripts de consola hasta programas de servicio más complejos. Este proceso puede variar según el sistema operativo y su configuración.

Las secuencias de comandos son utilizadas comúnmente para realizar tareas de corta duración que se ejecutan y finalizan durante el proceso de inicialización del sistema. Estas pueden ser escritas en lenguajes como shell scripting (bash, PowerShell, etc.) y están diseñadas para automatizar ciertas tareas.

Los servicios o demonios son programas que pueden ejecutarse en segundo plano y pueden estar activos todo el tiempo. Son responsables de diversos aspectos intrínsecos del sistema operativo, como la gestión de servicios de red, la programación de tareas, la gestión de impresión, entre otros.

En conjunto, estos componentes colaboran para asegurar un funcionamiento adecuado del sistema operativo, proporcionando las funcionalidades necesarias para satisfacer las demandas del usuario y las aplicaciones.

La integración de scripts de inicio y demonios en una distribución de Linux puede variar ampliamente debido a la diversidad de características y enfoques. Históricamente, esta diversidad ha dificultado el desarrollo de una solución única que satisfaga a todas las distribuciones. A pesar de esto, cualquier herramienta elegida por los responsables de la distribución debería permitir iniciar, detener y reiniciar servicios del sistema. Aunque el sistema suele encargarse de estas acciones tras una actualización de software, es probable que el administrador del sistema necesite reiniciar manualmente el servicio después de realizar modificaciones en su archivo de configuración.

También es conveniente que un administrador del sistema pueda activar un conjunto particular de demonios, dependiendo de las circunstancias. Debería ser posible, por ejemplo, ejecutar solo un conjunto mínimo de servicios para realizar tareas de mantenimiento del sistema.

Cuando el sistema operativo se inicia, el gestor de arranque carga el núcleo en la memoria RAM. El núcleo, a su vez, toma el control de la CPU y procede a detectar y configurar aspectos esenciales del sistema, como la configuración de dispositivos y la gestión de la memoria.

El núcleo del sistema operativo accederá al initramfs (initial RAM filesystem), que es un archivo que contiene un sistema de archivos temporales utilizados durante el proceso de arranque. Su principal función es proporcionar los módulos necesarios para que el núcleo pueda acceder al sistema de archivos raíz «real» del sistema operativo.

Una vez que el sistema de archivos raíz esté listo, el núcleo del sistema operativo montará todos los sistemas de archivos configurados en el archivo /etc/fstab. Luego, ejecutará el primer programa, conocido como «init«. Este programa, a su vez, se encarga de iniciar todos los scripts de inicio y demonios del sistema. Hay diferentes implementaciones de este iniciador de sistema, aparte del tradicional «init«, como systemd y Upstart. Una vez que el programa init ha sido cargado, el initramfs se elimina de la memoria RAM.

SysV standard .- Un administrador de servicios basado en el estándar SysVinit controla qué demonios y recursos estarán disponibles empleando el concepto de runlevels. Los niveles de ejecución están numerados del 0 al 6 y están diseñados por los encargados de la distribución para cumplir con propósitos específicos. Las únicas definiciones de nivel de ejecución compartidas entre todas las distribuciones son los niveles de ejecución 0, 1 y 6.

systemd.- Es un administrador moderno de sistemas y servicios con una capa de compatibilidad para los comandos y niveles de ejecución de SysV. systemd tiene una estructura concurrente, emplea sockets y D-Bus para la activación del servicio, ejecución de demonios bajo demanda, monitoreo de procesos con cgroups, snapshot support, recuperación de sesión del sistema, control de punto de montaje y un control de servicio basado en la dependencia. En los últimos años, la mayoría de las principales distribuciones de Linux han adoptado gradualmente systemd como su administrador de sistema predeterminado.

Upstart.- Al igual que systemd, Upstart es un sustituto de init. El objetivo de Upstart es acelerar el proceso de arranque paralelizando el proceso de carga de los servicios del sistema. Upstart fue utilizado por distribuciones basadas en Ubuntu en versiones anteriores, pero hoy dio paso a systemd.

Inspección de Inicialización

Durante el proceso de arranque, pueden producirse errores que no detienen por completo el sistema operativo, pero que pueden afectar al funcionamiento esperado. Estos errores generan mensajes que pueden ser útiles para investigaciones futuras, ya que proporcionan información sobre cuándo y cómo ocurrió el problema. Aun cuando no se generan mensajes de error, la información recopilada durante el arranque puede ser valiosa para ajustar y configurar el sistema.

El espacio de memoria donde el kernel almacena sus mensajes, incluidos los mensajes de arranque, se llama kernel ring buffer. Los mensajes se guardan en el búfer del anillo del núcleo incluso cuando no se muestran durante el proceso de inicialización, como cuando se muestra una animación en su lugar. Sin embargo, el buffer del anillo del núcleo pierde todos los mensajes cuando el sistema está apagado o al ejecutar el comando dmesg –clear. Sin opciones, el comando dmesg muestra los mensajes actuales en el búfer del núcleo:

La salida de dmesg puede tener cientos de líneas, por lo que la lista anterior contiene solo el extracto que muestra el núcleo que llama al administrador del servicio systemd. Los valores al comienzo de las líneas son la cantidad de segundos relativos al inicio de la carga del núcleo.

En sistemas basados en systemd, el comando journalctl mostrará los mensajes de inicialización con las opciones -b, –boot,-k o –dmesg. El comando journalctl –list-boots muestra una lista de números de arranque relativos al arranque actual, su hash de identificación y las marcas de tiempo del primer y último mensaje correspondientes:

En los sistemas basados en systemd, aún puedes revisar los mensajes de las sesiones anteriores del sistema operativo. Si usas las opciones -b 0 o –boot=0, verás los mensajes del inicio actual. Con las opciones -b -1 o –boot=-1, verás los mensajes del inicio anterior. Si usas -b -2 o –boot=-2, verás los mensajes del inicio antes de ese, y así sucesivamente. A continuación, un ejemplo de cómo el sistema operativo llama al administrador del servicio systemd para el último proceso de inicio:

Los mensajes de inicialización y otros del sistema operativo se guardan en archivos dentro de /var/log/. Si hay un error crítico que impide que el sistema continúe iniciando después de cargar el kernel y el initramfs, se podría utilizar un medio de arranque alternativo para acceder al sistema de archivos y buscar posibles causas del problema en los archivos almacenados en /var/log/. El comando journalctl, con las opciones -D o –directory, puede usarse para leer mensajes de registro en directorios distintos a /var/log/journal/, que es la ubicación predeterminada para los mensajes de registro de systemd. Como estos mensajes se almacenan en texto sin formato, se requiere el comando journalctl para leerlos.