CAPITULO II Inicialización y detención del Sistema En esta sección examinaremos brevemente el proceso de arranque de un sistema estándar desde que lo encendemos hasta que podemos hacer login en el mismo. Esto nos permitirá entender la forma en que se arrancan los diferentes servicios en los llamados niveles de ejecución (o runlevels), cómo pasar de un nivel a otro y cómo configurar estos niveles. MBR, particiones y cargadores Cuando booteamos desde un disco rígido, el primer sector del disco (llamado Master Boot Record) es cargado. Este sector contiene un programa cargador y la tabla de particiones del disco. El programa cargador usualmente carga el sector de booteo de la partición activa. EL sector de booteo de la partición contiene otro pequeño cargador (LILO o GRUB) que lee la primera parte del S.O. y lo inicia. El cargador Al arrancar un ordenador lo primero que este hace es un autochequeo (power on self test) comprobando que todo está en orden y se puede proceder al arranque del que se hace responsable un programa llamado el bootstrap loader1. Este programa se encuentra en la ROM BIOS del ordenador y su propósito es buscar un sector de arranque. Se llama sector de arranque al primer sector de un disco (en realidad de un sistema de ficheros, aunque también puede arrancarse un ordenador por red) y en este sector de arranque el ordenador encuentra un pequeño programa que hace posible cargar el sistema operativo. En la BIOS del ordenador (para ver cómo se accede a la misma hay que prestar atención al mensaje inicial que proporciona el sistema durante el autochequeo) hay una lista de los lugares donde el ordenador busca un sector de arranque y el orden en el que se lleva a cabo esta búsqueda. Una vez encontrado un sector de arranque se ejecuta el programa que se encuentra en él que se encarga de cargar el sistema operativo, pudiendo ser posible escoger entre varias posibilidades. En un sistema GNU/LINUX (en casi todas las distros) existen dos alternativas principales a la hora de escoger este programa, LILO y GRUB 1. El programa LILO El programa LILO (acrónimo de LInux LOader) permite configurar el arranque de un sistema GNU/Linux. Se ejecuta en dos etapas, la segunda de ellas nos proporciona un prompt, que podemos configurar para que sea de naturaleza gráfica o alfanumérica, donde se nos permite escoger entre los diferentes sistemas operativos instalados en nuestro ordenador. También podemos si fuera necesario pasar argumentos al kernel en el arranque del sistema. La primera vez que instalamos nuestro sistema se instala y se ejecuta LILO de forma que instala el cargador del sistema operativo en el sector de arranque del disco duro o MBR (Master Boot Record). También puede instalarse en el sector de arranque de alguna de las particiones que hayamos realizado. Al instalarse almacena la información acerca de los diferentes sistemas operativos que se pueden ejecutar. Cada vez que hacemos algún cambio dentro de la configuración de arranque debemos de volver a ejecutar LILO como superusuario para que dicho cambio quede reflejado en el correspondiente sector de arranque. La configuración de LILO se encuentra en el fichero “etc/lilo.conf ". A continuación incluimos un ejemplo de fichero de configuración de LILO y explicaremos las opciones más importantes Este fichero configura un sistema que Debian que arranca con dos posibles kernels, dados en la opción “image=…” y además indica que puede arrancar una partición con la distribución Mandrake o también en Windows XP (TM). Al indicar una imagen (kernel) las opciones más importantes son: 9 Label: Indica la etiqueta que identifica a esa imagen en el prompt. 9 root: Si la imagen se encuentra en una partición diferente a la partición root por defecto. 9 initrd: Fichero initrd usado por el kernel al arrancar. Además de estas opciones que afectan a cada imagen las opciones generales indican lo siguiente: 1. Especifica desde qué dispositivo se arrancará el sistema 2. Opción relacionada con la forma que tiene lilo de acceder a una unidad de fichero que aún no está montada. Desde 1998 es la opción estándar y permite superar la limitación existente en sistemas más antiguos que forzaba a que la información de arranque del sistema se encontrara en los primeros 1024 cilindros del disco. 3. Indica qué dispositivo se montará como root (/). 4. Permite leer de forma más eficiente el sector de arranque. Esta opción está especialmente indicada si se arranca desde un floppy o si se observa que el sistema tarda un tiempo inusualmente largo en cargar el kernel. 5. Fichero que se instala como sector de arranque. La opción por defecto es /boot/boot.b. 6. Número de décimas de segundo que el sistema espera antes de arrancar la imagen por defecto. 7. Localización del archivo map que contiene los kernels con los que es posible arrancar y su localización en el disco. 8. Modo de texto VGA en el que se arranca el ordenador. 9. La opción prompt muestra la información acerca de los kernels disponibles y espera da decisión del usuario durante un tiempo fijado en la opción timeout 2. El programa GRUB El nombre GRUB, acrónimo de GRand Unified Bootloader, corresponde al que hoy por hoy es probablemente el mejor cargador de sistemas (bootloader) y que, “casualmente”, entra dentro del software ofrecido por GNU. La aplicación GRUB es independiente del sistema o sistemas operativos instalados en el ordenador y podemos considerarlo como un minúsculo sistema operativo en sí mismo. El propósito de este mini s.o. es reconocer sistemas de ficheros y ficheros que sean imágenes de arranque del sistema, y trabajar con ellos, para lo cual nos proporciona tanto entornos de menú como de consola. En particular este último entorno es particularmente útil y potente, ya que por ejemplo cuenta con un historial de comandos y algunas características que hacen que aquellos que están acostumbrados a trabajar con bash se sientan como en casa. En concreto GRUB demuestra todo su potencial cuando se instala en sistemas que cuentan con múltiples sistemas operativos y modos de arranque, propios de aquellos que gustan de probar simultáneamente diferentes distribuciones GNU/Linux y a la vez conservan otros sistemas operativos en su ordenador. En principio GRUB reconoce multitud de sistemas de ficheros, pero por aquello de qué es lo más común vamos a instalarlo en un floppy con un sistema de ficheros FAT. De paso eso nos va a permitir presentar algunas herramientas importantes. BOOTEO Bootear un sistema Linux incluye etapas de diagnostico de hardware, carga del kernel en memoria, chequeo y montaje de sistema de archivos, inicio de tareas en background y daemons y establecer el funcionamiento de la red, entre otras cosas. El cargador se ocupa de cargar el kernel en memoria. La imagen del kernel se encuentra comprimida, por lo que contiene un pequeño sector de código al principio de que le indica como descomprimirse automáticamente. Cuando se termina de descomprimir el kernel el mismo se carga en memoria. La imagen del kernel se ubica en el directorio /boot y el nombre predeterminado es vmlinuz. Esta imagen es el resultado de la compilación del kernel. Una vez cargado el kernel en memoria, Linux se encuentra activo y funcionando. En este momento el S.O. comienza a cargar drivers de dispositivos y a establecer la configuración del hardware que va detectando. A medida que se instalan los drivers y se configuran dispositivos el kernel nos va mostrando mensajes que nos informan que es lo que esta realizando. Estos mensajes los podemos analizar mas tarde cuando el sistema esta iniciado ya que se van almacenando en el archivo /var/log/dmesg. Los mensajes varian dependiendo de los diferentes sistemas, del hardware que se posea, de la versión del kernel, y de como se encuentra configurada. Los mensajes que el kernel muestra pueden ser observados en la siguiente figura. Las líneas fueron numeradas para utilizarlas como referencia mas adelante. [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] Linux version 2.6.5 Tue May 11 20:15:59 ART 2006 Detected 350809121 Hz processor. Console: colour VGA+ 80x25 Calibrating delay loop... 699.60 BogoMIPS Memory: 95648k/98304k available CPU: AMD AMD-K6(tm) 3D processor stepping 0c Checking 386/387 coupling... OK, FPU using exception 16 error reporting. Checking 'hlt' intruction... OK. POSIX conformance testing by UNIFIX PCI: PCI BIOS revision 2.10 entry at 0xfb490 PCI: Using configuration type 1 PCI: Probing PCI hardware Linux NET4.0 for linux 2.2 NET4: Unix domain sockets 1.0 for linux NET4.0. NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP parport0: PC-style at 0x3bc [SPP,PS2] Detected PS/2 Mouse Port. Serial driver version 4.27 with no serial options enabled ttyS00 at 0x03f8 (irq = 4) is a 16550A ttyS01 at 0x02f8 (irq = 3) is a 16550A lp0: using parport0 (polling). apm: BIOS version 1.2 Flags 0x07 (Diver version 1.9) VP_IDE: IDE controller on PCI bus 00 dev 39 ide0: BM-DMA at 0xe000-0xe007, BIOS settings: hda:DMA, hdb:DMA ide0: VIA Bus-Master (U)DMA Timing Config Success ide0: BM-DMA at 0xe008-0xe00f, BIOS settings: hdc:DMA, hdd:DMA ide1: VIA Bus-Master (U)DMA Timing Config Success hda: ST34321A, ATA DISK drive hdb: CD-ROM TW 240D, ATAPI CDROM drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 hda: ST34321A, 4103MB w/128kB Cache, CHS=523/255/63, UDMA hdb: ATAPI 24X CD-ROM drive, 120kB Cache Uniform CDROM driver Revision: 2.54 Floppy drive(s): fd0 is 1.44M PPP: version 2.3.3 (demand dialling) TCP compression code copyright 1989 Regents of the University of California PPP line discipline registered. Partition check: hda1 hda2 hda3 hda4 VFS: Mounted root (ext3 filesystem) readonly. Freeing unused kernel memory: 48k freed Adding Swap: 40156k swap-space (priority -1) A continuación vamos a detallar las líneas más importantes: 9 [01] Nos muestra la versión del kernel, en este caso 2.6.5 y la fecha en la que se compilo el kernel. 9 [05] El kernel nos muestra la cantidad de memoria detectada en el sistema. En este caso 96 Mb. 9 [06] El kernel nos informa que procesador encontró. 9 [09] El kernel nos informa de la norma POSIX que soporta. 9 [10] El kernel nos informa de la detección de un bus PCI. 9 [13-14-15-16] En estas líneas se informa de la inicialización de los protocolos de red, en este caso TCP/IP. 9 [17-22] El kernel nos informa de la detección de un puerto paralelo que lo llama parport0 y trabaja en el puerto 0x3bc. Luego ese puerto es asignado a lp0. 9 [18] El kernel detecta un mouse PS/2 conectado al sistema. 9 [19-20-21] El kernel nos informa de la inicialización de los puertos serie. En este caso encuentra dos ttyS00 y ttyS01, 9 [29-30] Detección de un disco rígido hda y de un CD-ROM hdb. En este caso el kernel creara un link simbólico /dev/cdrom para que apunte a /dev/hdb. 9 [35] Detección de una unidad de discos flexibles de 1.44 Mb fd0. 9 [39-40] 9 [41] El kernel monta el sistema de archivos raíz, que debe ser de tipo ext3. 9 [43] El kernel inicializa el espacio de intercambio (swap) para utilizar una partición de 40 Chequeo de particiones, el kernel detecto cuatro particiones primarias (hda1, hda2, hda3, hda4). Mb. El proceso init Una vez leído el sector de arranque el siguiente paso para el sistema consiste en iniciar los diferentes servicios del ordenador, dependiendo del nivel en el que esté arrancando. Estos niveles de arranque suelen estar configurados en los sistemas UNIX usando dos sistemas diferentes: BSD o SystemV. En el caso de Debian se utiliza el sistema SystemV que es el que explicaremos brevemente, pero otros UNIX, y alguna distribución GNU/Linux (como Slackware) utilizan el modelo BSD. En el caso del modelo runlevel de SystemV, el primer proceso que arranca es el programa /sbin/init, que utiliza un fichero de configuración llamado /etc/inittab para decidir el modo de ejecución en el que va a entrar el sistema. En este fichero de configuración se define el runlevel por defecto en arranque, y una serie de servicios de Terminal para atender la entrada del usuario. Cualquier programa que coloquemos en lugar de /sbin/init se ejecutaría cuando el kernel hubiera terminado de cargarse. Un servicio es una funcionalidad proporcionada por la máquina. La activación o parada de servicios se realiza mediante la utilización de scripts. La mayoría de servicios estándar suelen tener su correspondiente fichero o directorio de configuración en el directorio /etc y se controlan mediante los scripts presentes en /etc/init.d/. En este directorio suelen aparecer scripts con nombre similar al servicio al que van destinados, y aceptan parámetros de activación o parada. Así /etc/init.d/servicio start arranca el servicio, /etc/init.d/servicio stop para el servicio y /etc/init.d/servicio restart para y después arranca el servicio. Si por ejemplo decididos reiniciar el demonio de impresión haremos como superusuario Los servicios, como habíamos comentado, se inician después de haberse cargado el kernel del sistema e iniciarse el primer proceso, denominado init. Este proceso es el responsable de ejecutar y activar el resto del sistema. Primero init corre un script inicial en bash que es /etec/init.d/rc. Este script se encarga de chequear y montar los sistemas de ficheros definidos, fijar la hora del reloj, hacer accesible es espacio de intercambio (swap space), definir el nombre del ordenador (hostname) etc. A continuación init se encarga de la gestión de los niveles de ejecución (o runlevels), Un runlevel es una configuración de software que define un estado de operación del sistema que permite existir solo a determinado grupo de procesos. Los procesos que init permite que existan en cada runlevel son especificados en el archivo /etc/inittab. En todo momento init se puede encontrar en un solo runlevel. Los runlevels validos se encuentran en un rango de 0 a 6 y se detallan a continuación: Inicio de los procesos de inicialización de terminales Una vez que el runlevel se encuentra activo, el proceso init se encarga de iniciar un proceso pro cada Terminal que se encuentre disponible para trabajar en el sistema. Cada uno de estos procesos toma una Terminal y espera pedidos de inicio de sesión consultando el estado de la Terminal. Cuando un usuario se loguea exitosamente se inicia un proceso de shell que será utilizado por ese usuario hasta que se termine su sesión en el sistema. Carga del perfil estándar El administrador del sistema crea un perfil estándar para todos los usuarios del sistema que es almacenado en el archivo /etc/profile. En este archivo se setean una variedad de variables de entorno y se realizan tareas de configuración que es necesario que se lleven a cabo para todos los usuarios. Entre otras cosas se modifica el PATH, se setea el MANPATH (es el path donde se encuentran las paginas manuales de los comandos), se setea el prompt predeterminado (variable PS1), se setean las variables USER y LOGNAME con el nombre de login del usuario que realiza el inicio de sesión, y se pueden configurar scripts para ser ejecutados en el momento que el usuario inicie la sesión. Carga de los perfiles personalizados Cada usuario puede personalizar el perfil dado por el administrador, modificando el archivo .bash_profile que se encuentra en su directorio, y que es cargado inmediatamente de que se cargue el perfil predeterminado. Este archivo además carga el archivo .bashrc que también posee configuraciones personales. Usualmente los usuarios definen en este archivo variables de entorno para uso personal, modifican el PATH a gusto, agregan alias para los comandos, etc. .---------. | MBR | ø---------ø | | \|/ .------------------. | Sector de booteo | | Partición | ø------------------ø | | \|/ .---------. | vmlinuz | ø---------ø | | \|/ .------. | init | ø------ø | | \|/ .----------------. | carga runlevel | ø----------------ø / | \ / | \____ \|/ \|/ \|/ .--------. .--------. .--------. | getty1 | | getty2 | | getty3 | ø--------ø ø--------ø ø--------ø | | | \|/ \|/ \|/ @ @ @ .-------. @ @ @ | login | ø-------ø | \|/ .---------. | profile | ø---------ø | \|/ .---------------. | .bash_profile | ø---------------ø Esquema de estados del inicio del sistema.