kernel - Compiler son kernel Linux
Table des matières
Le noyau Linux (ou kernel en anglais) est un noyau de système d'exploitation de type UNIX. Le noyau Linux est un logiciel libre développé essentiellement en langage C par des milliers de bénévoles et salariés communiquant par Internet.
Le noyau est le cœur du système, c'est lui qui s'occupe de fournir aux logiciels une interface pour utiliser le matériel.
C'est lui qui amorce le système d'exploitation.
Il est possible d'avoir plusieurs noyaux et utiliser celui de votre choix. Il est recommandé d'avoir toujours un noyau fonctionnel sur sa machine.
Pourquoi compiler son noyau ? Les noyaux fournis par défaut dans votre distribution GNU/Linux sont des noyaux capables de tourner sur un maximum de machines et de matériels. Ils sont donc souvent plus lourds, mais la différence de rapidité est en général assez faible. En fait les vraies raisons de compiler son propre noyau sont les suivantes :
Pour compiler son noyau, il est nécessaire d'avoir quelques prérequis :
Un bon processeur pour que la compilation soit rapide.
Prévoir 1Go de RAM au moins.
Avoir 10Go de place sur le disque dur (partition /usr/src)
Sur la distribution concernée, on a besoin de quelques logiciels :
Les paquets se nomment ainsi suivant les distributions:
Dans un premier temps, il est nécessaire de se connecter en root.
Toutes les commandes doivent être lancées en root.
On se positionne dans le dossier /usr/src . C'est le dossier qui contient des fichiers de code source, selon la norme FHS (File Hierarchy Standard)
On récupère ensuite le kernel depuis le site kernel.org (Je prends, en date de la rédaction de cet article le dernier noyau LTS : 3.14.33 )
On décompresse ensuite l'archive compressée :
Et on se rend dans le dossier précédemment désarchivé
Par défaut, le paquetage gentoo-source n'installe ni ne compile le kernel. Il s'agit donc des sources directement
Se rendre ensuite dans le dossier des sources :
Sous Calculate Linux, désactiver les 2 FLAG suivants :
Puis réinstaller le kernel :
Se rendre ensuite dans le dossier des sources :
Chez Mageia, pour récupérer directement les sources, on peut utiliser le paquet kernel-source-$version ou kernel-source-latest pour la dernière version empaquetée chez Mageia
Se rendre ensuite dans le dossier des sources :
On nettoie le dossier et on le prépare pour la compilation:
On peut recupérer la config en cours via :
Si on ne le fait pas, ce sera une config par "défaut" et minimale qui sera appliquée.
Pour régler les options dans le futur noyau, et affiner la configuration, on exécute la commande suivante :
On a ensuite une petite interface de type "ncurses" dans la console :
On navigue dans les menus avec les flèches haut et bas.
Les touches gauche et droite permettent de naviguer dans le menu en dessous et Entrée pour valider le choix.
On personnalise les options, par exemple, dans "General Setup" puis "Local Version" on peut mettre un suffixe au à la version du noyau, de notre choix :
On peut appuyer sur "?" pour avoir de l'aide (English of course!) sur l'option en question :
Si on cherche une option particulière, on peut afficher le formulaire de recherche via / (comme pour vi) et taper le terme souhaité. Les différents chemins pour accéder à l'option sont affichées :
METTRE UNE CAPTURE
Il n'existe pas que des menus et des options de type texte.
Par exemple, si on va dans les FileSystems, on voit plusieurs possibilités pour chaque option :
Par défaut, les options sont bien réglées.
On garde uniquement les * pour les éléments de base nécessaire au bon fonctionnement.
Le reste, en modules M.
Les modules ( < M > ) sont chargés à la demande. Si on met tout en drivers intégrés ( [ * ] ), on les charge au démarrage, le noyau est lourd et on ne peut pas les désactiver post-démarrage.
Ensuite au sauvegarde la configuration en allant sur <Save>
On lance ensuite la compilation :
Une fois la compilation terminée, on installe les modules :
Ils s'installent dans /lib(64)/modules/3.14.33/kernel
Cet ensemble de sous-répertoires contient les drivers pour accéder aux différents matériels présents dans le PC.
On installe ensuite le noyau :
On vérifie que les fichiers se sont bien installés :
Les fichiers :
Dans la plupart des cas, cette configuration fonctionne.
Néanmoins, il peut être utile de générer aussi un fichier initramfs.
Le fichier à générer est initramfs-version.img pour une autodétection par la commande grub-mkconfig.
C'est un fichier spécial qui contient un RAM Disk. C'est comme son nom l'indique un système de fichiers minimaliste chargé en RAM au démarrage du noyau qui contient les “drivers” nécessaires au boot du noyau. Ce RAM Disk est bien sûr détruit après boot complet du noyau.
Pour le générer on peut utilise la commande mkinitrd :
Exemple :
On peut utiliser la commande dracut qui permet d'être plus fexible :
Exemple
On peut ajouter plus facilement des modules complémentaires à la volée :
Exemple :
Il ne reste plus qu'à générer le fichier de GRUB2 pour lister dans le chargeur d'amorçage le nouveau kernel compilé :
(la localisation peut différer suivant les distributions)
Voici un exemple de sortie :
Notre noyau est bien trouvé avec son initramfs.
On redémarre et on teste notre nouveau noyau.
A la reconnexion on vérifie la version du kernel :
Dans mon exemple, tout est pris en compte
Si aucun module ne veut se charger (par exemple, pour le pilote réseau, modprobe e1000e) et que le message d'erreur est FATAL not found, vérifier
Si XZ est actif, vérifier les USE de sys-apps/kmod. Si le USE lzma n'est pas actif, l'activer ou désactiver la compression des modules dans la configuration du kernel.
Introduction
Le noyau Linux (ou kernel en anglais) est un noyau de système d'exploitation de type UNIX. Le noyau Linux est un logiciel libre développé essentiellement en langage C par des milliers de bénévoles et salariés communiquant par Internet.
Le noyau est le cœur du système, c'est lui qui s'occupe de fournir aux logiciels une interface pour utiliser le matériel.
C'est lui qui amorce le système d'exploitation.
Il est possible d'avoir plusieurs noyaux et utiliser celui de votre choix. Il est recommandé d'avoir toujours un noyau fonctionnel sur sa machine.
Pourquoi compiler son noyau ? Les noyaux fournis par défaut dans votre distribution GNU/Linux sont des noyaux capables de tourner sur un maximum de machines et de matériels. Ils sont donc souvent plus lourds, mais la différence de rapidité est en général assez faible. En fait les vraies raisons de compiler son propre noyau sont les suivantes :
- Comprendre comment fonctionne le noyau Linux.
- Faire fonctionner un matériel ou une fonctionnalité qui n'est pas pris en charge par votre noyau actuel.
- Vous voulez passer le temps.
Prérequis
Pour compiler son noyau, il est nécessaire d'avoir quelques prérequis :
Matériel
Un bon processeur pour que la compilation soit rapide.
Prévoir 1Go de RAM au moins.
Avoir 10Go de place sur le disque dur (partition /usr/src)
Logiciel
Sur la distribution concernée, on a besoin de quelques logiciels :
- wget : pour télécharger les sources du noyau (ou un navigateur Internet en graphique)
- tar : pour extraire l'archive du noyau
- xz : pour décompresser le noyau
- ncurses : pour afficher le menu de configuration
- make : pour lancer le processus de compilation
- gcc (c++) : le compilateur C
- dracut : le générateur d'image initramfs
Les paquets se nomment ainsi suivant les distributions:
- Gentoo / Calculate Linux : net-misc/wget app-arch/tar app-arch/xz-utils sys-libs/ncurses sys-devel/make sys-devel/gcc sys-kernel/dracut
- Mageia : wget tar xz ncurses-devel make gcc-c++
Mise en oeuvre
Dans un premier temps, il est nécessaire de se connecter en root.
Toutes les commandes doivent être lancées en root.
Récupération des ressources
Depuis le site officiel (base de cet article)
On se positionne dans le dossier /usr/src . C'est le dossier qui contient des fichiers de code source, selon la norme FHS (File Hierarchy Standard)
Code BASH :
cd /usr/src
On récupère ensuite le kernel depuis le site kernel.org (Je prends, en date de la rédaction de cet article le dernier noyau LTS : 3.14.33 )
Code BASH :
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.33.tar.xz
On décompresse ensuite l'archive compressée :
Code BASH :
tar -xf linux-3.14.33.tar.xz
Et on se rend dans le dossier précédemment désarchivé
Code BASH :
cd linux-3.14.33
Depuis les sources de la distribution
Gentoo
Par défaut, le paquetage gentoo-source n'installe ni ne compile le kernel. Il s'agit donc des sources directement
Code BASH :
emerge -avq gentoo-sources
Se rendre ensuite dans le dossier des sources :
Code BASH :
cd /usr/src
Calculate Linux
Sous Calculate Linux, désactiver les 2 FLAG suivants :
-minimal pour demander à emerge de télécharger les sources complètes ;
-vmlinuz pour éviter la compilation automatique, en faveur de la prise en charge manuelle du noyau.
-vmlinuz pour éviter la compilation automatique, en faveur de la prise en charge manuelle du noyau.
Puis réinstaller le kernel :
Code BASH :
echo "sys-kernel/calculate-sources -minimal -vmlinuz" >> /etc/portage/package.use/custom emerge -avq calculate-sources
Se rendre ensuite dans le dossier des sources :
Code BASH :
cd /usr/src
Mageia
Chez Mageia, pour récupérer directement les sources, on peut utiliser le paquet kernel-source-$version ou kernel-source-latest pour la dernière version empaquetée chez Mageia
Code BASH :
urpmi kernel-source-latest
Se rendre ensuite dans le dossier des sources :
Code BASH :
cd /usr/src
Préparation à la compilation
On nettoie le dossier et on le prépare pour la compilation:
Code BASH :
make mrproper
On peut recupérer la config en cours via :
Code BASH :
zcat /proc/config.gz > .config
Si on ne le fait pas, ce sera une config par "défaut" et minimale qui sera appliquée.
Caché :
Ensuite, vu que le kernel à compiler n'est sûrement pas dans la même version, il faut voir s'il y a eu des modifications dans la configuration :
Ce mode est interactif sur toutes les nouvelles options.
Code BASH :
make oldconfig
Ce mode est interactif sur toutes les nouvelles options.
Caché :
Code TEXT :
HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --oldconfig Kconfig # # using defaults found in /boot/config-3.14.27-calculate # # # configuration written to .config #
La personnalisation
Pour régler les options dans le futur noyau, et affiner la configuration, on exécute la commande suivante :
Code BASH :
make menuconfig
On a ensuite une petite interface de type "ncurses" dans la console :
On navigue dans les menus avec les flèches haut et bas.
Les touches gauche et droite permettent de naviguer dans le menu en dessous et Entrée pour valider le choix.
- Select permet de sélectionner le menu en surbrillance ou de changer une valeur (un texte)
- Exit permet de revenir au menu précédent
- Help permet d'avoir de l'aide sur le menu en cours
- Save permet de sauvegarder les modifications dans le fichier .config
- Load permet de restaurer une configuration
On personnalise les options, par exemple, dans "General Setup" puis "Local Version" on peut mettre un suffixe au à la version du noyau, de notre choix :
On peut appuyer sur "?" pour avoir de l'aide (English of course!) sur l'option en question :
Si on cherche une option particulière, on peut afficher le formulaire de recherche via / (comme pour vi) et taper le terme souhaité. Les différents chemins pour accéder à l'option sont affichées :
METTRE UNE CAPTURE
Il n'existe pas que des menus et des options de type texte.
Par exemple, si on va dans les FileSystems, on voit plusieurs possibilités pour chaque option :
Code TEXT :
< > < M > [ * ]
- < > : Driver non compilé
- < M > : Driver dynamique appelé module. Un module est compilé mais n'est pas lié au noyau. Un module sera chargé au boot du PC par un service du noyau en fonction des matériels réellement présents dans le PC. On pourra aussi charger manuellement un module si l'on veut (commande insmod).
- [ * ] : Le driver est compilé et lié de façon statique avec le noyau. On ne peut pas le retirer de la mémoire même si l'on ne s'en sert pas. On voit que si l'on incorpore tous les drivers dans le noyau, celui-ci devient énorme en taille et va contenir tout un tas de drivers inutiles car ne correspondant pas à un matériel présent dans le PC.
Par défaut, les options sont bien réglées.
On garde uniquement les * pour les éléments de base nécessaire au bon fonctionnement.
Le reste, en modules M.
Les modules ( < M > ) sont chargés à la demande. Si on met tout en drivers intégrés ( [ * ] ), on les charge au démarrage, le noyau est lourd et on ne peut pas les désactiver post-démarrage.
Ensuite au sauvegarde la configuration en allant sur <Save>
La compilation
On lance ensuite la compilation :
Code BASH :
make
Caché :
Code TEXT :
scripts/kconfig/conf --silentoldconfig Kconfig SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_32.h SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_64.h SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_x32.h SYSTBL arch/x86/syscalls/../include/generated/asm/syscalls_32.h SYSHDR arch/x86/syscalls/../include/generated/asm/unistd_64_x32.h SYSHDR arch/x86/syscalls/../include/generated/asm/unistd_32_ia32.h SYSTBL arch/x86/syscalls/../include/generated/asm/syscalls_64.h CHK include/config/kernel.release WRAP arch/x86/include/generated/asm/clkdev.h UPD include/config/kernel.release CHK include/generated/uapi/linux/version.h UPD include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h UPD include/generated/utsrelease.h HOSTCC scripts/kallsyms HOSTCC scripts/conmakehash HOSTCC scripts/bin2c HOSTCC scripts/sortextable CC scripts/mod/empty.o HOSTCC scripts/mod/mk_elfconfig CC scripts/mod/devicetable-offsets.s GEN scripts/mod/devicetable-offsets.h [........] IHEX firmware/ti_3410.fw IHEX firmware/ti_5052.fw IHEX firmware/mts_cdma.fw H16TOFW firmware/edgeport/boot.fw H16TOFW firmware/edgeport/down.fw H16TOFW firmware/edgeport/boot2.fw IHEX firmware/mts_edge.fw IHEX firmware/mts_gsm.fw H16TOFW firmware/edgeport/down2.fw IHEX2FW firmware/whiteheat_loader.fw IHEX2FW firmware/keyspan_pda/keyspan_pda.fw IHEX2FW firmware/keyspan_pda/xircom_pgs.fw IHEX firmware/cpia2/stv0672_vp4.bin IHEX firmware/edgeport/down3.bin IHEX2FW firmware/whiteheat.fw real 13m58.388s user 96m55.100s sys 7m51.510s
L'installation
Une fois la compilation terminée, on installe les modules :
Code BASH :
make modules_install
Caché :
Code TEXT :
INSTALL arch/x86/crypto/aes-x86_64.ko INSTALL arch/x86/crypto/aesni-intel.ko INSTALL arch/x86/crypto/camellia-aesni-avx-x86_64.ko INSTALL arch/x86/crypto/camellia-aesni-avx2.ko INSTALL arch/x86/crypto/camellia-x86_64.ko INSTALL arch/x86/crypto/crc32-pclmul.ko INSTALL arch/x86/crypto/crct10dif-pclmul.ko [...] INSTALL /lib/firmware/edgeport/down3.bin INSTALL /lib/firmware/whiteheat_loader.fw INSTALL /lib/firmware/whiteheat.fw INSTALL /lib/firmware/keyspan_pda/keyspan_pda.fw INSTALL /lib/firmware/keyspan_pda/xircom_pgs.fw INSTALL /lib/firmware/cpia2/stv0672_vp4.bin DEPMOD 3.14.33
Ils s'installent dans /lib(64)/modules/3.14.33/kernel
Cet ensemble de sous-répertoires contient les drivers pour accéder aux différents matériels présents dans le PC.
On installe ensuite le noyau :
Code BASH :
make install
Caché :
Code :
sh /usr/src/linux-3.14.33/arch/x86/boot/install.sh 3.14.33 arch/x86/boot/bzImage \
System.map "/boot"
On vérifie que les fichiers se sont bien installés :
Code BASH :
ls /boot/*3.14.33* /boot/config-3.14.33-adrien /boot/System.map-3.14.33-adrien /boot/vmlinuz-3.14.33-adrien
Les fichiers :
- vmlinuz-3.14.33-adrien : C'est le noyau Linux.
- System.map-3.14.33-adrien : C'est la table des symboles du noyau. C'est un fichier ASCII qui donne la correspondance entre un symbole du noyau (étiquette, fonction, variable...) et son adresse en mémoire. Cela sert par exemple à débugger le noyau au niveau symbolique.
- config-3.14.33-adrien : C'est le fichier de configuration de la compilation qui a servi à générer le noyau Linux.
Dans la plupart des cas, cette configuration fonctionne.
Néanmoins, il peut être utile de générer aussi un fichier initramfs.
Générer le initramfs
Le fichier à générer est initramfs-version.img pour une autodétection par la commande grub-mkconfig.
C'est un fichier spécial qui contient un RAM Disk. C'est comme son nom l'indique un système de fichiers minimaliste chargé en RAM au démarrage du noyau qui contient les “drivers” nécessaires au boot du noyau. Ce RAM Disk est bien sûr détruit après boot complet du noyau.
Avec la commande mkinitrd
Pour le générer on peut utilise la commande mkinitrd :
Code BASH :
mkinitrd /boot/initramfs-$version.img $version
Exemple :
Code BASH :
mkinitrd /boot/initramfs-3.14.33-adrien.img 3.14.33-adrien
Avec la commande dracut
On peut utiliser la commande dracut qui permet d'être plus fexible :
Code BASH :
dracut --kver $version
Exemple
Code BASH :
dracut --kver 3.14.33-adrien
On peut ajouter plus facilement des modules complémentaires à la volée :
Code BASH :
dracut -a "module1 module2" --kver $version
Exemple :
Code BASH :
dracut -a lvm --kver 3.14.33-adrien
Modifier le fichier de GRUB
Il ne reste plus qu'à générer le fichier de GRUB2 pour lister dans le chargeur d'amorçage le nouveau kernel compilé :
(la localisation peut différer suivant les distributions)
Code BASH :
grub-mkconfig -o /boot/grub/grub.cfg
Voici un exemple de sortie :
Code TEXT :
Création du fichier de configuration GRUB… Arrière-plan trouvé : /boot/grub/grub-calculate.png Image Linux trouvée : /boot/vmlinuz-3.14.33-adrien Image mémoire initiale trouvée : /boot/initramfs-3.14.33-adrien.img Image Linux trouvée : /boot/vmlinuz-3.14.27-calculate Image mémoire initiale trouvée : /boot/initramfs-3.14.27-calculate.img Image Linux trouvée : /boot/vmlinuz-3.14.27-SafeMode-calculate Image mémoire initiale trouvée : /boot/initramfs-3.14.27-SafeMode-calculate.img No volume groups found fait
Notre noyau est bien trouvé avec son initramfs.
Redémarrage et test
On redémarre et on teste notre nouveau noyau.
A la reconnexion on vérifie la version du kernel :
Code BASH :
uname -a
Dans mon exemple, tout est pris en compte
Code TEXT :
Linux tuto-kernel 3.14.33-adrien #2 SMP Fri Feb 20 18:30:58 CET 2015 x86_64 Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz GenuineIntel GNU/Linux
Problèmes connus
Aucun module ne se charge
Si aucun module ne veut se charger (par exemple, pour le pilote réseau, modprobe e1000e) et que le message d'erreur est FATAL not found, vérifier
Code BASH :
[*] Enable loadable module support ---> [*] Compress modules on installation Compression algorithm (XZ) --->
Si XZ est actif, vérifier les USE de sys-apps/kmod. Si le USE lzma n'est pas actif, l'activer ou désactiver la compression des modules dans la configuration du kernel.