La compilation du noyau

Avant de commencer, j'aimerai rappeler qu'il existe un Kernel Howto en français et que je ne suis pas là pour le remplacer :)

Qu'est ce que le kernel ?

A tort, certaines personnes considèrent Linux comme un système d'exploitation. Ce dernier n'est en réalité que le noyau. Associé au système GNU cela donne GNU / Linux, un système GNU et un noyau Linux. Tout comme il y aura un jour GNU / Hurd ... Tout ceci n'étant que philosophie, cela ne vous avance guère. Disons que le noyau c'est le coeur du système. C'est lui qui gère les périphériques, les drivers étant dans le kernel. La mémoire est également gérée par ce dernier. Les différents systèmes de fichiers ou protocoles réseau, le firewall ... tout ceci se trouve au sein du kernel. Linux, comme tout Unice est multi tâches, multi utilisateurs. Les différents mécanismes qui empêchent les utilisateurs de se nuire entre eux (fichiers utilisateurs, partage de la mémoire ...) sont également gérés par le noyau.

A quoi ca sert de recompiler son kernel ?

Sur des OS propriétaires tel que Windows, le kernel n'est qu'un fichier parmis tant d'autres (kernel32.dll) dont l'utilisateur de base ignore l'existance. La raison en est simple, c'est le même fichier pour tous, il se charge, effectue (mal) son travail et ca s'arrête là. Avec Linux c'est radicalement différent. Le code source est bien entendu disponible et les hackers de tout bord peuvent y bidouiller à loisir. Une fois les changements effectués, pour qu'ils soient pris en compte, il faut recompiler. Mais la recompilation du kernel ne s'arrête pas aux développeurs. Le kernel est personnalisable. J'entends par là que ce n'est pas un fichier unique pour tout le monde. On peut le configurer en fonction de notre matériel, de nos besoins. En fonction du type de CPU utilisé, les optimisations seront en conséquence. Pourquoi utiliser un kernel compilé pour i386 (le plus bas dans l'architecture x86 offrant une compatibilité pour tous) dans le cas où vous auriez un Athlon ? Dans le même ordre d'idée on peut parler du support des architectures SMP, des optimisations pour le bus AGP, l'Ultra DMA ... Vous pourriez également avoir plusieurs systèmes d'exploitation sur votre machine, et ainsi avoir besoin du support des systèmes de fichiers en question, ce qui vous permettrait de lire et d'écrire sur des partitions d'OS différents. Si vous avez des besoins spécifiques, support des quotas, gestion de la bande passante, du NAT ou autres, il vous faudra activer ou désactiver certaines options au sein du kernel.

Ma distribution inclue déjà tout ca sous forme de modules ...

Effectivement, les distributions proposent des kernels qui incluent toutes les options, tous les drivers, soit directement dans le kernel soit sous forme de module. A l'arrivée on se retrouve avec un kernel de plus d'un méga octet sans oublier les 300 modules qui l'accompagnent. Ca vous satisfait pleinement. Un allègement du kernel ne vous convaincra sûrement pas de l'utilité de la recompilation. On pourrait donc parler des optimisations processeur citées un peu plus haut ou le fait que régulièrement des mises à jour du kernel sont disponibles, incluant diverses corrections de bugs, des mises à jour de drivers. Pour les plus aventuriers / stupides / impatients, on pourrait ajouter que les kernels de développement sont rarement disponibles sous forme packagée.

Quelques précisions

Maintenant que vous vous êtes décidé à récupérer le dernier kernel - stable ou de développement - il va falloir le télécharger. Vous pouvez vous rendre sur le ftp officiel, ftp://ftp.kernel.org/pub/linux/kernel/ ou sur l'un des nombreux mirroir. Pour ce, il vous suffit de rajouter le suffix de votre pays entre ftp et kernel. Par exemple, ftp.fr.kernel.org. Une fois sur votre ftp vous vous rendez compte que de multiples versions sont disponibles. Elles ont une signification :

Prenons un kernel x.y.z. X représente le numéro majeur, Y nous indique que le kernel en question fait partie de la branche stable si le chiffre est pair ou instable si le chiffre est impair, Z représente le numéro de révision. Pour résumer, le kernel 2.2.17 est la 17ème révision de la branche 2.2.x dite stable, tandis que le 2.3.48 représentera la 48ème révision de la branche 2.3.x qui se trouve être instable (2.3.x, le 3 étant un chiffre impair). Attention, corsons un peu. Prenons le cas du 2.4.0-test11. Le 2.4 devrait nous indiquer qu'il s'agit d'un kernel stable, mais il n'en est rien. Il s'agit d'un kernel de test. On peut dire qu'il s'agit des dernières versions avant la sortie du 2.4.0 final, qui lui sera stable. Vous pouvez également rencontrer des 2.2.18-pre11. Il faut savoir que puisque le développement de Linux n'est pas centralisé comme c'est le cas chez Microsoft, les mainteneurs du kernel sortent régulièrements des pré versions d'un kernel à destination des développeurs. Dans notre exemple il s'agit d'un 2.2.17 qui en est à sa onzième pré version, qui mènera à l'arrivée au 2.2.18.

La parenthèse étant refermée, pour faire plus simple, 2.2 stable, 2.3 instable. Une fois dans le répertoire de votre choix, un fichier du type "LATEST-IS-2.2.17" vous indique que le dernier kernel stable en date dans cette branche est le 2.2.17. Bien que 6 fichiers différents commencent par linux-2.2.17, un seul nous intéresse. Si vous éliminez ceux inférieurs à 20 ko, il n'en reste plus que deux. Un se terminant par .tar.bz2 et l'autre par .tar.gz. Ceux sont les sources du kernel. La même archive, mais compressée différement. Vous pouvez prendre l'un ou l'autre, ca n'a pas d'importance.

Les préparatifs

Une fois votre fichier téléchargé, copiez le dans le répertoire /usr/src. Il y a de fortes chances pour que dans ce dernier il existe déjà un réperoire /linux contenant les includes du kernel, nécessaires à la compilation des programmes. Avant de décompresser les sources de notre nouveau noyau, nous allons commencé par renommer ce répertoire : mv linux linux-bak

Maintenant, si vous avez récupéré le fichier .tar.bz2, vous pouvez faire tar xIf linux-x.y.z.tar.bz2. Dans le cas d'un fichier .tar.gz il suffira d'employer la commande tar xvzf linux-x.y.z.tar.gz

Une fois les sources décompressées, entrez dans le répertoire linux nouvellement créé. Si les sources sont vierges de toute compilation, c'est ok. Dans le cas où vous auriez déjà compilé un kernel avec ces mêmes sources, utilisez la commande make mrproper pour nettoyer les sources de tous les fichiers .o crées par une compilation. Si vous tentez de compiler un kernel d'une branche autre que celle du kernel livré par défaut sur votre distribution, je vous conseil de jeter un oeil au fichier Changes qui se trouve dans le sous répertoire Documentation. Ce dernier indique les versions minimum des logiciels requis pour compiler ou utiliser correctement votre futur kernel.

Appliquer un patch

Pour la majeure partie des gens, le kernel de base suffit. Mais dans plusieurs cas, il se peut que vous ayez besoin d'appliquer un patch. Que ce soit une pre version d'un kernel à venir ou un patch incluant des fonctions non officielles, voir même le fait, tout simplement, de passer à la version supérieur en ne téléchargeant que les différences entre les deux versions d'un kernel donné. Dans tous ces cas, la procédure est la même.

Décompressez les sources du kernel dont vous avez besoin dans /usr/src. Entrez dans le répertoire /linux nouvellement créé et décompressez-y votre patch (généralement à l'aide de la commande gunzip). Pour finir, employez la commande suivante :

patch -p1 --dry-run <fichier-patch
Ensuite, si tout est ok : patch -p1 <fichier-patch

L'option -p1 signifie que vous vous trouvez dans /usr/src/linux avec les sources du kernel. Si vous êtes dans /usr/src (un niveau plus bas), vous utilisez l'option -p0. --dry-run sert à tester le patch sans appliquer les modifications. Pratique pour vérifier que tout est bien ok. Ne pas oublier le < du fait que patch attend un fichier en entrée. Et puis bien entendu, vous l'aurez compris, vous devez remplacer "fichier-patch" par le nom de votre patch.

La configuration

Avant de nous attaquer à la configuration du noyau proprement dite, si vous ne comprenez pas un mot d'anglais, vous pouvez toujours allé voir sur Kernel FR.org s'il n'existe pas un patch pour franciser la configuration de votre kernel. Maintenant que tout est ok, plusieurs choix s'offrent à vous pour la configuration du noyau :

make config : pour les gurus ou les frapadingues, en mode console, répondre à toutes les questions une par une :)
make menuconfig : toujours en mode console, mais configuration dans un mode pseudo graphique utilisant ncurses.
make xconfig : pour finir, le plus facile, configuration graphique sous X. La commande sera bien entendue tapée dans un xterm tout en étant à la racine des sources (/usr/src/linux si vous avez suivi mes conseils :)

Pour ne pas trop encombrer l'article, j'ai préféré détailler les options sur une autre page.

Maintenant que vous avez configuré votre kernel, il vaut mieux sauvegarder tout ca avec Store Configuration to File. Vous donnez un nom de fichier. Ce dernier se trouvera à la racine des sources du kernel. Je vous conseil d'en faire une copie en lieu sûr. Par la suite, si vous souhaitez recompiler un kernel, que la version soit identique ou différente, vous n'aurez plus qu'a recharger votre fichier de config avec Load Configuration from File et effectuer d'eventuels changements. Dans le cas d'un changement majeur du kernel, passage du 2.2.x au 2.4.x par exemple, il vaut quand même mieux repartir à zéro. Pour finir, cliquez sur Save and Exit.

La compilation

La compilation en elle même ne demande pas d'intervention particulière de votre part. Commencez par faire un make dep suivi d'un make clean. Viennent ensuite les commandes make bzImage (pour le kernel en lui même), make modules (dans le cas où vous auriez configuré certaines parties en tant que modules), et pour finir, make modules_install.

Si vous tournez actuellement sur un kernel SMP vous pourriez avoir envie de tirer profit de tous vos processeurs. Pour ce faire, éditez le fichier Makefile présent à la racine des sources du kernel et changez "MAKE=make" en "MAKE=make -jN" où N représente le nombre de vos CPU + 1. Si vous possédez une tonne de RAM et de swap vous pouvez également utiliser le paramètre -j sans aucun nombre.

Les derniers instants

Une fois que tout a été compilé avec succès, il nous reste quelques manips à effectuer. La première sera de copier l'image du kernel dans le répertoire /boot de votre système. Le kernel se trouve dans le sous répertoire /arch/i386/boot en tant que fichier bzImage. Profitez en également pour copier le System.map qui se trouve à la racine des sources.

cp arch/i386/boot/bzImage /boot/bzImage-x.y.z
cp System.map /boot/System.map-x.y.z

En copiant le kernel nous en avons profité pour le renommer. La raison est toute simple, LILO pouvant gérer 19 kernels différents, nous ne pouvont pas mettre plusieurs fois un fichier portant le même nom. Pourquoi plusieurs kernels ? Alors là c'est encore plus simple. Vous venez de compiler votre nouveau kernel, vous rebootez et là, horreur, ca ne démarre plus. Les raisons peuvent être multiples. Mauvaise configuration du kernel, divers oublis ... En ayant plusieurs kernels différents dans votre fichier /etc/lilo.conf, si un kernel ne démarre pas, vous pouvez toujours redémarrer sur votre ancien kernel, qui lui fonctionne bien.

Pour ceux que ca intéresse, le fichier System.map contient tous les symboles définis par le noyau ainsi que leurs adresses.

Donc notre kernel se trouve bien dans le répertoire /boot, mais pour que LILO puisse le charger faudrait quand même pensé à le lui indiquer. Donc vous éditez votre fichier /etc/lilo.conf, et vous rajoutez les lignes suivantes :

image=/boot/bzImage-x-y-z
label=linux
read-only

La ligne image= correspond au nom de l'image de votre kernel (sans oublier le chemin qui mène à cette dernière). label= sert à indiquer à LILO sur quel kernel ou sur quel système d'exploitation vous souhaitez booter. Par défaut, LILO charge le kernel portant le label "linux". N'oubliez pas de renommer le label de votre ancien kernel. Si vous avez besoin de plus d'infos sur la configuration de LILO il exite un LILO Mini Howto

Une fois les changements effectués vous devez relancez LILO. Pour ca, au prompt, il suffit de taper la commande lilo -v (-v pour verbose, pour que ce soit plus parlant en cas de problème).

Okki okki666@free.fr
02 décembre 2000

Un grand merci à flynux, TimeWarp et Obélix pour m'avoir aidé à combler mes lacunes :)