L'arrivée des NetBook donnent clairement une nouvelle forme de légitimité à Linux. Il suffit d'avoir utilisé tour à tour une distribution quelconque et un Windows Vista sur une de ces bestioles pour se rendre à quel point le pingouin se sent à l'aise lorsqu'il est un peu à l'étroit.
Dans la même idée, ces machines redonnent sens à de "vieilles" technique visant à optimiser un kernel pour coller au plus prés des ressources. Et l'une de ces techniques est la création d'un kernel monolithique.
Le principe "monolithique" n'est en soit pas réservé à Linux (ici le GNU n'est pas nécessaire
). Il s'agit en fait d'une des trois grandes catégories d'architectures de noyau, avec le modulaire et le micro.
Dans l'architecture monolithique, toutes les domaines de compétence sont regroupés dans un seul bloc binaire, le noyau, chargé au démarrage. Les domaines étant liés au noyau de manière statique, leur inter-communication se fait par simple "appel de fonction" comme dans n'importe quel programme en C. C'est rapide, efficace mais pose malgré tout deux problèmes. Le premier est qu'un tel noyau deviendrait vit obèse s'il devait prendre en charge la fulltitude de périphériques existant. Le second est qu'il est très difficile à maintenir car toutes ces domaines tendent humainement à se lier les unes aux autres pour former un sauvage plat de spaghetti d'appels de fonctions.
L'architecture "modulaire" va chercher à décharger le noyau de toutes les domaines variant d'une plate-forme (ex. telle périphérique) ou d'un paramétrage (ex. tel mode de gestion mémoire) à l'autre. Les domaines sont ici des modules sous la forme de fichier indépendant qui cette fois sont liés dynamiquement au noyau plus ou moins comme une simple librairie. la communication inter-domaine est donc à peu prés aussi rapides que pour l'architecture monolithique avec un noyau cette fois beaucoup plus petit. Le problème d'obésité est donc réglé mais pas celui de la maintenance, car les modules restent liés les uns aux autres par de simples appels de fonction.
L'architecture micro-noyau va quant à elle encore plus loin que le modulaire en délaissant le concept trop laxiste de librairies dynamique au profit d'un protocole de communication inter-processsus spécialisé qui fonctionne un peu à la manière de Corba ou DBUS. Les domaines sont connus par leurs interfaces, composée d'un nom de service (ex. "carte WIFI") et d'une liste normalisée de fonction (ex. "scanner réseaux"). En fonction de sa configuration le noyau va pouvoir ainsi charger le module qui convient pour un service donné (ex. "carte WIFI Atheros 5k"). Mais plus important, ce protocole assure l'étanchéité entre les domaines qui ne se connaissent plus que par leur "interface". Cela limite grandement la dépendance entre modules et rend l'ensemble plus maintenable au détriment d'une relative perte de vitesse.
Un exemple connu de noyau micro-kernel est Mach qui sert de base au noyau Darwin de MacOS. C'est aussi l'architecture du noyau de Windows NT. Comme quoi l'association classique faite entre micro-kernel, portabilité et performance n'est pas forcement une évidence.
Linux quant à lui appartient aussi bien à une architecture monolithique que modulaire car il est possible pour chaque module de décider s'il va être lié au kernel de manière statique (mode monolithique) ou dynamique (mode modulaire).
Le monolithique peut aujourd'hui, à juste titre, être considéré comme obsolète car au fond l'objectif de toute distribution est d'être compatible avec le plus large éventail de configurations matérielles. Cependant, l'omniscience du modulaire est aussi sa faiblesse. En effet un tel noyau ne connaît par définition que peu de choses du monde. Lorsqu'il démarre il ne sait pas ce qu'est un disque SATA, un système de fichier EXT3. Pour s'en sortir ce noyau a besoin d'un fichier contenant une série des modules de survie qui va au moins lui permettre de monter la partition principale qui contient le reste des modules. Ce fichier c'est initrd. Ainsi pour démarrer, ce noyau modulaire va devoir chercher ce fichier, le décompresser, le monter à la racine, tester les modules qui s'y trouvent pour trouver le contrôleur de disque, puis le système de fichier, monter la partition, et enfin, poursuivre son démarrage sur cette dernière.
Ensuite pour chaque nouveau domaine, il va devoir trouver le bon module, le charger en mémoire, lire sa table des symboles (car c'est librairie dynamiquement liée), l'initialiser puis passer au suivant, et ainsi de suite jusqu'à ce qu'enfin, le login apparaisse.
Sur une machine de bureau moderne, toute cette mise en route prends une quinzaine de secondes. Mais sur un NetBook comme l'U810 avec son Atom à 800Mhz et son disque dur à 4200rpm, c'est 80 secondes... Et une bonne partie de ce temps est soit lié à initrd, soit au choix des modules, soit à leur chargement. Et c'est du coup là que revient en force le kernel monolithique qui sait déjà quel matériel est présent, qui charge tout en une seule fois en mémoire et ne pose plus de questions après.
C'est donc un tel noyau que nous allons chercher à construire. Pour être exact nous allons créer un noyau hybride car il reste des choses qu'il est plus sage de laisser en module comme par exemple la partie spécifique de la gestion de l'USB. En effet ce sont des fonctions que l'on apprécie d'avoir sous la main (ex. brancher à chaud une clef Wifi) mais que l'on n'utilise pas forcément en permanence. L'idée est donc :
Pour les sources, le plus simple est d'utiliser celles du noyau courant de votre distribution mais vous pouvez aussi prendre une version originale sur kernel.org. Dans un cas comme dans l'autre, on va se dire que les sources sont décompressées dans le dossier /usr/src/linux.
Avant de commencer nous devons modifier version du prochain kernel (uname -r) en ajoutant par exemple un -custom. Pour se faire, il faut éditer le Makefile qui se trouve à la racine des sources :
Ensuite nous pouvons récupérer la configuration de l'actuel noyau (d'où l'avantage d'utiliser les sources du noyau de votre distribution) :
Nous allons maintenant éditer le fichier .config qui est le paramétrage du noyau. C'est lui qui permet d'activer ou désactiver des fonctionnalités non-utiles par le biais de modules générés ou pas.
Pour éditer la configuration du kernel nous avons plusieurs options :
Personnellement je préfère la méthode "menuconfig", mais chacun son style.
Maintenant comme Linux peut fonctionner en mode modulaire ou monolithique, un module peut être compilé en tant que fichier indépendant (.ko pour kernel object et ko.z pour la version gzippée) ou directement "lié" au kernel.
Une fois l'interface compilée et lancée, le jeu commence. Les [ ] signifie que le module ou la section est désactivé (non compilé), [*] que c'est activé ET lié au kernel (mode monolithique) et [m] que l'on cherche à produire un module indépendant (.ko.z). On se déplace avec les flèches, la touche n permet de désactiver quel que soit l'état d'origine et espace permet de passer d'un état à l'autre. Enfin, l'astuce excellente de Scorpio810, la touche / permet à tout moment de faire une recherche dans les différentes sections de l'aide.
Toute la science repose maintenant sur la capacité à savoir si tel ou tel module est utilisé par votre système. Déjà ne pas hésiter à utiliser l'aide en ligne du configurateur qui donne de très bon indices (genre "si vous ne savez pas à quoi ça sert, désactivez!"
).
L'autre outil est le classique lsmod. En effet, vous êtes actuellement dans la version "modulaire" du noyau, vous avez donc par cette fonction une liste des modules utiles à votre système. Ceci dit ils ne le sont pas tous loin de là, et c'est aussi un des aspects non optimum des kernels monolithique : charger des modules qui ne servent à rien et encombrent la mémoire.
Une fois que l'on a une liste de module "vitaux", il faut les transmettre dans la configuration. Le problème est généralement de savoir où cela se trouve. Une version aussi bourrine qu'efficace consiste à tester dans tous les Makefile avec les commande find/grep. Par exemple pour chercher le symbole kernel du module ide-cs
Une fois que l'on a le symbole responsable de la compilation ou non du module, il suffit d'ouvrir le fichier .config avec un éditeur de texte pour le localiser et ainsi comprendre où est-ce qu'il se trouve dans la configuration via menuconfig. Une autre option consiste à utiliser ce script PERL qui permet de tout faire en une seule passe. Il vous renvoie la liste des symboles qui semble non nécessaires et ceux qui lui semble l'être.
Avant de terminer, il peut être intéressant aussi de régler certaines options du noyau pour améliorer les performances. Ce genre de chose se trouve dans General setup ou Processor type and feature. On peut désactiver des choses sans intérêt pour nous comme le debugging, le profiling, l'IPV6, etc., ou encore sélectionner un type de processeur plus adapté. Par exemple, une légende urbaine peut être vraie tend à dire que l'Atom est mieux pris en charge par un code compilé en mode "Core2" que "Pentium4", c'est le moment de tester...
Enfin vous pouvez fixer certaines options un peu violente pour une petite machine comme le fait de gérer plus de 4go de ram lorsque l'on en aura jamais plus de 1go...
Une fois que la toutouille est terminée, nous pouvons passer à la compilation. Sélectionnez "sauver", et "quitter"
C'est bon, tout est configuré, il ne reste plus qu'à compiler. L'avantage est que nous avons tellement éliminé de module que cette étape sera un peu plus rapide que d'habitude. Cependant il est toujours possible d'utiliser distcc.
La première commande va nous créer le fichier qui nous intéresse : bzImage. Il s'agit du kernel sous la forme d'un gros fichier compressé localisé dans le dossier arch/x86/boot.
L'ensemble des noyaux disponibles au lancement de linux se trouvent dans le dossier /boot. Nous allons donc y copier notre bébé. Dans la mesure où nous sommes en kernel monolithique, nous n'avons pas, et c'est là un des intérêt de la manoeuvre, besoin de générer d'initrd.
Nous avons donc trois fichiers à copier pour pouvoir démarrer : bzImage, .config et System.map. A noter que les deux derniers sont optionnels et généralement lorsque je teste, je m'en passe très bien :
Dernière étape, paramétrer GRUB pour prendre en compte notre nouveau kernel :
Voilà, maintenant croisage de doigts et redémarrage. Si vous échouez sur un kernel panic, notez bien l'erreur, cherchez la sur le net et recommencez le paramétrage. Généralement il s'agit d'un problème de module disque ou système de fichier non chargé.
Une fois que le kernel est optimisé, il faut aussi penser à faire un dégraissage des services qui ne servent à rien. Par exemple avez-vous besoin du bluetooth activé en permanence ? qu'Avahi soit utilisé systématiquement ? Dans le cas contraire il est pertinent d'aller faire sur l'outil qui vous sert à activer/désactiver les services (drakxservices sous mandriva) et faire un peu le ménage.
De même telle ou telle interface réseau peut préférer être activée à la demande, pour cela modifier le fichier /etc/sysconfig/network-script/ifcfg-XXXX et ajoutez un ONBOOT=no.
Ensuite une bonne manière de gagner du temps passe par le paquet readahead qui va précharger dans le cache les binaires qui seront utilisés. A noter qu'il existe une version boosté de ce soft dans le project moblin, la plateforme Linux/Intel pour les unités mobiles. Dans le même esprit que readahead mais globalisé à l'ensemble des applications, il y aussi le paquet preload.
Concernant les temps de lancement des applications, un paquet bien utile est prelink qui va, via une tâche cron, scanner tous les binaires et les modifier de sorte à ce que les références à des librairies se fasse plus rapidement (en gros
).
Enfin, un portable voit rarement son hardware évoluer. Il est donc, sous mandriva, utile de rajouter dans /etc/sysconfig/system un HARDDRAKE_ONBOOT=no pour éviter qu'une recherche de nouveautés soit effectué au démarrage.
Comme nous le montre bootchart, là où le noyau mettait 15 secondes à se lancer, il est maintenant à moins de 5s. Le démarrage complet de la machine, c'est à dire tous les services chargés et le CPU libre, passe de 80s à 35s. Ensuite le système est globalement plus réactif, c'est très sensible. C'est là que l'on prend bien conscience que la vielle technique a encore de beaux jours devant elle.
- répondre
AP , le 27 October, 2008 - 07:19Et encore une très bonne doc, une.
Petite correction (mais j'ai eu un doute, sur le coup) : le micro-noyau de Darwin est Mach (http://fr.wikipedia.org/wiki/Mach_(informatique)) et non March.
Sinon, pour savoir quoi intégrer dans le nouveau noyau, on peut s'appuyer sur ce qu'indique "lspci" (package "pciutils" sur Mandriva). Mandriva, justement, fournit une version améliorée de lspci : "lspcidrake". Cette dernière a le bon goût d'afficher en regard de chaque périphérique trouvé le nom du module nécessaire correspondant (que celui-ci soit chargé en mémoire ou non). Un bon auxiliaire également pour obtenir le détail de la configuration est "lshw" qui fournit sous forme de texte un long listing (indenté, pour mettre en valeur la hiérarchie des matériels) du matériel détecté sur la machine.
Depuis le temps que j'entends parler de "bootchart", par curiosité je crois que je vais l'essayer sur ma config pour avoir une idée de ce qui prend le plus de temps dans mon boot. Bon, cela-dit, comme je ne reboote que quand je mets à jour mon noyau, à savoir peu souvent... gagner quelques secondes est accessoire. En revanche, sur mon eeePC ça peut être intéressant. La Mandriva 2009, cela-dit, semble faire du bon boulot sur cette petite config pour obtenir un boot rapide.
- répondre
Ulhume, le 27 October, 2008 - 08:43@AP Nan, c'est toi qui a raison, March ce sera seulement dans quelques mois
Yep lspci, lsusb, lshw sont des outils important, tu as raison.
Pour ce qui est du temps de boot, je suis bien d'accord, pour un netbook cela compte ne serais-ce qu'à cause de la mise en veille prolongée qui est la seule qui ne mange pas les batteries. Si cela t'intéresse, je peux te passer mon .config pour l'u810, il y a sûrement des différences, mais cela fait déjà moins de ménage à faire.
- répondre
Nithir , le 27 October, 2008 - 08:50Bravo pour la doc, aussi claire qu'intéressante.
Moi qui ai de vieux ordi (PIII 700, PII 350) pour lesquels je cherchais un moyen de leur donnée une seconde vie en tant que machine de surf internet "rapide" et qui les trouvé un peu lente
Je vais pouvoir diminuer leur temps de démarrage, a défaut de les rendre plus véloce à l'utilisation.
Moi qui avais "peur" de me lancer dans la compilation d'un noyau, je suis rassuré.
Bon travail et bonne continuation.
- répondre
Armetiz , le 27 October, 2008 - 09:26Coucou,
Encore une belle documentation en effet,
J'ai souris au passage du "Ici le GNU n'est pas nécessaire".
Par contre, même si l'exercice de la compilation de noyau est très intéressant, au niveau de l'optimisation, est-ce que l'on a un réel gain par rapport à une distribution comme Archlinux ?
Pour la petit histoire, Archlinux est compilée pour les 686, et ne contient pas beaucoup de chose à la base.
Pour un débutant, ou même un utilisateur un peu avancé ne maitrisant pas tout les concepts du noyau Linux, ne va t-il pas passer un temps énorme pour avoir son pc fonctionnel, tout cela pour gagner une seconde au démarrage ?
En tout cas, merci pour cette article, cela enrichi le Web
- répondre
Ulhume, le 27 October, 2008 - 10:02@Armetiz
Le gain est fonction de l'intérêt que l'on porte à l'objectif. L'optimisation d'un kernel, outre l'aspect pédagogique, permet 1/ de diminuer le temps de démarrage ce qui est fort utile pour un NetBook/suspend 2/ augmenter la vitesse globale du système. En effet, en désactivant certaines options qui ne sont pas utile comme IPV6, SELinux, le debug kernel, la gestion des >4go, les attributs étendus pour EXT2/EXT3, etc., mais aussi en activant d'autres (ex. premption), le noyau change ses priorité pour coller à tes besoins. Après je n'ai pas de bench particulier mais pour une petite machine comme l'U810, la réactivité me semble bien meilleur. La moindre consommation de mémoire doit aussi y être pour quelque chose.
Maintenant pour ce qui est de recompilé spécialement pour adopter une architecture CPU, j'ai tendance à dire BOF. Les debian ont longtemps été critiqués pour être compilées en mode 386 et pourtant je n'ai jamais senti qu'une debian allait moins vite qu'un mandriva (586). Lorsque je compile un noyau j'adapte juste par acquis de conscience plus que par conviction en somme
Pour ce qui est d'Archlinux, là aussi pour moi toutes les distributions se valent dans la mesure où chaque service peut être désactivé. J'ai gagné 7s au démarrage et autant de mémoire en jouant à ce jeu sur l'U810. Cependant l'avantage de LSF comme Gentoo ou de manière indirect des distribution spartiates comme Arch est que les applications elle même sont compilées avec moins d'options. Et là oui, j'imagine bien que cela octroi un gain de vitesse lorsque telle ou telle appli arrête de faire papa-maman.
Alors pour répondre à ta question, un débutant peut y trouver son compte, ne serait-ce qu'en étant plus un débutant
- répondre
Ulhume, le 27 October, 2008 - 10:04@Nithir
Pour te rassurer encore un peu ce site web a très longtemps tourné chez moi, sur un PII à 300Mhz avec un kernel mono et un nombre de services minimum, le tout sous Mandriva sans aucun problème avec la gestion du mail et du spam en prime.
- répondre
tuxce , le 27 October, 2008 - 12:09pour ce qui est des distributions (archlinux ou autre), le noyau a le même but, même s'il est compilé pour des architectures différentes, il a néanmoins besoin de démarrer sur différents ordinateurs et est donc relativement modulaire avec un image initrd qui se charge de choisir quoi prendre en compte.
sur un msi wind sous arch, la recompilation du kernel fait gagner ~12 sec sur le démarrage.
par contre, pour ce qui concerne les services et ce qui est démarré par la suite, les distributions n'ont pas les mêmes politiques, une mandriva démarrera des services qu'un débutant ne saura pas retrouver, alors qu'une Archlinux ne démarrera presque rien (syslog + cron) au risque que le débutant ne retrouve pas telle ou telle fonction.
au passage, le script perl n'a pas grand chose à voir avec perl
- répondre
Ulhume, le 27 October, 2008 - 12:12@tuxce
Maintenant c'est à double tranchant car un débutant ne saura pas plus quel service ajouter pour un besoin fonctionnel précis 
Yep je suis d'accord d'où ma dénomination de distribution "spartiate"
Oups pour le script, l'ai oublié de commiter le bon
c'est mieux maintenant 
- répondre
Remy , le 27 October, 2008 - 12:14Merci Ulhume pour ce bel article, je vais tenter d'optimiser le noyau de ma ubuntu sur netbook eee701. Par rapport à la Xandros de base, c'est en effet beaucoup beaucoup plus lent au démarrage, mais c'est un moindre mal, vive la liberté
- répondre
scorpio810 , le 27 October, 2008 - 12:43"Une fois que l'on a le symbole responsable de la compilation ou non du module, il suffit d'ouvrir le fichier .config avec un éditeur de texte pour le localiser et ainsi comprendre où est-ce qu'il se trouve dans la configuration via menuconfig"
ou simplement en faisant une recherche avec / dans le menuconfig
- répondre
AP , le 27 October, 2008 - 13:57@scorpio810: Le "/" dans le menuconfig, c'est juste énorme. Le pire c'est que c'est noté noir sur blanc en haut de l'écran !
On a le nez dessus tout le temps et à force on n'y fait plus attention.
Question aux spécialistes ici présents : existe-t-il un script qui permet de "scripter" des configs de noyau. Je m'explique. Admettons que je veuille personnaliser un kernel quelconque dont j'ai la configuration (.config) sous la main. Je sais que, pour être conforme à ce que je cherche, il faut que telle ou telle option soit activée, que ce soit en module ou en dur. J'aimerais, plutôt qu'un coup de "make menuconfig" un script du genre :
modifieconfig --off CONFIG_STACKTRACE_SUPPORT --module CONFIG_ACPI_AC --on CONFIG_ACPI_EC --value CONFIG_ACPI_BLACKLIST_YEAR 0 .config
Ce script serait conscient des interdépendances et soit activerait tout seul les dépendances nécessaires à ce que je demande soit s'arrêterait en spécifiant qu'une intervention manuelle est nécessaire.
Ça existe, ça, quelque part ?
À quoi j'appliquerais cela ? Par exemple au fait d'adapter un noyau existant pour qu'il fonctionne de manière optimale sous VMware (activation de la carte réseau, des contrôleurs disque, des options processeur qui vont bien sans modifier le reste de la config). Cela-dit, pour VMware, le mieux est encore de partir d'une config par défaut et de la dépouiller jusqu'à ce qu'il ne reste que le strict nécessaire.
- répondre
eddy33 , le 27 October, 2008 - 14:31Salut.
Très bon article.
Oui en fait tu as raison. Quand le matériel ne bouge pas, autant personnaliser son noyau !
En fait, tu viens de reprendre la méthode que l'on applique quand on fait du Linux embarqué !
++
- répondre
Ulhume, le 27 October, 2008 - 14:52@scorpio Alors là oui bravo ! effectivement c'est énorme, je suis vert de ne pas avoir vu cela plus tôt.
Sinon pour ton besoin je n'ai pas de réponse, si ce n'est perl et un peu d'huile de coude
- répondre
Ulhume, le 27 October, 2008 - 14:53@eddy33 tu veux dire que je suis le M. Jourdain du kernel monolithique, c'est ça ?
))
- répondre
rodhia, le 27 October, 2008 - 19:14Super l'article sa va me servir pour mon netbook! Question Ulhume, toi qui est ma fois assez calé! MSI viens de sortir une nouvelle version du bios pour les wind. Cela rend possible un mode "turbo" qui permet de d'overcloker le processeu r le biais de Fn+F11 je crois. Est ce que cela fonctionnera sous linux, ou est ce qu'il faudra recompiler le kernel pour qu'il puisse gérer sa?
- répondre
Ulhume, le 27 October, 2008 - 19:20@rodhia c'est très difficile à dire, tout dépend si Fn+F11 est géré par le BIOS ou par un pilote Windows. Dans le cas de l'U810, certaines fonctions Fn sont directement prises en charge par le BIOS, d'autres ne font que générer un scancode qui est utilisé par le pilote Windows. Le mieux reste de tester.
- répondre
scorpio810 , le 27 October, 2008 - 20:05une bonne doc pour ceux qui veulent en apprendre d'avantage sur leur kernel
http://casteyde.christian.free.fr/system/linux/guide/online/a12863.html
- répondre
Dab, le 28 October, 2008 - 10:30Ulhume: Peut être devrais tu préciser que lors de la création d'un noyau monolitique, si l'on veut que celui-ci boot, le minimum requis est de décocher ‘Initial RAM filesystem ’ et d'embarquer au moins le controleur disque et le système de fichier qui va bien.
- répondre
Rodhia , le 28 October, 2008 - 13:03Je viens de flasher mon bios et l'option est bien reconnu pour ceux que sa intéressent!
- répondre
eddy33 , le 28 October, 2008 - 14:39@Ulhume
Oui !
Les bonnes recettes du passé sont toujours valables !
Bonne continuation
++
- répondre
Ulhume, le 28 October, 2008 - 21:47@Scorpio la doc est sympa mais mériterais un chouilla de présentation
- répondre
Ulhume, le 28 October, 2008 - 22:04@DAB yep tu as raison, j'ai ajouté un bloc pour ça.
- répondre
Ulhume, le 28 October, 2008 - 22:05@Rodhia cool
Dommage que je n'ai pas cela sur mon U810...
- répondre
Ulhume, le 28 October, 2008 - 22:06@scorpio re-re-re merci pour le coup du /, c'est vraiment trop pratique ce truc. Si en plus ça pouvait te transporter directement à la bonne section, se serait vraiment nickel !
- répondre
scorpio810 , le 29 October, 2008 - 04:15"Si en plus ça pouvait te transporter directement à la bonne section"
dans un futur proche qui sait
personnellement j'apprécie surtout le depends on , ainsi que sa location
exemple : http://forum.generation-debian.org/viewtopic.php?p=5120#p5120
Poster un nouveau commentaire