|
2.1
Procedura di avvio del sistema Di seguito quella che è la
procedura di avvio di una qualunque macchina che gira con un sistema
operativo Linux.
POST (power-on self test). Operazione eseguita da qualunque
macchina, indipendentemente dal sistema operativo, per verificare che
tutti componenti interni siano al loro posto.
Il bootloader LILO (LInux LOader) lancia il sistema Linux.
LILO e’ anche in grado di avviare altri sistemi operativi e, in tal
caso, all’utente e’ lasciata la scelta di selezionare il sistema
desiderato.
Il kernel e’ caricato dall’hard disk, dal floppy disk o da
altra locazione della memoria. Di default, il kernel e’ caricato dalla
directory /boot.
Il kernel e’ avviato e i relativi messaggi sono scritti nel file
/var/log/messages
Il sistema carica i moduli, le impostazioni di default e ciò che é
descritto nei file /etc/modules.conf o /etc/conf.modules
Il kernel cede il controllo al demone init, che legge il file
/etc/inittab. Il demone init ha sempre un ID di processo uguale
a 1 ed e’ il padre di molti altri demoni.
Comunemente viene eseguito il check del filesystem (fsck) ed
e’ montato (almeno) il filesystem locale.
Il sistema passa al runlevel specificato nel parametro
initdefault, indicato nel file /etc/inittab. Così facendo,
vengono lanciati gli script contenuti nella directory /etc/rc.d/
ed usualmente altri processi e demoni, per esempio il print server,
cron, etc.
Esaurita la procedura di boot, il terminale e’ attivo e pronto per
il login.
La procedura descritta potrà risultare oscura, alla prima lettura.
I paragrafi successivi chiariranno quindi i principali dettagli delle
fasi di avvio del sistema.
2.2 Runlevels
Prima di affrontare l’avvio del sistema, e’ necessario comprendere
il concetto di runlevel o livello di funzionamento. Altri sistemi
operativi hanno solo due runlevels: sistema funzionante e sistema
spento. Linux, invece, ha normalmente 7 diversi livelli di
funzionamento, indicati nella seguente tabella.
|
Runlevels di Linux |
| Runlevel |
Effetto/Scopo |
| 0 |
Il sistema e’ spento |
| 1 |
Modalita’ che consente un solo utente |
| 2 |
Modalita’ multi-utente, senza
supporto di rete |
| 3 |
Modalita’ multi-utente, con supporto
di rete |
| 4 |
Non impiegato o variabile a seconda
delle distribuzioni Linux |
| 5 |
Modalita’ multi-utente, con supporto
di rete e ambiente X attivo |
| 6 |
Shutdown e riavvio |
Un runlevel e’ una configurazione software del sistema che permette
l’esistenza solo di un gruppo selezionato di processi. I processi avviati da
init per ognuno di questi runlevel sono definiti nel file /etc/inittab.
Init puo’ essere in uno degli otto runlevel, 0-6 e S o s. Il runlevel e’
cambiato da un utente privilegiato lanciando /sbin/telinit, il quale
invia un segnale appropriato a init, indicandogli a quale runlevel passare.
Runlevel 0
Il sistema e’ in stato shutdown e richiede il riavvio manuale da parte
dell’utente. Questo stato del sistema può anche essere chiamato usando i comandi
halt o powerdown. Quando si passa a questo runlevel, i file
vengono sincronizzati col disco rigido e il sistema é posto in uno stato in cui
lo spegnimento può avvenire in modo sicuro.
Runlevel 1
Questo livello di funzionamento, anche noto come modalità amministrativa,
pone il sistema in modalità single-user. Ciò consente ad un solo utente,
tradizionalmente l’utente root, di accedere al sistema e impedisce a chiunque
altro di accedervi. Spesso, questo livello consente l’accesso tramite un solo
terminale, cioè quello definito come console. Questo livello è comunemente
impiegato per ricompilare il kernel e svolgere analoghi compiti amministrativi.
Runlevel 2
Livello in modalità multi-utente, permette a più utenti di accedere al sistema
contemporaneamente. Sono lanciati i processi in background (demoni) e sono
montati gli eventuali filesystem addizionali (il filesystem root, comunque, e’
sempre montato). Non è in esecuzione NFS (Network File System).
Runlevel 3
Livello detto anche network mode, e’ identico al livello 2 con il supporto di
rete abilitato.
Runlevel 4
Livello definito in modo variabile dai produttori di sistemi Linux. Spesso e’
inutilizzato.
Runlevel 5
Livello detto anche hardware state. E’ disponibile il prompt dei comandi e gli
utenti sono abilitati a collegarsi e scollegarsi all’ambiente grafico X.
Runlevel 6
Questo livello esegue lo shutdown e il reboot automatico, cioè lo stesso effetto
che si otterrebbe passando al runlevel 0 e poi riavviando la macchina
manualmente. E’ chiamato riavvio a caldo (warm boot) perché la corrente
elettrica continua ad alimentare l’hardware. Al contrario, il runlevel 0
rappresenta un riavvio a freddo (cold boot) perché l’alimentazione elettrica
viene tolta e deve essere poi ripristinata manualmente.
2.3
Configurazione di init e LILO
init è uno di quei programmi che sono assolutamente necessari per il
funzionamento di un sistema Linux, ma che si può quasi sempre ignorare. Di
solito preoccuparsi di init serve solo se agganciate terminali seriali, modem in
ingresso (non in uscita) o per cambiare il runlevel di default.
Quando si è avviato il kernel (cioè quando è stato caricato in memoria, si è
inizializzato ed ha inizializzato tutti i driver dei dispositivi, le strutture
dati e cose del genere), finisce la sua parte del processo di boot facendo
partire un programma a livello utente, init; quindi, init è sempre il primo
processo ed il suo numero di processo e’ sempre 1.
2.3.1 Configurazione di init: il file /etc/inittab
Quando si avvia, init legge il file di configurazione /etc/inittab. Durante
il funzionamento del sistema il file verrà riletto se gli si manda il segnale
HUP; questa caratteristica rende inutile riavviare il sistema per attivare delle
modifiche alla configurazione di init.
Il file /etc/inittab è piuttosto complicato; cominceremo con il caso
semplice della configurazione delle linee per le getty. Le linee del file /etc/inittab
consistono di quattro campi delimitati da due punti:
id:runlevel:azione:processo
Oltre a ciò, /etc/inittab può contenere linee vuote e commenti (linee che
cominciano con un cancelletto ‘\#’): entrambe vengono ignorate.
- id. Identifica la linea del file. Per le linee di getty
specifica il terminale su cui gira (il carattere dopo /dev/tty nel
nome del file di device). Per altre linee non vuol dire niente
(tranne che per le restrizioni sulla lunghezza), ma non deve essere
univoco.
- runlevel. Il runlevel per cui va considerata la linea. I
runlevel vengono indicati da una sola cifra, senza delimitatori (i
runlevel sono descritti nella prossima sezione).
- azione. L’azione che deve corrispondere alla linea, ad
esempio fare riavviare a respawn il comando nel campo successivo,
quando esiste, o a once una volta sola.
- processo. Il comando da avviare.
Per aprire una getty sul primo terminale virtuale (/dev/tty1) in tutti i
normali runlevel multiutente (2-5) si dovrebbe scrivere la seguente linea:
1:2345:respawn:/sbin/getty 9600 tty1
Il primo campo dice che questa è la linea di /dev/tty1. il secondo dice che
si applica ai runlevel 2, 3, 4 e 5. Il terzo campo significa che il comando deve
essere riavviato quando esce (in modo che ci si possa collegare, scollegare e
collegare di nuovo). L’ultimo campo è il comando che avvia la getty sul primo
terminale virtuale.
Se voleste aggiungere ad un sistema dei terminali o delle linee modem in
ingresso, dovreste aggiungere altre linee ad /etc/inittab, una per ciascun
terminale o linea. Ulteriori dettagli sono, come sempre, disponibili sulle
pagine man di init (8), inittab (5) e getty (8).
Se un comando non parte, e init è configurato per farlo ripartire (restart),
userà moltissime risorse di sistema: init lo avvia, fallisce, init lo avvia,
fallisce, e così via all’infinito. Per evitare una cosa del genere, init tiene
traccia di quanto spesso avvia un comando e se la frequenza cresce aspetterà
cinque minuti prima di avviarlo di nuovo.
I runlevel sono configurati da /etc/inittab da linee come questa:
l2:2:wait:/etc/init.d/rc 2
Il primo campo e’ un livello arbitrario, il secondo significa che la linea si
applica per il runlevel 2. Il terzo campo dice che init dovrebbe avviare il
programma che sta nel quarto campo una sola volta, quando si entra nel runlevel,
e che init deve aspettare che sia completato. Il comando /etc/init.d/rc avvia
qualsiasi comando sia necessario per far partire o interrompere i servizi per
entrare nel runlevel 2. Il comando nel quarto campo fa tutto il lavoro duro di
impostare un runlevel: inizializza i servizi che non stanno girando e ferma
quelli che non dovrebbero farlo più nel nuovo runlevel. Quale è esattamente il
comando e come sono configurati i runlevel dipende dalla distribuzione di Linux.
Quando parte, init cerca una linea in /etc/inittab che specifichi il runlevel
di default:
id:2:initdefault:
Il file /etc/inittab ha alcune caratteristiche speciali che permettono ad
init di reagire a circostanze particolari; tali caratteristiche vengono segnate
da speciali parole chiave nel terzo campo. Alcuni esempi:
- powerwait. Permette ad init di spegnere il sistema,
quando viene a mancare la corrente. Assume l’uso di un UPS e di un
software che lo controlli ed informi init che non c’è più corrente.
- ctrlaltdel. Permette ad init di riavviare il sistema,
quando l’utente preme ctrl-alt-del sulla tastiera di console. Notare
che l’amministratore di sistema può configurare la reazione a C-A-D
in modo che sia qualcos’altro, ad esempio che venga ignorata, se il
sistema è accessibile al pubblico.
- sysinit. Il comando da far partire all’avvio del sistema.
Di solito fa cose come pulire la directory /tmp.
2.3.2 LILO
LILO è il LInux LOader, il più utilizzato per la versione di Linux che gira
su processori di famiglia x86. Quando Lilo avvia il sistema, usa le chiamate del
BIOS per caricare il kernel Linux dal disco (disco IDE, dischetto o altro). Per
questo motivo, il kernel deve risiedere in un luogo che possa essere visto dal
BIOS della macchina.
All’accensione Lilo non è in grado di leggere i dati del filesystem per cui
ogni pathname che appare in /etc/lilo.conf viene risolto durante
l’installazione di Lilo (quando il superuser invoca il comando /sbin/lilo).
Tale installazione è il momento in cui il programma costruisce le tabelle che
elencano quali settori sono usati dai file coinvolti nel caricamento del sistema
operativo. Una conseguenza di cià è che tutti questi file devono risiedere in
una partizione accessibile da parte del BIOS (siccome tali file di solito
risiedono in /boot, è sufficiente che il BIOS possa leggere la partizione root
del vostro sistema).
Un’altra conseguenza dell’appoggiarsi sul BIOS è che occorre reinstallare il
programma (cioè, occorre reinvocare /sbin/lilo), ogni volta che si modifica la
configurazione del programma. Ogni volta che si ricompila il kernel e si
sovrascrive la precedente immagine, occorre reinstallare Lilo.
All’interno di /etc/lilo.conf, la direttiva boot= indica a Lilo dove
installare il loader primario, quello che viene eseguito dal BIOS all’accensione
della macchina. Come regola generale, questo codice può essere installato nel
"master boot record" (cioè in /dev/hda) oppure nella partizione root
dell’installazione Linux (di solito /dev/hda1 o /dev/hda2).
Se il proprio disco contiene un altro sistema operativo oltre a Linux,
conviene installare Lilo sulla partizione root invece che sul Master Boot
Record. In questo caso occorre marcare la partizione come "bootable"
(usando il comando a di fdisk o il comando b di cfdisk). Se il
master boot sector non viene sovrascritto risulterà più facile la
disinstallazione di Linux se dovesse sorgere il bisogno.
La maggior parte delle installazioni di Lilo utilizzano un file di
configurazione come il seguente:
boot = /dev/hda \#
oppure la partizione root
delay = 10 \# attesa, in decimi di secondo, per poter
interagire
vga = 0 \# opzionale. Si usi @b{vga=1} per un modo testo
80x50
\#linear \# si provi @b{linear} se ci sono problemi di
geometria sul disco
image = /boot/vmlinux \# il proprio file zImage
root = /dev/hda1 \# la partizione root
label = Linux \# o un altro bel nome
read-only \# root va montato in sola lettura
other = /dev/hda4 \# la partizione dos o altro sistem, se
esistente
table = /dev/hda \# la tabella delle partizioni attuale
label = dos \# o nome dell’altro sistema operativo
Si possono specificare diverse sezioni image e other se serve.
E’ in effetti abbastanza comune configurare nel proprio lilo.conf diverse
immagini del kernel, almeno per chi cerca di rimanere aggiornato con le versioni
di sviluppo del sistema.
|