Disclaimer :
La versione originale di questo articolo è stata pubblicata da IBM
developerWorks ed è di proprietà di Westtech Information Services. Questo
documento è una versione aggiornata dell'articolo originale, e contiene
numerosi miglioramenti apportati dal Gentoo Linux Documentation team.
Questo documento non è mantenuto attivamente.
|
Compilare il kernel Linux
1.
Introduzione al kernel
Il kernel è... Linux!
Che cosa viene in mente sentendo la parola "Linux"? In generale, un'intera
distribuzione Linux completa di tutti quei programmi che la fanno
funzionare.
Tecnicamente Linux è un kernel, e solo quello. Tutte le altre componenti di
ciò che comunemente viene definito "Linux" (come la shell o il compilatore)
costituiscono parti essenziali di una distribuzione; ciononostante sono di
fatto tecnicamente separate da Linux (il kernel). Sebbene da molti la parola
"Linux" venga frequentemente utilizzata come sinonimo di "Distribuzione
basata su Linux", si conviene che il kernel Linux è il cuore di ogni
distribuzione.
Interfacciamento con l'hardware
Il ruolo primario del kernel Linux consiste nell'interfacciarsi direttamente
con l'hardware del sistema. Il kernel fornisce uno strato di
astrazione tra il nudo hardware e i programmi applicativi. Questi non
sono quindi costretti a conoscere le specifiche dei chipset delle varie
schede madri o dei controller dischi per operare ad un livello di astrazione
più alto, come ad esempio le operazioni di scrittura e lettura file.
Astrazione della CPU
Il kernel Linux fornisce inoltre un livello di astrazione per i processori
del sistema, siano essi uno solo o più di uno. Ciò consente di eseguire
programmi in maniera apparentemente simultanea. Linux rende questo possibile
permettendo a svariati processi UNIX di avviarsi nello stesso momento;
il kernel si occupa di spartire equamente le risorse del processore/i.
Un kernel Linux può supportare una o più CPU. Infatti, il kernel che il
lettore sta utilizzando in questo momento può essere UP (UniProcessor) oppure
SMP (Symmetric MultiProcessor). Nel caso si utilizzi una scheda madre SMP
con un kernel UP, Linux non sarà consapevole della presenza di più CPU. Per
rimediare a questo occorre compilare un kernel SMP. Allo stato attuale, un
kernel SMP gira anche su macchine monoprocessore, sebbene con un leggero
impatto sulle prestazioni.
Astrazione dell'I/O
Il kernel si occupa inoltre del fondamentale compito di astrarre tutte le
forme di I/O su file. Se ogni programma dovesse interfacciarsi direttamente
con l'hardware di I/O la semplice sostituzione del controller dischi
impedirebbe loro di continuare a funzionare Il kernel Linux segue invece il
modello UNIX: fornisce una semplice astrazione dell'I/0 disco che qualunque
programma può utilizzare. Questo approccio consente, ad esempio,
all'applicazione di database di non occuparsi della memorizzazione dei dati,
che possono così essere salvati indifferentemente su un disco IDE, un RAID
SCSI o un file system di rete.
Networking
Una delle caratteristiche di spicco del kernel Linux è la parte dedicata al
networking, specialmente il supporto al TCP/IP. Tale supporto si trova
appunto nel Kernel Linux. Il kernel fornisce un'interfaccia ad altro livello
ai programmi che devono inviare dati in rete. Dietro le quinte il kernel
Linux si interfaccia direttamente con la scheda di rete presente sul sistema
e si occupa della comunicazione internet a basso livello.
Peculiarità del supporto di rete
Una delle caratteristiche piu utili di Linux è la quantità di funzionalità
disponibili nel kernel, specialmente quelle relative al networking. Ad
esempio è possibile configurare un kernel in modo che permetta all'intera
rete di casa propria di accedere ad Internet attraverso un modem installato
sulla macchina Linux. Questa caratteristica viene denominata IP Masquerading
o IP NAT (network address translating o traslazione dell'indirizzo di rete)
Oltre questo è possibile configurare un kernel per esportare o montare file
system di rete, come NFS, consentendo cosi alle altre macchine UNIX presenti
nella rete di condividerne i dati.
Il boot, parte I
Quando si accende un sistema basato su Linux il boot loader (ad es. LILO) si
occupa di caricare il kernel dal disco in memoria. Una volta caricato in
memoria, il kernel prende il controllo del sistema. Per prima cosa rileva ed
inizializza l'hardware presente, posto che sia stato compilato con il
necessario supporto. Una volta inizializzato correttamente l'hardware, il
kernel è pronto per l'esecuzione dei processi. Il primo ad essere eseguito è
init, che risiede in /sbin. A questo punto init
avvia altri processi, come specificato in /etc/inittab.
Il boot, parte II
init tipicamente esegue diverse copie di un programma chiamato
getty, il cui compito è di attendere i login da console. Dopo che
getty ha elaborato con successo la richiesta di login, viene caricata
la shell (solitamente bash) predefinita per l'utente che ha eseguito
appunto il login. A questo punto si ha davanti il prompt di bash, che
permette all'utente di eseguire i programmi che desidera.
Durante i passaggi sopra descritti, il kernel suddivide su base temporale la
capacità di calcolo della CPU, in modo da assegnarla equamente ad ogni
processo. Inoltre, fornisce servizi di networking e astrazione dell'hardware
ai vari processi in esecuzione.
Introduzione ai moduli del kernel
Qualunque kernel Linux recente supporta i moduli del kernel, cioè parte
integrante del kernel che però risiede sul disco rigido. Quando il kernel
abbisogna delle funzionalità di un particolare modulo esso viene caricato dal
disco, automaticamente integrato nel kernel e reso disponibile all'utilizzo.
Se inoltre un modulo resta inutilizzato per alcuni minuti il kernel può di
sua iniziativa scaricarlo dalla memoria; questa prerogativa prende il nome di
autocleaning.
Moduli, parte II
I moduli del kernel risiedono in /lib/modules; ogni modulo ha
come suffisso .o oppure .ko. Come si può immaginare
ogni modulo rappresenta un particolare componente delle funzionalità
complessive del kernel: ad esempio, il supporto per il filesystem FAT, oppure
quello per una particolare scheda ethernet ISA.
I moduli permettono di ridurre la memoria utilizzata dal kernel. Si può
compilare un kernel che contenga solo quanto necessario all'avvio del
sistema; tutte le altre funzionalità possono essere caricate su richiesta
grazie ai moduli. Considerando che il kernel tende ad effettuare
l'autocleaning dei moduli caricati, la memoria del proprio sistema può essere
utilizzata al meglio.
Moduli -- -- importanti considerazioni
Non è possibile delegare tutte le funzioni del kernel ai moduli. I
moduli, risiedendo sul disco rigido, richiedono ad esempio che l'immagine
avviabile del kernel abbia compilato al suo interno il supporto per il
controller del disco così come quello per il file system utilizzato
(tipicamente l'ext2). Nel caso non si abbia compilato i suddetti componenti
nell'immagine del kernel ma, ad esempio, li si abbia compilati come moduli,
il kernel non sarà in grado di caricarli dal disco. Si verifica infatti
l'idiosincrasia tipica del problema dell'uovo e della gallina.
2.
Localizzare e scaricare i sorgenti
Versioni del Kernel
Per compilare un kernel recente, occorre prima scaricare i sorgenti. Ma quali
sorgenti scaricare, quelli per un un kernel stabile o oppure quelli per uno
sperimentale ?
Le versioni stabili del kernel sono caratterizzate dall'avere un numero
positivo come secondo numero di versione; ad es. 2.0.38, 2.2.15, 2.2.18,
2.4.1 vengono tutti considerati kernel stabili (rispettivamente 0, 2, 2, e
4). Nel caso si voglia testare un kernel sperimentale occorre, come regola
generale, cercarne la versione più alta che abbia però un numero negativo
come secondo numero di versione. 2.3.99 e 2.1.38 sono entrambi kernel
sperimentali (riportando 3 e 1, rispettivamente, come secondo numero di
versione).
Cronologia del kernel
I kernel della serie 2.2 vengono considerati moderni e stabili. Se "moderno"
e "stabile" rappresentano le caratteristiche volute, si utilizzerà un kernel
2.2 con il più alto terzo numero di versione che si riesce a trovare.
Nel corso dello sviluppo della serie 2.2 ed, ha avuto inizio quello della
serie 2.3. Questa serie è stata pensata per essere utilizzata come terreno
di prova per tutte le nuove funzionalità avanzate che avrebbero eventualmente
trovato collocazione nella serie stabile 2.4. Al giorno d'oggi la serie 2.3
ha già raggiunto la versione 2.3.99, e qui si è fermato lo sviluppo. Gli
sviluppatori stanno lavorando per mettere insieme il kernel 2.4.0. Il kernel
2.4.0-test è quello da scegliere per chi voglia provare il kernel in assoluto
più recente.
Avvertenze circa il kernel 2.4
Non appena viene rilasciato un kernel reale della serie 2.4, non
significa che sia maturo per esser utilizzato su un sistema mission-critical
come ad es. un server. Sebbene si suppone che la serie 2.4 sia stabile, vi
sono buone possibilità che le prime versioni rilasciate non siano all'altezza
delle aspettative. Come spesso succede nel mondo dell'informatica, la prima
versione è in generale soggetta a errori grossolani. Ciò non costituisce un
problema per chi sperimenta il kernel sul proprio sistema di casa, mentre
rappresenta un rischio da evitare se il sistema in questione fornisce servizi
a più utenti, come succede nel caso di un server.
Scaricare il kernel
Se si desidera semplicemente compilare una nuova versione del kernel
installato, ad esempio per abilitare il supporto SMP, non occorre scaricare
alcunché ed è possibile saltare la lettura di questa e della prossima
sezione.
http://www.kernel.org/pub/linux/kernel è il sito ove cercare i
nuovi kernel. Vi si trovano i sorgenti del kernel organizzati in svariate
directory basate sulla versione del kernel (v2.2, v2.3, ecc.). All'interno di
ogni directory risiedono file del tipo "linux-x.y.z.tar.gz" e
"linux-x.y.z.tar.bz2". Questi sono i sorgenti del kernel Linux.
Oltre a questi, si possono trovare file del tipo
"patch-x.y.z.gz" e "patch-x.y.z.bz2". Questi file
sono patch che possono essere utilizzate per aggiornare versioni precedenti.
Volendo compilare una nuova release del kernel, occorre scaricare uno dei
file che iniziano con "linux".
Scompattare il kernel
Scaricato il kernel da kernel.org, occorre scompattarlo così: cd in
/usr/src. Se dovesse già esser presente una directory chiamata
linux, rinominarla in linux.old (mv linux
linux.old, dall'account root.)
Sempre da /usr/src, digitare:
Codice 2.1: Scompattare con gzip |
# tar -xzvf /percorso/al/mio/kernel-x.y.z.tar.gz
|
oppure
Codice 2.2: Scompattare con bzip2 |
# tar -xvjf /percorso/al/mio/kernel-x.y.z.tar.bz2
|
a seconda che i sorgenti scaricati siano compressi con gzip o
bzip2. Dopo l'esecuzione del comando digitato, i nuovi sorgenti del
kernel appariranno in una nuova directorylinux. Ma attenzione:
una volta scompattati generalmente occupano sul disco più di 50 megabyte!
3.
Configurazione del kernel
Cos'è la configurazione
Prima di compilare un kernel, occorre configurarlo. La configurazione
consente di decidere con precisione quali funzionalità saranno o meno
abilitate nel nuovo kernel. Sarà inoltre possibile controllare cosa viene
compilato nell'immagine binaria del kernel caricata in fase di boot e cosa
invece nei file corrispondenti ai moduli del kernel che verranno caricati su
richiesta.
In passato, la configurazione del kernel era piuttosto macchinosa e iniziava
con lo spostarsi in /usr/src/linux e digitare make
config. make config funziona ancora, ma non la si utilizzi a meno
di non voler configurare il kernel rispondendo a centinaia di domande poste
attraverso la linea di comando.
I nuovi configuratori del kernel
Al giorno d'oggi invece di make config, si possono utilizzare make
menuconfig oppure make xconfig. make menuconfig consente
di configurare il kernel attraverso un gradevole sistema di menù testuali.
make xconfig invece permette di configurare le varie opzioni del
kernel attraverso un'interfaccia grafica di X. Di seguito una
screenshot?????mik di make menuconfig:
Figura 3.1: menuconfig in azione |
 |
In make menuconfig, le opzioni che possono essere compilate come
modulo hanno alla loro sinistra un < >. Quando l'opzione è
evidenziata, premendo la barra spazio si può scegliere se deselezionare
l'opzione(< >), selezionarla per la compilazione nell'immagine
del kernel (<*>) oppure come modulo (<M>).
Suggerimenti per la configurazione
Esistono una miriade di opzioni del kernel e una loro spiegazione non trova
posto nel presente documento; a questo scopo si può utilizzare il sistema di
help (?????mik)aiuto incluso nel kernel. Quasi tutte le opzioni sono
descritte in un certo dettaglio, ed ognuna di esse comprende la riga "If you
don't know what this means, type Y (or N).", che tradotta suona come "Se non
hai idea di cosa significa, digita Y (or N)". Questi suggerimenti
costituiscono un importante aiuto quando non si è incerti sull'utilizzo di
una data opzione. Per accedere al sistema di help (????mik proporre help al
posto di aiuto, sistema di help al posto di sistema di aiuti (o aiuto))),
selezionare l'opzione sulla quale si desiderano maggiori informazioni e
premere il tasto "?".
4.
Compilare ed installare il kernel
make dep; make clean
Una volta configurato il kernel il passo successivo è la compilazione,prima
della quale occorre generare le informazioni sulle dipendenze e eliminare i
residui di eventuali precedenti compilazioni, spostandosi in
/usr/src/linux e digitando: make dep; make clean
Make bzImage
Ora occorre compilare il vero e proprio binario del kernel, digitando make
bzImage. La compilazione richiede svariati minuti producendo (per un
kernel x86) il file bzImage in /usr/src/linux/arch/i386/boot. Ma
prima di illustrare l'installazione del kernel occorre dare uno sguardo ai
moduli.
Compilare i moduli
Ottenuto il file bzImage, occorre compilare i moduli. Si raccomanda di non
omettere questo passo anche se non si ha abilitato alcun modulo in sede di
configurazione del kernel. Quella di lanciare la compilazione dei moduli
subito dopo quella di bzImage è senza dubbio una buona abitudine, e se non si
sono abilitati moduli si completerà velocemente. Digitare make modules;
make modules_install. Questi comandi producono la compilazione e
l'installazione dei moduli in /usr/lib/<kernelversion>.
Congratulazioni! Il kernel è compilato e i moduli compilati ed installati. È
il momento di riconfigurare LILO per l'avvio con il nuovo kernel.
5.
Configurazione del boot (?????mik lasciare boot invece di avvio)
Introduzione a LILO
LILO deve ora essere configurato per caricare il nuovo kernel. LILO è il più
popolare boot loader (?????mik) per Linux, ed è utilizzato dalle principali
distribuzioni. La prima cosa da fare è esaminare il file
/etc/lilo.conf. Deve contenere una riga del tipo
image=/vmlinuz Questa linea indica a LILO dove si trova il kernel.
Configurazione del boot, parte 2
L'avvio del nuovo kernel può essere configurato in due modi. Il primo è di
sovrascrivere il kernel esistente, opzione rischiosa a meno di non aver
pronto un metodo di boot d'emergenza, ad esempio un disco di boot contenete
quel particolare kernel.
L'opzione più sicura è quella di configurare LILO in modo che possa caricare
il vecchio oppure il nuovo kernel. Si può configurare LILO in modo da
caricare per impostazione predefinita ?????default il nuovo kernel, fornendo
comunque un modo per selezionare il vecchio kernel nel caso si difficoltà.
Questa è l'opzione raccomandata e trattata di seguito.
Configurazione del Boot, parte 3
Ecco un tipico lilo.conf
Codice 5.1: /etc/lilo.conf |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz
label=linux
|
Come aggiungere una nuova sezione a lilo.conf Prima di tutto,
copiare /usr/src/linux/arch/i386/boot/bzImage in un file nella
partizione root (?????partizione radice), ad es. chiamandolo
vmlinuz2. Duplicare poi le ultime tre righe di
lilo.conf aggiungendole alla fine del file stesso.
Configurazione del Boot, parte 4
Ora il proprio lilo.conf dovrebbe esser simile a quanto segue:
Codice 5.2: the new lilo.conf |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz
label=linux
image=/vmlinuz
label=linux
|
Occorre cambiare la riga image= in modo che contenga
image=/vmlinuz2. Quindi, modificare la seconda riga
label= in modo che riporti label=oldlinux. Occorre inoltre
accertarsi che vi sia una riga con delay=20 verso l'inizio del file;
in caso contrario aggiungerla, facendo attenzione che il numero sia almeno
20.
Configurazione del boot, parte 5
Il file lilo.conf dovrebbe ora rassomigliare a quanto segue:
Codice 5.3: Il lilo.conf finale |
boot=/dev/hda
delay=20
vga=normal
root=/dev/hda1
read-only
image=/vmlinuz2
label=linux
image=/vmlinuz
label=oldlinux
|
A questo punto occorre eseguire lilo come root. Questo è un passaggio
fondamentale! Omettendo questo passaggio, il processo di avvio non
funzionerà. L'esecuzione di lilo comporta l'aggiornamento della mappa
di boot da parte dello stesso lilo.
Spiegazione della configurazione del boot
Il file lilo.conf sopra riportato permette il boot di due
kernel differenti: il kernel originale, nella fattispecie
/vmlinuz, e il nuovo kernel, situato in /vmlinuz2.
Come impostazione predefinita, il sistema proverà a caricare il nuovo kernel,
le cui righe image/label precedono le altre nel file di configurazione.
Se per qualche ragione occorre caricare il vecchio kernel, è sufficiente
riavviare il sistema e tenere premuto il tasto Shift. LILO, accorgendosene,
permetterà di digitare l'etichetta corrispondente all'immagine binaria che si
desidera avviare. Per avviare quindi il vecchio kernel, si digiti
oldlinux seguito da Invio. Per visualizzare la lista delle immagini
disponibili, si prema TAB.
6.
Risorse
Congratulazioni! La compilazione del kernel è terminata. Di seguito alcune
risorse per approfondire ulteriormente l'argomento:
-
www.kernel.org, il sito che ospita
gli archivi del Kernel Linux.
-
Kernel Newbies è un'eccellente risorsa per imparare come compilare il
kernel, ed imparare come funzionano i suoi diversi componenti. Il sito
fornisce inoltre un dettagliato ma pur sempre facilmente comprensibile
panoramica sui cambiamenti tra ogni
rilascio del kernel.
|