Product SiteDocumentation Site

8.10. Compilare un kernel

I kernel forniti da Debian includono il maggior numero possibile di funzionalità, così come il massimo numero di driver, per coprire lo spettro più ampio di configurazioni hardware esistenti. Ecco perché alcuni utenti preferiscono ricompilare il kernel per includere unicamente ciò di cui necessitano. Ci sono due ragioni per questa scelta. Primo, questo può ottimizzare il consumo di memoria perché il codice del kernel anche se non viene mai utilizzato occupa memoria senza motivo (e non viene mai posto nello spazio di swap, dato che utilizza la vera RAM), cosa che può diminuire le prestazioni complessive del sistema. Inoltre un kernel compilato localmente può anche limitare i rischi di sicurezza poiché solo una frazione del codice del kernel è compilato ed eseguito.
Ricompilare il kernel è inoltre necessario se si vuole utilizzare certe funzionalità che sono disponibili solo come patch (e non sono incluse nella versione standard del kernel).

8.10.1. Introduzione e prerequisiti

Non stupisce che Debian gestisca il kernel sotto forma di pacchetti, diversamente da come i kernel sono stati compilati ed installati tradizionalmente. Poiché il kernel rimane sotto il controllo del sistema di pacchettizazione può essere rimosso in modo pulito, o distribuito su diverse macchine. Inoltre, gli script associati con questi pacchetti automatizzano l'interazione con il bootloader ed il generatore initrd.
I sorgenti originari di Linux contengono tutto il necessario per costruire un pacchetto Debian del kernel. Ma è ancora necessario installare build-essential per assicurarsi di avere gli strumenti necessari per costruire un pacchetto Debian. Inoltre, le fasi di configurazione del kernel richiedono il pacchetto libncurses5-dev. Infine, il pacchetto fakeroot consente la creazione del pacchetto Debian senza l'impiego di privilegi di amministratore.

8.10.2. Ottenere i sorgenti

Come qualiasi cosa che può essere utile in un sistema Debian, i sorgenti del kernel Linux sono disponibili in un pacchetto. Per ottenerli, basta installare il pacchetto linux-source-versione. Il comando apt-cache search ^linux-source elenca le varie versioni del kernel pacchettizate da Debian. L'ultima versione è disponibile nella distribuzione Unstable: è possibile ottenerla senza troppi rischi (specialmente se il proprio APT è configurato secondo le istruzioni nella Sezione 6.2.6, «Lavorare con più distribuzioni»). Va notato che il codice sorgente contenuto in questi pacchetti non corrisponde precisamente con quello pubblicato da Linus Torvalds e dagli sviluppatori del kernel: come tutte le distribuzioni, Debian applica una serie di patch, le quali potrebbero (o non) trovare la loro strada nella versione originaria di Linux. Queste modifiche includono backport di /correzioni/caratteristiche/driver dalle versioni più recenti del kernel, le nuove funzionalità non ancora (interamente) incluse nella struttura originaria di Linux, e talvolta anche cambiamenti specifici di Debian.
Il resto di questa sezione si concentra sulla versione 3.16 del kernel Linux, ma gli esempi possono, natualmente, essere adattati alla particolare versione del kernel che si desidera.
Supponiamo che il pacchetto linux-source-3.16 sia installato. Contiene /usr/src/linux-source-3.16.tar.xz, un archivio compresso dei sorgenti del kernel. Si devono estrarre questi file in una nuova directory (non direttamente in /usr/src/, poiché non c'è bisogno di permessi speciali per compilare un kernel Linux): ~/kernel/ è appropriato.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xjf /usr/src/linux-source-2.6.32.tar.bz2

8.10.3. Configurare il kernel

I passi successivi consistono nella configurazione del kernel secondo le proprie necessità. La procedura esatta dipende dagli obiettivi.
Quando si ricompila una versione del kernel più recente (eventualmente con patch aggiuntive) la configurazione sarà probabilmente mantenuta più simile possibile a quella proposta da Debian. In questo caso, e piuttosto di riconfigurare tutto da zero, è sufficiente copiare il file /boot/config-versione (la versione è quella del kernel correntemente in uso, che può essere trovato con il comando uname -r) in un file .config nella directory contenente i sorgenti del kernel.
$ cp /boot/config-3.16.0-4-amd64 ~/kernel/linux-source-3.16/.config
Se non si necessita di cambiare la configurazione, è possibile fermarsi qui e saltare alla Sezione 8.10.4, «Compilazione e creazione del pacchetto». Se invece è necessario modificarla, o se si è deciso di riconfigurare tutto da zero, è necessario prendersi del tempo per configurare il kernel. Ci sono varie interfacce dedicate nella directory dei sorgenti del kernel che possono essere richiamate utilizzando il comando make target, dove target sarà uno dei valori descritti di seguito.
make menuconfig compila ed esegue un'interfaccia testuale (ecco perché è richiesto il pacchetto libncurses5-dev) che consente la navigazione tra le opzioni disponibili in una struttura gerarchica. La premendo il tasto Spazio cambia il valore delle opzioni selezionate, ed Invio conferma il bottone selezionato in basso sullo schermo; Select rimanda al sotto-menu selezionato; Exit chiude la finestra corrente e torna indietro alla gerarchia, Help visualizzerà informazioni maggiormente dettagliate sul ruolo dell'opzione selezionata. Le frecce consentono di muoversi tra la lista di opzioni ed i bottoni. Per uscire dal programma di configurazione, scegliere Exit dal menu principale. Il programma offrirà di salvare le modifiche effettuate; accettare se si è soddisfatti delle proprie scelte.
Altre interfacce hanno funzioni simili, ma lavorano con interfacce grafiche più moderne: come make xconfig che usa l'interfaccia grafica Qt, e make gconfig che usa GTK+. La prima richiede libqt4-dev, mentre quest'ultima dipende da libglade2-dev e libgtk2.0-dev.
Quando si utilizza una di queste interfacce di configurazione, è sempre una buona idea partire da una configurazione predefinita ragionevole. Il kernel fornisce tali configurazioni in arch/arch/configs/*_defconfig e si può attivare la configurazione selezionata con un comando come make x86_64_defconfig (in caso di un PC a 64-bit) opuure make i386_defconfig (in caso di un PC a 32-bit).

8.10.4. Compilazione e creazione del pacchetto

Una volta che la configurazione del kernel è pronta, un semplice make deb-pkg genererà fino a 5 pacchetti Debian: linux-image-versione che contiene l'immagine del kernel e dei moduli associati, linux-headers-versione che contiene i file header necessari per compilare moduli esterni, linux-firmware-image-versione che contiene i file del firmware necessari per alcuni driver ( questo pacchetto potrebbe mancare quando si genera dai sorgenti del kernel forniti da Debian), linux-image-versione-dbg che contiene i simboli di debug per l'immagine del kernel e dei suoi moduli, e linux-libc-dev che contiene gli header realtivi ad alcune librerie come GNU glibc.
La versione è definita dalla concatenazione della versione originaria (come definita dalle variabili VERSION, PATCHLEVEL, SUBLEVEL e EXTRAVERSION in Makefile), del parametro di configurazione LOCALVERSION, e della variabile d'ambiente LOCALVERSION. La versione del pacchetto riutilizza la stessa stringa della versione con aggiunto un numero di revisione che viene viene incrementato regolarmente (e memorizzata in .version), almeno che non si sovrascrive con la variabile d'ambiente KDEB_PKGVERSION.
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot-dbg_3.16.7-1_amd64.deb
../linux-libc-dev_3.16.7-1_amd64.deb

8.10.5. Compilare moduli esterni

Alcuni moduli sono mantenuti fuori dal kernel ufficiale Linux. Per usarli, è necessario compilarli parallelamente al kernel corrispondente. Alcuni moduli comuni di terze parti sono forniti da Debian in pacchetti dedicati, come xtables-addons-source (moduli aggiuntivi per iptables) o oss4-source (Open Sound System, alcuni driver audio alternativi).
Questi pacchetti esterni sono molti e variegati e non possiamo elencarli tutti qui: il comando apt-cache search source$ può restringere il campo alla chiave di ricerca. Comunque una lista completa non sarebbe particolarmente utile visto che non c'è una ragione particolare per compilare moduli esterni se non quando si sa di averne bisogno. In questi casi la documentazione del dispositivo dettaglia tipicamente i moduli specifici di cui necessita per funzionare su Linux.
Per esempio, diamo un'occhiata al pacchetto xtables-addons-source: dopo l'installazione, in /usr/src/ viene memorizato un file .tar.bz2 dei sorgenti del modulo. Anche se si potrebbe estrarre manualmente l'archivio tarball e creare il modulo, in pratica si preferisce automatizzare il tutto utilizzando DKMS. La maggior parte dei moduli offrono l'integrazione DKMS nei pacchetti che terminano con il suffisso -dkms. Nel nostro caso, l'installazione di xtables-addons-dkms è tutto ciò che serve per compilare il modulo del kernel per il kernel corrente a condizione che abbiamo il pacchetto linux-headers-* corrispondente al kernel installato. Per esempio, se si utilizza linux-image-amd64, si dovrebbe installare anche linux-headers-amd64.
$ sudo apt install xtables-addons-dkms

[...]
Setting up xtables-addons-dkms (2.6-1) ...
Loading new xtables-addons-2.6 DKMS files...
First Installation: checking all kernels...
Building only for 3.16.0-4-amd64
Building initial module for 3.16.0-4-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.16.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.6, 3.16.0-4-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/3.16.0-4-amd64/updates/dkms/xt_ACCOUNT.ko
license:        GPL
alias:          ipt_ACCOUNT
author:         Intra2net AG <opensource@intra2net.com>
description:    Xtables: per-IP accounting for large prefixes
[...]

8.10.6. Applicare una patch al kernel

Alcune funzionalità non sono incluse nel kernel standard perché non mature o per un mancato accordo tra il manutentore del codice sorgente ed i manutentori del kernel. Alcune funzionalità possono essere distribuite come patch che chiunque può applicare liberamente ai sorgenti del kernel.
Debian distribuisce alcune di queste patch nei pacchetti linux-patch-* o kernel-patch-* (per esempio linux-patch-grsecurity2 intensifica alcune delle politiche di sicurezza del kernel). Questi pacchetti installano file nella directory /usr/src/kernel-patches/.
Per applicare una o più di queste patch installate utilizzare il comando patch nella directory dei sorgenti, poi avviare la compilazione del kernel come descritto sopra.
$ cd ~/kernel/linux-source-3.16
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.0-3.17.1-201410250027.patch.gz | patch -p1
Notare che una patch potrebbe non funzionare con ogni versione del kernel: è possibile che patch fallisca quando la applica ai sorgenti del kernel. Un messaggio d'errore sarà visualizzato e fornirà alcuni dettagli a proposito del fallimento. In questo caso, si deve far riferimento alla documentazione disponibile nel pacchetto Debian della patch (nella directory /usr/share/doc/linux-patch-*/). In molti casi il manutentore indica per quali versioni del kernel è stata realizzata la patch.