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

Unsurprisingly Debian manages the kernel in the form of a package, which is not how kernels have traditionally been compiled and installed. Since the kernel remains under the control of the packaging system, it can then be removed cleanly, or deployed on several machines. Furthermore, the scripts associated with these packages automate the interaction with the bootloader and the initrd generator.
The upstream Linux sources contain everything needed to build a Debian package of the kernel. But you still need to install build-essential to ensure that you have the tools required to build a Debian package. Furthermore, the configuration step for the kernel requires the libncurses5-dev package. Finally, the fakeroot package will enable creation of the Debian package without using administrator's rights.

8.10.2. Ottenere i sorgenti

Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the linux-source-version package. The apt-cache search ^linux-source command lists the various kernel versions packaged by Debian. The latest version is available in the Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of Sezione 6.2.6, «Lavorare con più distribuzioni»). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches, which might (or might not) find their way into the upstream version of Linux. These modifications include backports of fixes/features/drivers from newer kernel versions, new features not yet (entirely) merged in the upstream Linux tree, and sometimes even Debian specific changes.
The remainder of this section focuses on the 3.2 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-3.2 package has been installed. It contains /usr/src/linux-source-3.2.tar.bz2, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xjf /usr/src/linux-source-3.2.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.2.0-4-amd64 ~/kernel/linux-source-3.2/.config
Se non si necessita di cambiare la configurazione è possibile fermarsi qui e saltare alla prossima sezione. Se invece è necessario modificarla, o se si è deciso di riconfigurare tutto da zero, è necessario prendersi il tempo di configurare il kernel. Ci sono varie interfacce dedicate nella directory dei sorgenti del kernel che possono essere richiemate utilizzando il comando make target dove target sarà uno dei valori descritti di seguito.
make menuconfig compiles and executes a text-mode interface (this is where the libncurses5-dev package is required) which allows navigating the options available in a hierarchical structure. Pressing the Space key changes the value of the selected option, and Enter validates the button selected at the bottom of the screen; Select returns to the selected sub-menu; Exit closes the current screen and move back up in the hierarchy; Help will display more detailed information on the role of the selected option. The arrow keys allow moving within the list of options and buttons. To exit the configuration program, choose Exit from the main menu. The program then offers to save the changes you've made; accept if you are satisfied with your choices.
Other interfaces have similar features, but they work within more modern graphical interfaces; such as make xconfig which uses a Qt graphical interface, and make gconfig which uses GTK+. The former requires libqt4-dev, while the latter depends on libglade2-dev and libgtk2.0-dev.
When using one of those configuration interfaces, it's always a good idea to start from a reasonable default configuration. The kernel provides such configurations in arch/arch/configs/*_defconfig and you can put your selected configuration in place with a command like make x86_64_defconfig (in the case of a 64-bit PC) or make i386_defconfig (in the case of a 32-bit PC).

8.10.4. Compilazione e creazione del pacchetto

Once the kernel configuration is ready, a simple make deb-pkg will generate up to 5 Debian packages: linux-image-version that contains the kernel image and the associated modules, linux-headers-version which contains the header files required to build external modules, linux-firmware-image-version which contains the firmware files needed by some drivers, linux-image-version-dbg which contains the debugging symbols for the kernel image and its modules, and linux-libc-dev which contains headers relevant to some user space libraries like GNU glibc.
The version is defined by the concatenation of the upstream version (as defined by the variables VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION in the Makefile), of the LOCALVERSION configuration parameter, and of the LOCALVERSION environment variable. The package version reuses the same version string with an appended revision that is regularly incremented (and stored in .version), except if you override it with the KDEB_PKGVERSION environment variable.
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=1
[...]
$ ls ../*.deb
../linux-firmware-image-3.2.46-falcot_1_amd64.deb
../linux-headers-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot-dbg_1_amd64.deb
../linux-libc-dev_1_amd64.deb

8.10.5. Compilare moduli esterni

Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages, such as virtualbox-source (kernel support for the VirtualBox virtualization solution) or oss4-source (Open Sound System, some alternative audio drivers).
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.
For example, let's look at the virtualbox-source package: after installation, a .tar.bz2 of the module's sources is stored in /usr/src/. While we could manually extract the tarball and build the module, in practice we prefer to automate all this using DKMS. Most modules offer the required DKMS integration in a package ending with a -dkms suffix. In our case, installing virtualbox-dkms is all that is needed to compile the kernel module for the current kernel provided that we have the linux-headers-* package matching the installed kernel. For instance, if you use linux-image-amd64, you would also install linux-headers-amd64.
$ sudo apt-get install virtualbox-dkms

[...]
Loading new virtualbox-4.1.18 DKMS files...
First Installation: checking all kernels...
Building only for 3.2.0-4-amd64
Building initial module for 3.2.0-4-amd64
Done.

vboxdrv:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.2.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
virtualbox, 4.1.18, 3.2.0-4-amd64, x86_64: installed
virtualbox-guest, 4.1.18, 3.2.0-4-amd64, x86_64: installed
$ sudo modinfo vboxdrv
filename:       /lib/modules/3.2.0-4-amd64/updates/dkms/vboxdrv.ko
version:        4.1.18_Debian (0x00190000)
license:        GPL
description:    Oracle VM VirtualBox Support Driver
[...]

8.10.6. Applicare una patch al kernel

Some features are not included in the standard kernel due to a lack of maturity or to some disagreement with the kernel maintainers. Such features may be distributed as patches that anyone is then free to apply to the kernel sources.
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.2
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-2.9.1-3.2.21-201206221855.patch.gz | patch -p1
$ make deb-pkg LOCALVERSION=-grsec
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.