domingo, 25 de enero de 2009

Arranque y parada del Sistema

Durante el arranque, el sistema pasa por la siguientes fases:
→ Carga e inicialización del kernel
→ Detección de dispositivos y configuración
→ Creación de procesos de inicio
→ Ejecución de los scripts de inicio del sistema
→ Creación de terminales.


Carga del Kernel:
Usualmente en 2 pasos:
1. La RIM del sistema carga un pequeño programa (bootstrap o gestor de arranque) en memoria desde el disco.
→ la localización dle programa depende del sistema UNIX
→ en un PC, se sitúa en el MBR (Master Boot Record), primer sector del disco
2. El bootstrap localiza y carga en memoria el kernel
→ en Linux normalmente localizado en /boot (fichero vmzlinuz-versión)
3. Los gestores de arranqu más populares en Linux son LILO y GRUB.

Una vez cargado, el kernel realiza los siguientes pasos:
1. inicializa sus estructuras de datos internas (colas,tabla de procesos,etc)
2. chequea el hardware.
3. verifica la integridad del filesystem root y lo monta
→ en Linux, se cra un RAM disk a partir del fichero /boot/initrd.img-versión
4. se crean los procesos de inicio
→ en BSD, 3 procesos: swapper (0), init (1) y pagedaemon (2)
→ en System V: shed(0), init (1) y varios procesos de manejo del kernel y memoria.
→ en Linux: init (1) y varios procesos del manejo del kernel y la memoria (ksoftirqd,migration,events,etc., que en realidad son parte del kernel)
→ init se encarga de arrancar el resto de procesos

Una vez arrancado init, este inicia los scripts de inicio, que activan los demonios:
→ en BSD: ejecuta el script /etc/rc que a su vez ejecuta otros scripts
→ en System V: lee el fichero /etc/inittab desde el que se invocan scripts situados en los directorios /etc/rcx.d
→ x es el nivel de ejecución o runlevel


Niveles de ejecuión (runlevels);
El proceso init inicia el sistema en un determinado runlevel.
→ el runlevel inicial especificado en /etc/inittab
Runlevel: determinada configuración software que permite la ejecución de una serie de procesos en la máquina
Los runlevels se identifican por números de 0 a 6
0 → parada del sistema
1 → modo monousuario; solo root puede entrar
2,3,4,5 → modos multiusuario
6 → reiniciar el sistema
S → también monousuarios (usado por scripts)

La utilización de los runlevels 2-5 varía con la distribución de Linux:
→ en Debian los 4 son idénticos: modo multiusuarios completo (con entorno de ventanas, si disponible); por defecto se usa el 2
→ en RedHat y similares:
→2:multiusuario sin NFS
→3:multiusuario completo (sin ventanas)
→4:no usado
→5:multiusuario completo (con ventanas)
Es posible cambiar de runlevel en cualquier momento usando el comando telinit o init:
Formato: telinit [-t SEC] runlevel
SEC es el número de segundos que esperará init a que un procesos se detenga con un SIGTERM antes de matarlo con un SIGKILL (por defecto, 5)
Es posible hacer que init relea el fichero de configuración /etc/inittab: telinit q
Podemos saber en que runlevel nos encontramos con el comando runlevel


El fichero /etc/initab:
Define como se ejecutan los runlevels
→ indica el runlevel por defecto
→ indica los scripts a ejectuar en cada runlevel
Formato de las líneas de inittab:
identificador:runlevels:acción:proceso
→ identificador: nombre asociado a cada línea del fichero generalmente no superior a 4 caracteres
→ runlevels: lista de runlevels (todos seguidos) para los cuales esta línea se tendrá en cuenta
→ acción: indica de qué forma o bajo qué condiciones se ejecuta el comando del campo siguiente
→ proceso: comando que se ejecuta para esta entrada en los runlevels especificados

Algunas de las acciónes de init son:
→ respawn: el proceso se reinicia si termina
→ wait: init iniica el proceso y espera q ue termina para seguir
→ once: init inicia el proceso una vez, cuando se entra en el runlevel
→ sysinit: el proceso se ejecuta durante el arranque del sistema
→ ctrlaltdel: el proceso se ejecuta si se recibe un CTRL-ALT-DEL
→ powerwait: el proceso se ejecuta cuando se acaba la batería
→ powerokwait: el proceso se ejecuta cuando se recupera la energía
→ powerfailnow: el proceso se ejecuta cuando la batería está casi vacía

El script /etc/init.d/rcS se ejecuta en el arranque
→ este script llama a los scripts del directorio /etc/rcS.d
Por cada runlevel, se ejecuta el script /etc/init.d/rc X
→ este script llama a los scripts del directorio /etc/rcX.d


Directorios /etc/rcX.d:
Los ficheros de estos directorios son de la forma:
[K|S] NN Servicio
Al entrar en un runlevel se ejecutan todos los ficheros del /etc/rcX.d correspondiente
→ los que empiezan por K detienen servicios
→ los que empiezan por S los inicias
→ los scripts se ejecutan por orden alfabético (primero K y después S)
Todos los ficheros son enlaces a los scripts reales, que están en el directorio /etc/init.d
→estos script admiten, al menos, uno d elos siguientes parámetros:
→start: inicia el servicio
→stop: para el servicio

Si queremos iniciar un nuevo servicio en un determinado runlevel:
→ colocar el script de inicio en /etc/init.d
→ hacer un enlace de nombre SxyServicio en el runlevel
→ tener en cuenta posibles dependencias con otros servicios
→ hacer un enlace de nombre tipo K en el runlevel en que se quiera pararlo
→ un buen número de secuencia es 100-xy (el orden de matar los procesos inverso debe ser al de iniciarlos)
→ existen programas que nos facilitan la labor:
→ upadte-rc.d: crea y borra enlaces a los scripts init
→ sysv-rc-conf: GUI para consola
→ ksysv: entorno gŕafico para KDE



Terminales:
Despues de ejecutar los cripts de inicio, init crea un confjunto de terminales virtuales, siguiendo lo que se indica en /etc/inittab
.......
# Lanzar las terminales para el login de los usuarios
# Notar que el la mayor ́a de los sistemas tty7 es usado por X Window, . . .
# así, para añadir mas getty’s se debe saltar tty7
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

→ en esta configuración, los runlevels 2 y 3 arrancan 6 terminales y los 4 y 5 sólo 1.
→ podemos cambiar de tty con CTRL-ALT-F[1-6]
→ el tty7 se utiliza para pasar al entorno de ventanas
→ los terminales se lanzan con spawn para que se vuelvan a crear cuando salimos de la sesión.
En este momento se puede acceder al sistema:
→ al iniciar la sesión en un terminal
→el proceso tty se convierte en un proceso login que chequea usuario y contraseña
→ si se accede con éxito, el proceso login se convierte en un shell
→ al salir de la sesión
→ el proceso bash muere
→ init relanza (respawn) un nuevo tty



Gestores de arranque:

LILO:
LILO(LInux LOader): sistema de arranque muy extendido
• no depende de un sistema de ficheros específico no sabe leer sistemas de ficheros: sólo entiende localizaciones físicas dentro del disco.
• puede arrancar núcleos de Linux desde diskettes y discos duros
• permite arrancar Linux y otros sistemas operativos instalados en el sistema
PC/MS-DOS, DR DOS, OS/2, Windows 9*/NT/XP, 386 BSD, SCO UNIX, Unixware,. . .
• permite pasar parámetros a cada kernel

Estructura de LILO
• El bootloader propiamente dicho reside normalmente en /boot/boot.b
y se divide en dos partes:
Primera etapa: de pequeño tamaño para que quepa en un sector de arranque, localiza y carga la segunda etapa.
Segunda etapa: de mayor tamaño, con el resto de la lógica, se carga directamente desde el fichero.
• La primera etapa se puede guardar en varios sitios, dependiendo del sistema y del modo de arranque preferido:
en el MBR.
en el sector de arranque de una partición o de un disco flexible
• Los datos que necesita el bootloader para arrancar el sistema
se encuentran el fichero map, generalmente en /boot/map

Configuración de LILO
• La configuraci ́n se encuentra generalmente en el archivo /etc/lilo.conf
• cada vez que modifiquemos este archivo es necesario ejecutar el comando /sbin/lilo
Lee el fichero de configuración, construye el map, lee las
posiciones de los ficheros que necesita leer y escribe la
primera etapa del bootloader en su lugar

Problemas:
• LILO depende de las funciones de la BIOS para acceder al disco
• Si la BIOS no soporta el acceso a discos grandes (anteriores a 1998), la segunda etapa y todos los dem ́s ficheros que se usen, deberán estar en sectores dentro de los 1024 primeros cilindros del disco.
• LILO debe saber la posici ́n física en disco de los ficheros que carga: si esta posición cambia y LILO no se reinstala,el arranque fallará

Ejemplo de fichero /etc/lilo.conf
# Opciones globales
lba32
boot=/dev/hda
install=/boot/boot.b
map=/boot/map
prompt
timeout=50
default=linux
# im ́genes del kernel:
a
image=/boot/vmlinuz--2.4.27-2-386
label="Linux 2.4.24"
root=/dev/hda2
initrd=/boot/initrd.img-2.4.27-2-386
read-only
image=/boot/vmlinuz-2.4.20-3-686
label="Linux 2.4.20"
root=/dev/hda2
initrd=/boot/initrd.img-2.4.27-2-386
append="single"
# otros sistemas operativos:
other=/dev/hda1
label="Windows"
table=/dev/hda

Opciones globales:
• lba32 permite acceso a discos de más de 8 GB
• boot=/dev/hda dispositivo o partición donde se instala LILO
• install=bootloader indica el bootloader a usar, modo texto (boot-text.b), modo men ́ (boot.b) o modo gráfico (boot-bmp.b)
• map=map-file posición del fichero map
• prompt hace que se muestre el prompt
• timeout=50 si no se recibe una entrada del usuario en 5 segundos arranca la imagen predeterminada
• default=linux la imagen predeterminada que será cargada

Opciones para las imágenes
• image=/boot/vmlinuz... indica el fichero del kernel a cargar
• label=... nombre como aparece en el menú
• root=/dev/hda2 dispositivo que tiene la partición raiz
• initrd=/boot/initrd... archivo que contiene la imagen que será cargada en el disco RAM inicial
• append=... añade la línea especificada a los parámetros iniciales del kernel
• read-only cuando se arranca la imagen del kernel se montara el filesystem raiz de sólo lectura, para que pueda ser chequeado por fsck
• other=... permite indicar otros SO
• table=/dev/hda indica donde está la tabla de particiones de este SO


GRUB:
GRUB(GRand Unified Bootloader) es un sistema de arranque más potente que el anterior.
• desarrollado dentro del proyecto GNU
• es el preferido en muchas de las distribuciones actuales de
Linux
• diseñado para unificar el arranque entre los SO para x86
→implementa el estándar Multiboot, que permite cargar varias imágenes de arranque, necesarias para cargar kernels modulares(GNU Hurd)
• a diferencia de LILO, GRUB entiende los sistemas de ficheros
en tiempo de arranque.
→ no es necesario conocer posiciones físicas a priori
→ no es necesario ejecutar ningún programa cada vez que se cambia la configuración: sólo cuando se instala o actualiza GRUB
• Detecta automáticamente si el direccionamiento LBA está soportado por la BIOS
• Permite arrancar un kernel desde la línea de comandos del arranque sin configuración previa

Arranque con GRUB
• el arranque pasa por varias etapas:
→ en la etapa 1 se lee el MBR, que se encarga de pasar a las etapas siguientes
→ en la etapa 2 se accede al filesystem y se lee el fichero de configuración
• el fichero de configuració́n es, normalmente, /boot/grub/menu.lst
• a diferencia de LILO, si se modifica el fichero de configuración no es necesario reinstalar el MBR

Un ejemplo de /boot/grub/menu.lst
timeout 10
default 0
# Men ́ para arrancar Linux
u
title Debian GNU/Linux, kernel 2.4.27-2-386
root (hd0,1)
kernel /vmlinuz-2.4.27-2-386 root=/dev/hda3 ro
initrd /initrd.img-2.4.27-2-386
savedefault
boot
# Men ́ para arrancar Linux en modo monousuario
u
title Debian GNU/Linux, kernel 2.4.27-2-386
root (hd0,1)
kernel /vmlinuz-2.4.27-2-386 root=/dev/hda3 ro single
initrd /initrd.img-2.4.27-2-386
savedefault
boot
# Men ́ para arrancar Windows
u
title Windows
rootnoverify (hd0,0)
makeactive
chainloader +1

Opciones generales
• timeout 10 espera 10 segundos para arrancar
• default 0 arranca la primera de las imágenes
→ si default saved arranca la última imagen salvada con savedefault
Opciones para la imágenes
• title título que aparece en el menú
• root (hd0,1)
indica que el kernel está en la segunda partición de hda
• kernel /vmlinuz...root=/dev/hda3 ...
indica el fichero del kernel y donde se encuentra el directorio raiz
→ si boot se encontrara en la misma partición que raíz (hda3) habría que poner
root (hd0,2)
kernel /boot/vmlinuz...root=/dev/hda3...

• savedefault usado con default save; salva esta entrada como entrada por defecto para el próximo arranque
• boot arranca la imagen cargada (puede no ponerse)
• rootnoverify arranca desde la partición pero no intentes montarla
• makeactive pon la partición como activa (para poder arrancar desde ella)
• chainloader +1 encadena con el cargador de Windows

Reinstalar GRUB
• podemos usar grub-install para reinstalar un GRUB estropeado
• Formato:
grub-install [opciones] dispositivo
• Ejemplo: instala GRUB en /dev/hda
# grub-install /dev/hda
• Opciones:
--root-directory DIR instala GRUB en DIR/boot en vez de en /boot

Paso de parámetros al kernel
Al iniciar LILO o GRUB es posible pasar parámetros al kernel
• o bien indicandolos directamente en el menú inicial,
• o añadiendolos en lilo.conf o menu.lst
Alguno de estos parámetros son:
init=comando → haz que el comando inicial sea comando en vez de init
root=device → cambia el dispositivo del filesystem raíz
mem=valor → indica al kernel la memoria del sistema
ro/rw → monta el filesystem raíz de sólo lectura/escritura
single → inicia en modo monousuario
acpi = [on | off] → activa/desactiva el soporte ACPI


Apagado del sistema:
El apagado del sistema debría implicar los siguientes pasos:
1.envío de avisos a los posibles usuarios conectados
2. enviar una señal de TERM para terminar los procesos (si no terminan enviar kill)
3. pasar a modo monusuario
4. realizar un sync para vaciar los buffers al disco
El comando shutdown realiza todos estos pasos

Formas de apagar el sistema:
→enviar una señal TERM a init
→ no siempre funciona
→ conveniente hacer varios sync antes
→cambiar al runlevel 0 (apagar) o 6(reiniciar)
→usar el comando shutdown
→forma más recomendable
→ usar otros comandos como halt, reboot o poweroff