Compilazione del kernel

Il kernel, come ogni programma per elaboratore elettronico, è scritto in un linguaggio, detto anche codice sorgente, che deve essere tradotto da un altro programma, detto compilatore, in un linguaggio comprensibile al computer, che dopo può eseguire le istruzioni in esso contenute. La sequenza di istruzioni che viene fuori dal processo di compilazione viene denominata, non a caso, codice binario, perché è fatta di zeri e uno, la sola lingua che il computer è in grado di capire. Per semplicità, normalmente i programmi sono forniti già compilati e pronti per essere utilizzati, ma il kernel, cuore pulsante del nostro mostro da scrivania, merita un trattamento speciale.

Compilare il codice sorgente del kernel anzichè installare uno dei pacchetti pre-compilati assicura certamente alcuni vantaggi, tra cui:

ma soprattutto, considerate che non potrete mai definirvi un vero linuxiano se non avete mai compilato un kernel! Nel caso decidiate di non usare i kernel pre-compilati messi a disposizione da Debian e vogliate compilare il vostro kernel personalizzato, per tenere il passo con gli aggiornamenti di sicurezza (paragrafo 8.2) avete due possibilità:
  1. usare i kernel di Debian nel formato sorgente e ricompilarli ogni volta che essi incorporano dei rimedi contro bachi conosciuti (la versione del kernel non cambia);
  2. usare i kernel standard di Linus ricompilando nuove versioni ogni volta che esse incorporano dei rimedi contro bachi (pararagrafo 8.3) conosciuti (la versione del kernel cambia).

Debian mette a disposizione dei comandi che rendono più semplice la procedura di compilazione del kernel; tale procedura verrà illustrata (quasi) passo-passo. Assicuratevi di aver installato i pacchetti48 elencati in tabella 7.1.


Table 7.1: Pacchetti per compilazione kernel
kernel-package make libncurses5-dev
binutils gcc dpkg-dev
debianutils patch libc6-dev


Se siete su piattaforma x86 (in pratica tutti i comuni computer con processore Intel/AMD) dovrete avere installato anche il pacchetto bin86.

Primo passo: ottenere il sorgente del kernel

Diversamente da come alcuni credono, come accennato sopra non ci sono controindicazioni nell'usare in Debian un kernel vanilla, curato da Linus Torvalds in persona, prelevato da kernel.org: l'unica differenza con i kernel Debian è che essi sono per comodità disponibili anche già compilati e contenenti delle specifiche patch. L'ultima versione stabile del kernel (denominata ``vanilla'') è sempre disponibile su internet; provate per esempio da:

ftp.it.kernel.org
Il sorgente è tipicamente contenuto in un file compresso: supponiamo di prelevare il file linux-2.6.10.tar.bz2

Secondo passo: scompattare il file sorgente

Posizionarsi in /usr/src dopo avervi posto il file linux-2.6.10.tar.bz2

# cd /usr/src
e digitare

# tar -xjf linux-2.6.10.tar.bz2
che creerà in /usr/src/linux-2.6.10 un albero di file sorgenti (source-tree); a questo punto creare il collegamento simbolico

# ln -s /usr/src/linux-2.6.10 linux
in modo da operare con comodità su /usr/src/linux invece che su /usr/src/linux-2.6.10.

Terzo passo: accertarsi della compatibilità del sistema

Prima di iniziare la compilazione occorre verificare che le versioni del software di sistema siano compatibili con il nuovo kernel. A tale scopo, basta selezionare in un qualunque file manager la cartella ``Documentation'' in /usr/src/linux; lì apriamo il file ``Changes'' e in esso cerchiamo la sezione ``Current Minimal Requirements'': qui controlliamo che le versioni del nostro software di sistema siano accettabili (inutile controllare i programmi di servizio di filesystem che non usiamo, come per esempio di ReiserFS se noi usiamo ext3).

Quarto passo: applichiamo le eventuali patch

Questo passo è facoltativo perchè non è strettamente necessario applicare delle patch49 e viene aggiunto solo per completezza. Se però applicate delle patch, assicuratevi di farlo nel giusto ordine. Qui si supporrà di avere un'unica super-patch da applicare, contenuta nel file linux-2.6.10-ck7.patch (già eventualmente scompattato); posizionare il file della patch in /usr/src/linux e digitare:

# cd /usr/src/linux

# patch -p1 < linux-2.6.10-ck7.patch

E' superfluo osservare che le patch devono riferirsi esattamente alla versione del kernel da compilare.

Quinto passo: configurare il kernel

Lanciamo il menu di configurazione:

# cd /usr/src/linux

# make menuconfig

ove compariranno anche le voci introdotte dalle patch, se le avete applicate. La configurazione del kernel è il passo più delicato: una scelta errata ne può pregiudicare gravemente il funzionamento. E' in questa sede che dovete decidere se volete un kernel monolitico o modulare50. Fare comunque attenzione al fatto che alcuni pezzi del kernel sono compilabili solo come moduli51.

Esiste numerosa documentazione, inclusa quella in linea del menù di configurazione del kernel, che è prodiga di consigli sulle impostazioni da dare; inoltre il kernel stesso già contiene molte impostazioni predefinite di base (nel menù di configurazione le trovate già selezionate). Nel seguito si daranno comunque un minimo di indicazioni sulle impostazioni da dare (tenete anche presente che il modo in cui è strutturato il menù di configurazione cambia abbastanza spesso), ma il consiglio principe è quello di studiare l'hardware della vostra macchina e valutare attentamente le spiegazioni dell'aiuto in linea delle varie voci del menù di configurazione del kernel. Nel seguito per risposta ``yes'' si intende la selezione (come modulo o direttamente compilato nel kernel) della corrispondente voce del menu di configurazione, mentre per risposta ``no'' si intende la medesima voce lasciata o resa non selezionata.

  1. Nella sezione ``Enable loadable module support'' la risposta ``yes'' definisce un kernel modulare, mentre la risposta ``no'' un kernel monolitico.
  2. Se, come probabile, avete una macchina moderna, dovete sicuramente attivare il supporto PCI nella sezione ``Bus options'':

    PCI Support -> yes

    PCI device name database -> yes
  3. Nella sezione ``Networking Options'' assicurarsi che siano attive:

    Networking Packet Filtering -> yes

    TCP/IP networking -> yes
  4. Cercate ed attivate tutte le opzioni riguardanti ATA/IDE per far funzionare il disco fisso.
  5. Nella sezione ``File Systems'' cercate ed attivate il supporto al tipo di filesystem che avete sul disco fisso, tipicamente ext3.
  6. Nella sezione ``General Set Up'' assicurarsi che siano attive alcune opzioni un po' oscure ma importanti come ``System V IPC'' per consentire la comunicazione tra processi, ``Sysctl support'' per consentire l'accesso ad alcune parti del sistema da parte dei programmi che lo usano.
Prendetevi il vostro tempo: la configurazione viene salvata nel file nascosto /usr/src/linux/.config e può essere richiamata un numero infinito di volte.

Fate dei tentativi: questa procedura che si illustra permette, se qualcosa non funziona, di riavviare la macchina col vecchio kernel di sempre; considerate inoltre che la mostruosa potenza dei computer moderni permette di compilare il kernel in una manciata di minuti.

Sesto passo: compilare il sorgente

Una volta soddisfatti di come è configurato il kernel si può passare alla compilazione; è adesso che si usano gli strumenti Debian; digitare:

# cd /usr/src/linux

# make-kpkg -revision=prova.1.0 kernel_image

Questo comando produrrà un pacchetto Debian nuovo fiammante contenente il codice binario del nostro kernel personalizzato:

kernel-image-2.6.10_prova.1.0_i386.deb

con ``i386'' se siamo su piattaforma x86. L'opzione revision è importante per impedire che il gestore dei pacchetti vada a sostituire il nostro kernel personalizzato in occasione di un dist-upgrade (pararagrafo sec:Aggiornare-la-distribuzione) del sistema. A questo punto non abbiamo fatto ancora nulla perché il nuovo kernel è stato compilato ma non ancora installato!

Settimo passo: installare il nuovo kernel

Per installare il kernel inserire:

# cd /usr/src

# dpkg -i kernel-image-2.6.10_prova.1.0_i386.deb

Da notare che dpkg con l'opzione di installazione richiede di specificare il nome completo del pacchetto, come nell'esempio di cui sopra. Non resta ora che riavviare il sistema per far caricare automaticamente il nuovo kernel. Per essere sicuri che è in funzione il nuovo kernel inserire:

$ uname -a
Se per qualsiasi motivo si vuole caricare il vecchio kernel basta riavviare il sistema tenendo poi premuto il tasto shift: comparirà un menù da cui potrete selezionare con i tasti cursore l'etichetta ``LinuxOld'', che corrisponde al vecchio kernel. Questa procedura può variare un poco se per avviare il kernel usate GRUB, installato in modo predefinito da Debian, invece di usare LILO preferito dall'autore.

La procedura di compilazione descritta, conducendo alla generazione di un pacchetto Debian del kernel personalizzato, contiene il vantaggio della facile portabilità del kernel compilato, che si traduce in:

La prima possibilità è stata sfruttata con successo dall'autore nel caso di un portatile che non ne voleva sapere di avviare il kernel dell'installazione Debian: il problema è stato risolto compilando un kernel personalizzato (specificando l'hardware ed il processore del portatile) su un altro computer, passando poi al portatile il corrispondente pacchetto Debian, che una volta installato si è avviato regolarmente.



Subsections
Mauro Darida 2006-07-25