I retroscena del processo di avvio

NotaNota Bene
 

Questa sezione si dedica in particolare al processo di avvio con processore x86, che può variare leggermente a seconda dell'architettura del vostro sistema. Comunque, quando il kernel viene rilevato e caricato dal sistema, il processo di avvio di default è identico per tutte le architetture. Per maggiori informazioni su un processo di avvio diverso da x86, consultate la la sezione Differenze nel processo di avvio di altre architetture.

Quando un computer viene avviato, il processore controlla alla fine il BIOS (Basic Input/Output System) alla fine della memoria di sistema e lo avvia. Il programma BIOS è scritto in una memoria permanente in sola lettura e può sempre essere utilizzato. Il BIOS fornisce l'interfaccia per le periferiche e controlla la prima fase del processo di avvio.

Il BIOS testa il sistema, cerca e controlla le periferiche e poi cerca un'unità da utilizzare per avviare il sistema. Di solito controlla nell'unità floppy (o CD-ROM, nei sistemi più recenti) se vi sono supporti avviabili e poi controlla il disco fisso. Nella maggior parte dei casi,la sequenza delle unità utilizzate per l'avvio è controllata da una particolare configurazione del BIOS. Quando Red Hat Linux viene installato sul disco fisso di un sistema il BIOS cerca un Master Boot Record (MBR) nel primo settore del primo disco fisso, ne carica il contenuto in memoria e gli passa il controllo del processo.

Il codice di questo MBR cerca la prima partizione attiva e poi ne legge il record di avvio contenente le istruzioni su come caricare il loader di avvio LILO (LInux LOader). L'MBR carica poi LILO, che assume il controllo del processo (se LILO è installato sull'MBR). Nella configurazione di default di Red Hat Linux, LILO utilizza le impostazioni nell'MBR per visualizzare le opzioni di avvio e autorizzare l'input utente con cui il sistema operativo si avvia.

Probabilmente vi starete domandando come fa LILO a sapere cosa fare una volta letto l'MBR. LILO in realtà ha già letto le istruzioni usando lilo con il file di configurazione /etc/lilo.conf.

Opzioni nel file /etc/lilo.conf

In genere non occorre cambiare il Master Boot Record sul disco fisso, a meno che non dobbiate avviare un sistema operativo appena installato oppure stiate cercando di utilizzare un nuovo kernel. Se dovete creare un nuovo MBR utilizzando LILO, ma con una configurazione diversa, è necesssario modificare /etc/lilo.conf e rieseguire lilo.

AttenzioneAvvertimento
 

Se intendete modificare /etc/lilo.conf, assicuratevi di effettuare una copia di backup del file prima di eseguire qualsiasi modifica. Inoltre controllate di avere un dischetto di avvio funzionante, in modo da poter avviare il sistema ed effettuare le modifiche all'MBR se si verificano dei problemi. Per maggiori informazioni su come creare un dischetto di avvio, consultate le pagine man relative a mkbootdisk.

Il file /etc/lilo.conf viene utilizzato da lilo per stabilire quale sistema operativo utilizzare o quale kernel avviare e dove installare se stesso (per esempio /dev/hda per il primo dispositivo IDE). Ecco un esempio del file /etc/lilo.conf:

boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
message=/boot/message
lba32
default=linux

image=/boot/vmlinuz-2.4.0-0.43.6
	label=linux
	initrd=/boot/initrd-2.4.0-0.43.6.img
	read-only
	root=/dev/hda5

other=/dev/hda1
	label=dos

Questo esempio mostra un sistema configurato per avviare due sistemi operativi: Red Hat Linux e DOS. Qui di seguito sono visualizzate più in dettaglio alcune delle righe di questo file (il vostro /etc/lilo.conf potrebbe essere leggermente diverso):

Successivamente LILO mostra la videata iniziale Red Hat Linux con i diversi sistemi operativi instalati o i kernel che deve avviare. Se Red Hat Linux è il vostro unico sistema operativo e non avete modificato nulla in /etc/lilo.conf, vedrete come unica opzione linux. Se avete configurato LILO per avviare altri sistemi operativi, in questa videata potete selezionare quale sistema operativo eseguire. Utilizzate i tasti freccia per evidenziare il sistema da avviare e poi premete Invio

Se desiderate un prompt dove inserire i comandi per LILO, premete Ctrl-X. In questo modo LILO visualizza il prompt LILO: sullo schermo e attende un input dell'utende per un periodo di tempo prestabilito. (Questa quantità di tempo viene impostata dalla riga timeout nel file /etc/lilo.conf). Se il file di configurazione /etc/lilo.conf è impostato per far caricare a LILO diversi sistemi operativi, è ora necessario inserire il nome del sistema operativo che si desidera avviare.

Se LILO sta avviando Linux, carica innanzitutto in memoria il kernel con il file vmlinuz (più un numero di versione, per esempio: vmlinuz-2.4.0-xx) che si trova nella directory /boot. Il kernel passa poi il controllo a init.

Quando viene caricato il kernel, Linux è già operativo, ma solo a un livello base. Comunque senza applicazioni e senza la possibilità di fornire un input al sistema, non si può fare molto. Il programma init risolve questo problema, attivando i vari servizi che consentono al sistema di svolgere il proprio ruolo.

Init

Il kernel individua init nella directory /sbin e lo esegue. init poi coordina la fase restante del processo di avvio.

Quando init viene eseguito, diventa il padre di tutti i processi che si avviano automaticamente sul sistema Red Hat Linux. Innanzitutto esegue lo script /etc/rc.d/rc.sysinit che imposta il percorso, attiva lo swapping, controlla i filesystem e così via. In sostanza, rc.sysinit si occupa di tutti i processi che vanno eseguiti all'inizializzazione del sistema. Per esempio, su un sistema in rete, rc.sysinit utilizza le informazioni contenute nel file /etc/sysconfig/network per inizializzare i processi di rete. La maggior parte dei sistemi utilizza un orologio e rc.sysinit usa il file /etc/sysconfig/clock per inizializzare l'orologio. Se dovete inizializzare processi speciali per le porte seriali, rc.sysinit può eseguire anche rc.serial.

In seguito, init esegue lo script /etc/inittab, che descrive il modo in cui il sistema va configurato per ogni runlevel e imposta il runlevel di default. (Per maggiori informazioni sulla configurazione dei runlevel, consultate la la sezione Inizializzazione dei runlevel). Questo file specifica, tra le altre cose, che /sbin/update va eseguito a ogni avvio dei runlevel. Il programma update viene utilizzato per ripulire i buffer difettosi su disco.

Quando si cambia un runlevel, init utilizza gli script in /etc/rc.d/init.d per avviare e bloccare diversi servizi come il server web, il server DNS ecc. Innanzitutto init configura la libreria delle funzioni sorgenti per il sistema (di solito /etc/rc.d/init.d/functions), che stabilisce come avviare o terminare un programma e come trovarne il PID. In seguito init determina il runlevel attuale e quello precedente.

A questo punto init avvia tutti i processi di background necessari al sistema per funzionare cercando nella relativa directory rc il runlevel (/etc/rc.d/rc<x>.d, dove <x> è un numero da 0 a 6). init termina tutti gli script kill (il loro nome comincia con una K), poi inizializza tutti gli script start (il loro nome comincia per S) nella directory di runlevel idonea. In tal modo tutti i servizi e le applicazioni si attivano correttamente). In realtà è possibile eseguire questi script anche manualmente, al termine dell'avvio, collegandosi come root ed eseguendo un comando simile ai seguenti: /etc/rc.d/init.d/httpd stop o service httpd stop. In questo modo viene disattivato il server httpd.

NotaNota Bene
 

Se intendete avviare i servizi manualmente, collegatevi come root. Se si verifica un errore durante l'esecuzione di service httpd stop, /sbin potrebbe non trovarsi in /root/.bashrc (o nel file .rc corretto per la shell in uso). Digitate l'intero comando /sbin/service httpd stop oppure aggiungete export PATH="$PATH:/sbin" al file .rc della shell. Se modificate il file di configurazione della shell, collegatevi come utente root per attivarlo.

Nessuno degli script che avviano e terminano i servizi si trova in /etc/rc.d/init.d. Quasi tutti i file contenuti in /etc/rc.d/rc<x>.d sono link simbolici per gli script che si trovano in /etc/rc.d/init.d. Un link simbolico è un file che fa riferimento a un altro file e viene usato in questo caso perché può essere creato e cancellato senza intaccare lo script che termina o attiva il servizio. I link simbolici ai diversi script sono numerati secondo un ordine particolare, con cui poi iniziano. È possibile modificare l'ordine in cui i servizi vengono avviati e terminati, modificando il nome del link simbolico relativo allo script che avvia o termina il servizio. È possibile assegnare ai link simbolici lo stesso numero di altri link, se desiderate che quel servizio venga avviato o terminato prima o dopo di un altro.

Per esempio, per trovare il runlevel 5, init controlla nella directory /etc/rc.d/rc5.d, individuando quanto segue (il vostro sistema e la configurazione potrebbero variare leggermente):

K01pppoe -> ../init.d/pppoe
K05innd -> ../init.d/innd
K10ntpd -> ../init.d/ntpd
K15httpd -> ../init.d/httpd
K15mysqld -> ../init.d/mysqld
K15pvmd -> ../init.d/pvmd
K16rarpd -> ../init.d/rarpd
K20bootparamd -> ../init.d/bootparamd
K20nfs -> ../init.d/nfs
K20rstatd -> ../init.d/rstatd
K20rusersd -> ../init.d/rusersd
K20rwalld -> ../init.d/rwalld
K20rwhod -> ../init.d/rwhod
K25squid -> ../init.d/squid
K28amd -> ../init.d/amd
K30mcserv -> ../init.d/mcserv
K34yppasswdd -> ../init.d/yppasswdd
K35dhcpd -> ../init.d/dhcpd
K35smb -> ../init.d/smb
K35vncserver -> ../init.d/vncserver
K45arpwatch -> ../init.d/arpwatch
K45named -> ../init.d/named
K50snmpd -> ../init.d/snmpd
K54pxe -> ../init.d/pxe
K55routed -> ../init.d/routed
K60mars-nwe -> ../init.d/mars-nwe
K61ldap -> ../init.d/ldap
K65kadmin -> ../init.d/kadmin
K65kprop -> ../init.d/kprop
K65krb524 -> ../init.d/krb524
K65krb5kdc -> ../init.d/krb5kdc
K75gated -> ../init.d/gated
K80nscd -> ../init.d/nscd
K84ypserv -> ../init.d/ypserv
K90ups -> ../init.d/ups
K96irda -> ../init.d/irda
S05kudzu -> ../init.d/kudzu
S06reconfig -> ../init.d/reconfig
S08ipchains -> ../init.d/ipchains
S10network -> ../init.d/network
S12syslog -> ../init.d/syslog
S13portmap -> ../init.d/portmap
S14nfslock -> ../init.d/nfslock
S18autofs -> ../init.d/autofs
S20random -> ../init.d/random
S25netfs -> ../init.d/netfs
S26apmd -> ../init.d/apmd
S35identd -> ../init.d/identd
S40atd -> ../init.d/atd
S45pcmcia -> ../init.d/pcmcia
S55sshd -> ../init.d/sshd
S56rawdevices -> ../init.d/rawdevices
S56xinetd -> ../init.d/xinetd
S60lpd -> ../init.d/lpd
S75keytable -> ../init.d/keytable
S80isdn -> ../init.d/isdn
S80sendmail -> ../init.d/sendmail
S85gpm -> ../init.d/gpm
S90canna -> ../init.d/canna
S90crond -> ../init.d/crond
S90FreeWnn -> ../init.d/FreeWnn
S90xfs -> ../init.d/xfs
S95anacron -> ../init.d/anacron
S97rhnsd -> ../init.d/rhnsd
S99linuxconf -> ../init.d/linuxconf
S99local -> ../rc.local

Questi link simbolici indicano a init che deve terminare pppoe, innd, ntpd, httpd, mysqld, pvmd, rarpd, bootparamd, nfs, rstatd, rusersd, rwalld, rwhod, squid, amd, mcserv, yppasswdd, dhcpd, smb, vncserver, arpwatch, named, snmpd, pxe, routed, mars-nwe, ldap, kadmin, kprop, krb524, krb5kdc, gated, nscd, ypserv, ups, e irda. Dopo aver chiuso tutti i processi, init controlla nella stessa directory e trova degli script start per kudzu, reconfig, ipchains, portmap, nfslock, autofs, random, netfs, apmd, identd, atd, pcmcia, sshd, rawdevices, xinetd, lpd, keytable, isdn, sendmail, gpm, canna, crond, FreeWnn, xfs, anacron, rhnsd, e linuxconf. L'ultima azione di init è di avviare /etc/rc.d/rc.local per eseguire gli script speciali configurati per quell'host. A questo punto il sistema funziona al runlevel 5.

Dopo che init ha percorso tutti i runlevel, lo script /etc/inittab crea un processo figlio getty per ciascuna console virtuale (prompt di login) di ogni runlevel (i runlevel da 2 a 5 dispongono di sei console; il runlevel 1, in modalità a utente singolo, dispone di un'unica console; i runlevel 0 e 6 non ne ottengono nessuna). In sostanza, getty apre delle linee tty, ne imposta la modalità, visualizza il prompt di login, riceve il nome dell'utente e poi inizializza il processo di login per quell'utente. Ciò permette all'utente di autenticarsi al sistema e di cominciare a usarlo.

Inoltre /etc/inittab indica a init come interpretare la sequenza di tasti Ctrl-Alt-Canc. Dato che Red Hat Linux va chiuso e riavviato in modo corretto, init esegue il comando /sbin/shutdown -t3 -r now quando un utente usa tale combinazione di tasti. Inoltre /etc/inittab specifica a init cosa fare in caso di cali di tensione, se il vostro sistema è collegato a un'unità UPS.

/etc/inittab esegue uno script chiamato /etc/X11/prefdm nel runlevel 5. Lo script prefdm avvia il display manager di X (gdm se usate GNOME, kdm se usate KDE, oppure xdm se usate AnotherLevel) a seconda di quanto contenuto nella directory /etc/sysconfig/desktop.

A questo punto dovrebbe comparire il prompt di login. Questa operazione richiede solo alcuni secondi.

SysV Init

Come illustrato precedentemente, il programma init viene attivato dal kernel all'avvio. Il suo compito è quello di avviare tutti i processi standard che vanno avviati con il sistema. Tra questi figurano i processi getty, che consentono di collegarsi al sistema, i demoni NFS e FTP e qualunque altro servizio vogliate mettere in funzione all'avvio del calcolatore.

SysV init è il processo standard nel mondo Linux per controllare l'esecuzione del software all'avvio. Questo perché è più facile da usare ma anche più potente e flessibile dell'init BSD tradizionale.

Diversamente da BSD init, i file di configurazione di SysV init si trovano in /etc/rc.d anziché direttamente in /etc. In /etc/rc.d troverete rc, rc.local, rc.sysinit e le seguenti directory:

init.d
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d

SysV init rappresenta ogni runlevel init con una directory diversa, utilizzando il programma init e i link simbolici in ogni directory per terminare e avviare i servizi mentre il sistema si sposta da runlevel a runlevel.

In breve, la catena degli eventi per un avvio SysV è la seguente:

Il runlevel di default è definito in /etc/inittab. Dovreste vedere una riga in alto simile a:

id:3:initdefault:

In questo esempio il runlevel di default è il 3, ossia il numero dopo la prima colonna. Se desiderate modificarlo, potete digitare /etc/inittab manualmente. Prestate molta attenzione nel modificare il file inittab. Se vi sbagliate, potete rimediare all'errore riavviando il computer, accedendo al prompt boot: con Ctrl-X e digitando

boot:  linux single

Questo dovrebbe consentirvi di eseguire l'avvio in modalità a utente singolo, in modo da poter ristabilire i valori iniziali di inittab.

Discuteremo ora delle informazioni contenute nei file della directory /etc/sysconfig. Questi file definiscono i parametri utilizzati dai diversi servizi del sistema quando vengono avviati.