7.3. Compilation du noyau Linux

La compilation du noyau est une spécificité des systèmes libres, qui n'est possible que parce que l'on dispose des sources du noyau. Cependant, même pour certains Unix commerciaux, il est possible d'effectuer une édition de liens, les modules du noyau étant fournis sous la forme de fichiers objets. La compilation ou l'édition de liens du noyau est une opération technique qui peut surprendre un habitué des systèmes fermés que sont par exemple Windows ou OS/2. Cependant, elle permet d'obtenir un noyau très petit, optimisé pour la machine sur laquelle il tourne, et donc à la fois économe en mémoire et performant. Il est donc recommandé d'effectuer cette compilation : pourquoi conserver un monstre capable de gérer des périphériques qui ne sont pas et ne seront jamais installés sur votre système ?

La compilation du noyau de Linux nécessite de disposer des dernières sources du noyau (version 2.4.20. au 29/11/2002) et d'un compilateur. Il est évident que le compilateur idéal est le compilateur GCC. La version recommandée par les développeurs du noyau est la 2.95.3, mais les versions récentes semblent fonctionner correctement. Je supposerai dans la suite de ce document que vous disposez de la dernière version du noyau, à savoir la version 2.4.20.

La compilation du noyau n'est pas très difficile. Elle nécessite cependant de répondre correctement aux questions de configuration. Les erreurs peuvent être multiples, et souvent fatales. Il est donc fortement conseillé de disposer d'une disquette de démarrage afin de réparer le système en cas d'erreur. Par ailleurs, il faut toujours conserver le dernier noyau utilisable en sauvegarde dans le répertoire /boot/. Il faut également ajouter une entrée spécifiant ce noyau dans le programme de démarrage (lilo), afin de pouvoir sélectionner l'ancien noyau en cas d'erreur. Ces opérations seront décrites en détail plus loin.

La compilation du noyau se passe en quatre étapes :

7.3.1. Installation des sources de Linux

Les sources du noyau peuvent être trouvées sur le site kernel.org. Il est possible de récupérer les sources complètes, sous la forme d'une archive comprimée d'environ 24 Mo. Toutefois, si l'on dispose déjà d'une version complète des fichiers sources, il est envisageable de ne télécharger que les fichiers différentiels de cette version à la version courante (ce que l'on appelle classiquement des « patches »).

Il est recommandé d'installer les sources du noyau dans un autre répertoire que celui où se trouvent les fichiers sources de votre distribution, car ceux-ci contiennent les fichiers d'en-tête C qui ont été utilisés pour générer la bibliothèque C du système et sont donc nécessaires à la compilation des programmes. Le remplacement des fichiers sources du noyau imposerait donc, en toute rigueur, de recompiler la bibliothèque C du système (en pratique cependant, il est rare que les en-têtes du noyau soient modifiés au point de générer des incompatibilités, du moins dans une même série de noyaux). Cette opération est extrêmement technique, risquée et longue, il est donc logique que l'on s'en dispense. Les plus motivés trouveront en annexe la manière de procéder pour recompiler la bibliothèque C.

Généralement, les fichiers sources de Linux sont installés dans le répertoire /usr/src/linux/. On devra donc renommer temporairement le répertoire originel avant d'installer les sources du nouveau noyau, ou au moins en faire une sauvegarde. Une autre solution est d'installer les fichiers du noyau dans un répertoire /usr/src/linux<version>/ et d'utiliser un lien symbolique /usr/src/linux/ pour sélectionner la version que l'on veut compiler. Cela permet de conserver plusieurs jeux de sources de versions différentes, et de travailler sur la version courante dans le répertoire /usr/src/linux/ facilement. Les commandes suivantes permettront d'extraire les sources dans le répertoire dédié au sources de Linux. Elles supposent qu'il existe déjà un lien symbolique /usr/src/linux/ vers le répertoire devant acceuillir ces fichiers sources :

cd /usr/src
rm linux
mkdir linux-2.4.20
ln -s linux-2.4.20 linux
tar xvfz linux-2.4.20.tar.gz

Une fois le nouveau noyau compilé et installé, on pourra rétablir la dépendance de la bibliothèque C sur les fichiers d'en-tête de l'ancien noyau en rétablissant le lien symbolique à sa valeur initiale.

Si l'on dispose déjà d'une version complète des fichiers sources, et que l'on désire appliquer un patch, il faut décomprimer le fichier de patch avec la commande suivante :

gunzip fichier.gz
fichier.gz représente le fichier de patch comprimé (en supposant qu'il ait été comprimé à l'aide de gzip). L'application du patch se fait de la manière suivante :
patch -p0 < fichier

Cette commande doit être lancée à partir du répertoire /usr/src/. Elle suppose que les fichiers sources de Linux pourront être trouvées dans le répertoire ./linux/. Dans cette ligne de commande, fichier représente le nom du fichier de patch précédemment décomprimé, et l'option -p0 indique au programme patch d'utiliser les noms de répertoires relatifs au répertoire courant (à savoir ./linux/). Si les sources sont installées dans un autre répertoire, il faudra modifier l'option -px passée en paramètre au programme patch, où x est le nombre de niveaux de répertoires à ignorer pour l'application du patch. Consultez la page de manuel patch pour plus de détails sur cette option.

Il est recommandé de télécharger au moins une fois l'ensemble des sources du noyau, et de ne pas utiliser les sources fournies avec la distribution que vous utilisez. En effet, certaines distributions modifient les sources et on ne peut donc pas leur appliquer les patches standards. Toutefois, les fichiers sources fournis avec les distributions contiennent souvent d'autres patches non encore intégrés officiellement dans le noyau. Si l'une des fonctionnalités apportées par ces patches est utilisée, on devra se contenter des sources de la distribution.

7.3.2. Choix des options de configuration du noyau

La configuration du noyau peut se faire à l'ancienne avec la commande suivante :

make config

Cette commande pose une série de questions auxquelles il faut pouvoir répondre correctement du premier coup. On n'a pas le droit à l'erreur ici, faute de quoi il faut tout reprendre à zéro.

Il est nettement plus convivial d'utiliser la version Tcl/Tk sous X11. Cette version donne l'accès aux différentes options sans un ordre quelconque, et ne présente que les options réalisables étant données celles déjà fixées. Cette méthode est évidemment la méthode conseillée. Pour l'utiliser, il suffit de taper la commande suivante :

make xconfig

Si l'on ne dispose pas encore de X11, ce qui est probablement le cas lors d'une première installation, on peut utiliser la version texte avec menu en tapant la commande suivante :

make menuconfig

Quelle que soit la méthode utilisée, il faut répondre par 'Y' (pour « Yes »), 'N' (pour « No ») ou 'M' (pour « Module ») lorsque c'est possible. 'Y' et 'M' incluent la fonctionnalité courante dans le noyau, 'N' la supprime. 'M' permet d'utiliser la fonctionnalité en tant que module du noyau. En général, l'utilisation des modules permet d'alléger le noyau car les fonctionnalités sont chargées et déchargées dynamiquement. Cependant, les fonctionnalités nécessaires au démarrage de Linux, comme les gestionnaires de disques et systèmes de fichiers par exemple, ne doivent en aucun cas être placées dans des modules, car alors le système ne pourrait pas démarrer.

Le choix des options de configuration est réellement très large, car celles-ci couvrent un ensemble de fonctionnalités très large. La description exhaustive de ces options est à la fois fastidieuse et inutile, car vous n'utiliserez pas tous les gestionnaires de périphériques et toutes les fonctionnalités de Linux avec un même ordinateur. Il s'agit donc de répondre aux questions appropriées pour votre configuration, mais de le faire avec rigueur : la moindre erreur de configuration peut empêcher votre système de fonctionner correctement, voire l'empêcher de démarrer tout simplement. Vous trouverez une description rapide des principales options de configuration dans l'Annexe A. Les options les plus utiles seront également décrites lorsque cela sera nécessaire dans le chapitre de configuration du matériel.

7.3.3. Compilation et installation du noyau

Une fois la configuration du noyau réalisée, la compilation peut être lancée. Pour cela, il suffit de lancer les trois commandes suivantes dans le répertoire /usr/src/linux :

make dep
make clean
make bzImage

La première commande génère les dépendances entre les fichiers du noyau. Ces dépendances sont utilisées par les fichiers makefile. La deuxième commande effectue le ménage nécessaire pour supprimer tous les fichiers objets pouvant résulter d'une précédente compilation. Cette opération est nécessaire afin d'éviter de mélanger des fichiers ayant été compilés avec des options de configuration différentes. Enfin, la troisième commande lance la compilation et l'édition de liens proprement dite.

Une fois la compilation achevée, il faut installer le nouveau noyau. Cette opération nécessite beaucoup de prudence, car si le noyau nouvellement créé n'est pas bon, le système ne redémarrera pas. C'est pour cela qu'il est conseillé de conserver toujours deux versions du noyau, dont on est sûr que l'une d'entre elle fonctionne parfaitement. En pratique, cela revient à conserver la version originale du noyau installé par votre distribution. Pour cela, il faut en faire une copie de sauvegarde.

En général, le noyau est installé dans le répertoire /boot/ (ou dans le répertoire racine pour les anciennes versions de Linux). Il porte souvent le nom de vmlinuz. Pour le sauvegarder, il suffit donc de taper par exemple la commande suivante :

cp vmlinuz vmlinuz.old

Il faut également indiquer au gestionnaire d'amorçage qu'il faut qu'il donne maintenant la possibilité de démarrer l'ancienne version du noyau sous ce nouveau nom. Pour LILO, il suffit d'éditer le fichier /etc/lilo.conf et d'y ajouter une nouvelle configuration. En pratique, cela revient à dupliquer la configuration du noyau actuel et à changer simplement le nom du noyau à charger (paramètre « image » de la configuration dans /etc/lilo.conf) et le nom de la configuration (paramètre « label »). Vous devrez aussi rajouter l'option « prompt » si elle n'y est pas déjà, afin que LILO vous demande la configuration à lancer à chaque démarrage. Dans notre exemple, le nom du noyau à utiliser pour la configuration de sauvegarde sera vmlinuz.old. De même, si la configuration initiale de Linux porte le nom « linux », vous pouvez utiliser le nom « oldlinux » pour la configuration de sauvegarde.

Une fois le fichier lilo.conf mis à jour, il faut vérifier que l'on peut bien charger l'ancien système. Pour cela, il faut réinstaller LILO et redémarrer la machine. La réinstallation de LILO se fait exactement de la même manière que son installation, simplement en l'invoquant en ligne de commande :

lilo

Si LILO signale une erreur, vous devez corriger immédiatement votre fichier lilo.conf et le réinstaller.

Pour le GRUB, la définition d'une nouvelle configuration se fait également en dupliquant la configuration initiale et en changeant le nom de l'option de menu du GRUB et le chemin sur le fichier du noyau sauvegardé. Veillez également à bien ajouter une option timeout pour avoir la moindre chance de sélectionner la configuration à lancer. Tout cela doit être effectué dans le fichier de configuration /boot/grub/menu.lst. Contrairement à LILO, il n'est pas nécessaire de réinstaller le GRUB pour que les modifications de ce fichier soient prises en compte au démarrage suivant.

Vous pourrez alors redémarrer redémarrer la machine avec la commande suivante :

reboot

Le gestionnaire d'amorçage utilisé vous propose alors de choisir le système d'exploitation à lancer. Il faut ici sélectionner la configuration de sauvegarde pour vérifier qu'elle est accessible et fonctionne bien. Le système doit alors démarrer en utilisant la copie sauvegardée du noyau. Si cela ne fonctionne pas, on peut toujours utiliser le noyau actuel en sélectionnant le noyau initial et en corrigeant la configuration du gestionnaire d'amorçage.

Lorsque vous vous serez assuré que le système peut démarrer avec la sauvegarde du noyau, vous pourrez installer le nouveau noyau. Son image a été créée par make dans le répertoire /usr/src/linux/arch/i386/boot/, sous le nom bzImage. L'installation se fait donc simplement par une copie dans /boot/ en écrasant le noyau actuel vmlinuz :

cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz

Il faut également copier le fichier System.map du répertoire /usr/src/linux/ dans le répertoire /boot/ :

cp System.map /boot

Ce fichier contient la liste de tous les symboles du nouveau noyau, il est utilisé par quelques utilitaires systèmes.

Si vous utiliser LILO, il vous faudra le réinstaller à nouveau pour qu'il prennent en compte le nouveau noyau. Cela se fait avec la même commande que celle utilisée précédemment :

lilo

Cette opération n'est en revanche pas nécessaire avec le GRUB.

Encore une fois, il faut redémarrer la machine avec la commande suivante :

reboot

et vérifier que le nouveau noyau fonctionne bien. S'il ne se charge pas correctement, c'est que les options de configuration choisies ne sont pas correctes. Il faut donc utiliser le noyau sauvegardé, vérifier ses choix et tout recommencer. Attention cependant, cette fois, il ne faut pas recommencer la sauvegarde du noyau puisque cette opération écraserait le bon noyau avec un noyau défectueux.

Si le nouveau noyau démarre correctement, il ne reste plus qu'à installer les modules.

7.3.4. Compilation et installation des modules

Si le système a redémarré correctement, on peut compiler les modules et les installer. Il n'est pas nécessaire de prendre les mêmes précautions pour les modules que pour le noyau. Il suffit donc ici de lancer la commande suivante dans le répertoire /usr/src/linux/ :

make modules

Les modules sélectionnés lors de la configuration sont alors compilés, il ne reste alors plus qu'à les installer.

Au préalable, il est recommandé de décharger tous les modules présents en mémoire. Cette opération peut être réalisée avec les commandes suivantes :

modprobe -ar
lsmod
rmmod module
rmmod module
   ...

Notez que certains modules ne se déchargent pas automatiquement, il faut donc exécuter rmmod sur ces modules manuellement. L'installation des modules est alors très simple, puisqu'il suffit de lancer la commande suivante dans le répertoire /usr/src/linux/ :

make modules_install

Les modules sont installés dans le répertoire /lib/module/version/, où version est le numéro de version du noyau courant. Il est possible que des modules d'autres versions du noyau existent dans leurs répertoires respectifs. Si vous n'en avez plus besoin, vous pouvez les effacer. Attention cependant si vous avez installé des modules additionnels non fournis avec le noyau dans ces répertoires, vous pourriez encore en avoir besoin.

Comme on l'a déjà vu, les modules sont utilisés par le chargeur de module du noyau, grâce à la commande modprobe. Cette commande a besoin de connaître les dépendances entre les modules afin de les charger dans le bon ordre. Il faut donc impérativement mettre à jour le fichier /lib/modules/version/modules.dep à chaque fois que l'on installe les modules, à l'aide de la commande suivante :

depmod -a

Note : La commande depmod -a est exécutée automatiquement lors de l'installation des modules du noyau. Toutefois, elle devra être exécutée manuellement si l'on installe des modules non fournis avec le noyau.

Les modules doivent être installés après avoir installé le noyau et redémarré le système, faute de quoi la commande depmod peut ne pas trouver trouver tous les symboles utilisés par les modules dans le noyau en cours d'exécution.