Accueil DexTER |
Projet DSPBook
télécharger au format PDF
De nombreux travaux sont en cours visant à accélérer le démarrage d'un système GNU/Linux. Certains ont déjà annoncés des résultats impressionnants avec une durée réduite à cinq secondes. Ces résultats ont été obtenus au prix d'optimisations parfois assez agressives, pas totalement divulguées ou dans le cadre de nouvelle distribution et restent difficilement applicables à un système existant. Avec un objectif plus modeste, nous présentons notre approche basée sur une configuration du noyaux et des services adaptée au matériel et à l'usage ciblé. Nous proposons aussi un système de parallélisation du démarrage des services qui s'appuie simplement sur GNU Make. Ces techniques ont été appliquées à des netbooks pour lesquels un démarrage rapide est un réel atout.
logiciel libre, linux, boot, développement industriel, accélération, optimisation
L'accélération du démarrage d'un système GNU/Linux fait l'objet actuellement de nombreux travaux. Certaines équipes ont déjà annoncé des résultats spectaculaires avec une durée ramenée à quelque cinq secondes. Cependant la majorité de ses méthodes sont assez agressives et reposent parfois sur une modification profonde du noyau lui-même. De plus malgré des démonstrations filmées prouvant la réalité des résultats, ils sont encore difficiles à reproduire car les modifications apportées n'ont pas souvent été publiées dans leur intégralité et il sera nécessaire d'attendre encore avant de voir leur intégration dans des distribution officielles.
Toutefois nous présentons dans ce document quelques actions plus ou moins aisées qui peuvent être menées pour réduire la durée du démarrage d'un système linux commun tel qu'on le trouve aujourd'hui par le biais des principales distributions. Ces actions, même si elles requièrent un minimum de connaissances, comme configurer et recompiler un noyau, restent assez faciles à intégrer. Pour parvenir à nos fin, nous avons développé nos recherches selon deux axes:
Si l'accélération d'une étape qui a lieu en générale une fois par jour pour un poste bureautique et beaucoup plus rarement pour un serveur peut sembler vaine, elle apportera un réel confort d'utilisation pour les PC Portables et tous les appareils intermédiaires entre le PC portable, l'agenda électronique ou le téléphone mais aussi pour des systèmes plus ou moins embarqués et spécialisés comme des settopbox. C'est pourquoi nous avons choisi de tester nos optimisations sur des netbooks. Ce sont des PC ultra portables, permettant d'effectuer toutes les tâches traditionnelles qu'un ordinateur portable "classique" fait. La puissance de calcul d'un netbook est moindre face à celle d'un portable classique, mais reste comparable à celle d'un PC moyen de gamme d'il y a cinq ans. Pour cette étude, nous avons utilisé trois netbooks différents:
La mise sous tension d'un ordinateur de type PC provoque l'activation de plusieurs systèmes qui se passent la main successivement jusqu'à être prêt à recevoir les requêtes de l'utilisateur :
Le BIOS ( Basic Input and Output System ) réside sur un circuit mémoire directement intégré au materiel qui est configuré par construction pour exécuter le programme qu'il contient avant toute chose. Sa première tâche est de contrôler la présence et la bonne marche des équipements matériels qui constituent l'ordinateur, il s'agit principalement d'un test de la mémoire, d'un inventaire des disques durs disponibles, et dans le cas courant d'un PC, faire l'inventaire des périphériques présents sur le bus PCI. Il recherche parmi les composants qu'il a découverts si certains embarquent un BIOS propre qui sera exécuté à son tour. Pour terminer, il va rechercher selon un ordre établi sur chaque périphérique de masse disponible la présence d'un programme d'amorçage (communément appelé bootloader). Dans le cas de linux les bootloader les plus courants sont LILO et Grub, ce dernier tend à remplacer de plus en plus le premier.
La plupart des distributions Linux actuelles, dont celles avec lesquelles nous avons travaillé utilisent Grub comme programme d'amorçage, c'est à dire un programme qui peut être chargé et exécuté depuis le BIOS afin de prendre en charge le démarrages de programme trop complexes pour pouvoir être activé directement par le BIOS. Le principal intérêt de Grub par rapport à ses concurrents est une grande souplesse de configuration. Par la simple édition d'un fichier ASCII, il est possible de décrire les caractéristiques de chaque système hébérgé sur les mémoires de masse disponibles. Ce fichier autorisera selon les options activées le choix du système à démarrer au travers d'un menu convivial. vu d'un système Linux démarré, ce fichier de configuration est accessible en général par le chemin /boot/grub/menu.lst. Chaque système pouvant être démarré y sera décrit par une section ressemblant à celle-ci :
title Debian GNU/Linux, kernel 2.6.28
root (hd0,6)
kernel /boot/vmlinuz-2.6.28 root=/dev/sda7 ro
initrd /boot/initrd.img-2.6.28
Selon les options de configuration, Grub montrera un menu qui liste chaque système présent et décrit comme montré ci-dessus. Lorsque l'utilisateur fait son choix, grub charge en mémoire le fichier du noyau correspondant à ce choix et déclenche son exécution.
Suite à son propre chargement, le noyau effectue également des initialisations qui consistent principalement à faire lui même un inventaire minimal des périphériques disponibles pour son propre fonctionnemen, c'est à dire essentiellement, le(s) processeur(s), la mémoire vive, les périphérique de masse. Ceci fait, sa seule tâche sera alors de démarrer un premier processus qui sera le père de tous les processus suivants jusqu'à l'arrêt du système. Dans le cas d'un système de type Unix ce processus souvent appelé init se chargera à son tour de poursuivre la procédure d'initialisation et de démarrage.
Le programme init "traditionnel" trouve ses instructions dans le fichier /etc/inittab qui décrit en détail les actions qu'il doit mener pour initialiser le système. Init a également la faculté de gérer un indice d'état du système appelé niveau d'exécution (ou runlevel) qui permet de gérer la phases transitoires de la vie du système comme le démarrage lui-même. Il permet également d'avoir plusieurs mode de fonctionnement (exclusif) pour un même système. Par convention les niveaux d'exécution disponibles par défaut ont été établi ainsi :
Dans beaucoup de distribution linux récente, la distinction entre les modes 2, 3, 4 et 5 tend à disparaître, et le mode de démarrage par défaut est 2 pour lequel l'interface graphique et le réseau sont actifs.
Le fichier /etc/inittab décrit les actions à mener à l'entrée de chaque niveau d'exécution, il est constitués de lignes elles mêmes constituées de quatre champs séparés par deux points :
Une ligne d'un type particulier (champ 3 = initdefault) et d'identifiant lui aussi réservé (champ 1 = id) indique le niveau d'exécution à atteindre.
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
Dans l'exemple qui précède, le fichier /etc/inittab commande à init d'atteindre le niveau 2 après avoir réalisée les commandes de l'état transitoire sysinit. On remarque que pour tous les niveaux, il est demandé de lancer la commande /etc/init.d/rc X où X est le niveau d'exécution. Le script /etc/init.d/rc propose un mécanisme particulier pour déterminer les services à démarrer selon les niveaux d'exécution d'origine et de destination qui repose sur les conventions suivante :
Le script rc consulte le répertoire de liens correspondant au niveau reçu dans son propre argument pour y exécuter dans l'ordre établie par les deux chiffres avec l'argument déterminé par le premier caractère de chaque lien. Ceci permet pour chaque niveau d'exécution de définir quels sont les services à démarrer, les services à arrêter et dans quel ordre il faut mener ces opérations.
En conclusion, la tâche principale d'init est de déléguer le séquençage des actions requise lors d'une transition de niveau d'exécution à un automate séquentiel dont le comportement est déterminé par l'ensemble des scripts et liens symboliques présents dans les répertoires /etc/rc*.d et /etc/init.d.
Chacune des étapes présentées au chapitre précédent peut recevoir son lot d'optimisation en vu d'accélérer le processus global. En effet ces étapes sont complètement séquentielles et relativement étanches, le seule dépendance étant qu'un échec total aboutissant au blocage de l'une d'entre elle empêchera la poursuite du processus. A l'inverse il n'y a pas de raison que la modification d'une étape ait un impact majeur sur les suivantes dès que toutes les tâches dont elle a la responsabilité ont été bien menées. Les possibilités d'action varient bien entendu selon les étapes :
Pendant nos expérimentations, nous avons été menés à redémarrer linux sur des systèmes de boot plus ou moins stables, ainsi par mesure de sécurité, nous avons créé un clone d'init légèrement modifié pour ne plus recevoir ses instructions du fichier/etc/inittab-finit, mais d'une copie de inittab que nous pourrons modifier sans problème. Cela nous permet de créer une entrée spécifique dans le menu grub pour démarrer notre noyau linux personnalisé en précisant également de démarrer comme premier processus la commande /sbin/finit à la place de /sbin/init, tout en conservant l'entrée relative au système d'origine. Cette capacité de choisir entre le processus de boot standard ou celui expérimental permet un retour au système d'origine pour continuer d'accéder à tous les fichiers de notre disque dans le cas où notre système expérimental n'est pas en mesure d'achever son démarrage.
La procédure suivie pour produire notre init alternatif est :
#define INITTAB "/etc/inittab"
par
#define INITTAB "/etc/inittab-finit"
title Debian GNU/Linux, kernel 2.6.28
root (hd0,6)
kernel /boot/vmlinuz-2.6.28 root=/dev/sda7 ro
initrd /boot/initrd.img-2.6.28
savedefaulttitle Fast boot
root (hd0,6)
kernel /boot/vmlinuz-2.6.28 root=/dev/sda7 ro init=/sbin/finit
initrd /boot/initrd.img-2.6.28
savedefault
Comme nous l'avons rapidement évoqué précédemment, les noyaux des distributions généralistes doivent pouvoir affronter toutes les situations pour mener leur démarrage à terme. Cela est particulièrement épineux quand un pilote particulier est requis pour accéder à la racine du système de fichier. Pour surmonter cette difficulté, il est possible de préciser dans la configuration du bootloader (cf paramètre initrd dans le fichier de configuration de grub), qu'une image de système de fichier racine minimale est disponible. Cette image contiendra le minimum vital pour le bon démarrage du système en toute circonstance, c'est à dire essentiellement l'ensemble des pilotes de périphériques. Pendant son chargement, le noyau monte le système de fichier contenu dans cette image en tant que racine temporaire qui lui donne accès à tout ce dont il a besoin pour réaliser sont démarrage jusqu'à être en mesure de remplace ce système de fichier racine temporaire par le système de fichier racine définitif. Au bout du compte, ce mécanisme consomme obligatoirement du temps supplémentaire et n'a que peut d'intérêt dans un environnement où la configuration est maitrisée et stable. Cela apporte seulement le confort de ne pas avoir à configurer ni compiler quoi que ce soit lors d'une installation d'un nouveau système (ce qui reste vital pour rendre GNU/Linux accessible au plus grand nombre).
En fait, la plupart des pilotes de périphérique peuvent se présenter sous deux formes :
Inclure les pilotes des périphérique de la plateforme ciblée accélère le démarrage par ces deux effets :
En pratique, on ne pourra pas toujours inclure dans le noyau, tous les pilotes correspondant au matériel "fixe" de l'ordinateur car cela produirait une image amorçable de noyau trop volumineuse pour pouvoir démarrer correctement (Vérifier que cette affirmation est toujours vraie pour les noyaux et les bootloader récents)
La première chose à faire est de se procurer les sources d'un noyau linux. Le site Kernel.org publie les sources officiels maintenus par Linus Torvalds et en archive toutes les versions. Lors de l'écriture de cette note, la dernière version est la 2.6.28.4. Attention les sources sont publiés sous deux forme :
On prendra donc soin lors d'un premier téléchargement de choisir une archive complète. Une fois l'archive décompressée, se rendre dans son répertoire racine et utiliser la commande make menuconfig pour accéder à un menu de configuration relativement convivial qui permet de choisir tous les options et le mode de compilation des pilotes qui présente trois possibilité :
On utilisera également ce menu pour donner un suffix personnel à notre noyau ce qui évitera d'écraser le noyau éventuellement déjà présent dans la même version sur notre poste de travail.
A l'issue de l'utilisation du menu de configuration, il est créé un fichier .config (attention, selon les conventions unix, c'est un fichier caché) qu'on pourra sauvegarder pour une utilisation future et dont on pourra aussi contrôler et affiner le contenu. Chaque option présentée dans le menu de configuration y est retranscrite par une ligne :
Toute nos plateformes de test ont une architecture relativement identique, à base de processeur Pentium M ou de processeur Atom, accompagné du chipset intel (i914 ou i945) et d'un contrôleur de disque SATA. Nous avons par conséquent ajusté les options de compilation selon ces paramètres en particulier pour inclure les pilotes pour les puces intel, pour les périphérique SATA et le système de fichier de nos distribution linux, à savoir ext3. Le boot sans initrd sera donc possible si les options suivantes on pour valeur "y" dans le fichier .config : CONFIG_BLK_DEV_IDE_SATA, CONFIG_SCSI, CONFIG_BLK_DEV_SD, CONFIG_SCSI_SAS_ATA, CONFIG_ATA, CONFIG_ATA_PIIX, CONFIG_EXT3_FS. Les pilotes SCSI sont inclus car l'architecture de pilote SATA de Linux consiste à les présenter de la même manière que des périphériques SCSI.
Une fois la configuration établie, nous pouvons accomplir la compilation du noyau :
make
make modules
make install
make modules_install
Attention pour effectuer les deux dernières commandes, il est nécessaire de posséder les droits administrateur (cf. commande sudo).
On vérifiera que le noyau et ses modules ont bien été installés par une vérification du contenu des répertoires /boot et /lib/modules. On terminera par ajuster si besoin la configuration de grub (fichier /boot/grub/menu.lst) pour prendre en compte ce nouveau noyau :
title Noyau experimental Dexter sans initrd
root (hd0,6)
kernel /boot/vmlinuz-2.6.28.4-dexter init=/sbin/finit root=/dev/sda1 ro
savedefault
Selon la distribution GNU/Linux de base choisie pour ces expérience, ceci ne sera peut être pas suffisant pour charger correctement le noyau et relayer le démarrage au programme init tel que nous l'avons modifié. Il pourra être nécessaire de procéder un ajustement du contenu de /dev tel que cela est exposé au paragraphe suivant.
Sous Unix, tout est fichier (ou presque), ainsi tous les périphériques sont présentés sous la forme d'un ou plusieurs pseudo fichiers hébergés dans le /dev. Le travail d'un pilote consiste en fait à traduire les opérations de lecture et écriture classiques sur ces fichiers en ordres compréhensibles par le matériel qu'il prend en charge. Auparavant tout le contenu de /dev était établi une bonne fois pour toute, et on y trouvait une multitude de fichiers pour tous les périphériques potentiellement pris en charge par le noyau. Maintenant, le démon udev propose une gestion dynamique de son contenu pour ajouter et créer les entrée de /dev au fur et à mesure de l'apparition ou de la disparition des périphériques. Cependant nous avons besoin d'un minimum de chose avant l'activation de udev lui même, en particulier pour pouvoir accéder au premier disque de boot qui contient en générale le système de fichier racine.
Le plus simple consiste à relever les entrées correspondant à ce disque et ses partitions directement depuis le système de base avant de le redémarrer pour tester notre noyau personnalisé. On pourra s'aider de la commande fdisk -l pour les identifier : tous les disques présents et les partitions associées vont apparaitre à l'écran avec leurs noms. Conventionnellement, le premier disque est appelé sda et ses partitions sda1 sda2 ... Le deuxième disque sdb et ses partitions sdb1 sdb2... Rendez-vous maintenant dans /dev/ et regardons son contenu (commandes ls -l). Nous retrouvons des fichiers se nommant sda, sda1, sdb, sdb1, etc, et observons les informations importantes sur une ligne :
brw-rw---- 1 root disk 8, 0 2009-02-10 11:07 sda
Mais comment créer ces entrée si elle sont déjà présente ? Comme nous il a été dit plus haut, le contenu de /dev est maintenant géré par le démon udev et rien ne dit que les fichiers sont déjà présents avant l'activation de udev. Nous avons besoin d'accéder au répertoire /dev/ de la partition racine sans que udev n'y soit actif. Pour cela il y a deux possibilité :
Utiliser la commande mount pour accéder à la partition puis ajuster si besoin le contenue du répertoire dev qu'elle contient avec la commande mknod :
mknod -m <droit sur le fichier> <nom du fichier> <type de périphérique> <numéro majeur> <numéro mineur>
mknod -m 0660 sda b 8 0
Cette commande va donc créer l'entrée sda de type block avec 8 comme numéro majeur et 0 comme mineur. Il est évident qu'il faut adapter les paramètres à sa configuration. Pour créer sda1 il suffit de modifier le nom et de mettre 1 à la place de 0. Ainsi de suite jusqu'a sda9. Une dernière manipulation est à faire, il faut mettre toutes les entrées créées dans le groupe disk en utilisant la commande suivante :
chgrp <nom du groupe> <nom du fichier>*
C'est à dire, dans notre cas : chgrp disk sda*.
Après un démontage propre de la partition (voir commande umount), le système et prêt pour l'étape suivante.
Pour comprendre la suite, des connaissances de base en ce qui concerne la syntaxe et l'utilisation de Make sont nécessaire. Make est un outil permettant l'exécution automatique d'une séquence de tâche dont la nécessité et l'ordre sont déterminé par des règles de dépendance. Si cet outil a été inventé par des programmeurs pour des programmeurs, rien ne le restreint à son principal emploi qui est la compilation de logiciels. Il peut être employé pour toute autre tâche à partir du moment où elle repose sur une séquence de commande avec des contraintes d'enchaînement. Nous l'employons d'ailleurs également pour automatiser la mise en forme de la présent documentation.
Lorsque nous avons brièvement abordé le processus de démarrage par init dans un paragraphe précédent, nous avons vu qu'il s'agit essentiellement d'exécuter dans un ordre précis des scripts hébergés dans /etc/init.d. Ceci est justement une tâche pour laquelle make a été conçue. Mais qu'en est-il de la parallélisation ? Il s'avère que GNUMake, qui est la déclinaison GNU du make présente par défaut sur la plupart des systèmes Linux, possède une option très intéressante lui donnant la capacité de piloter en parallèle de lancement des commandes tout en préservant les dépendances. C'est à dire qu'une tâche particulière ne sera démarrée que si toutes les tâches dont elle dépend ont été complètement réalisées avec succès. Il suffit donc d'établir le bon Makefile, c'est à dire rédiger dans la syntaxe make, la liste des dépendances entre les services et indiquer pour chaque niveau d'exécution quels sont les services "finaux" à démarrer. C'est à dire, les services qui doivent être actifs mais donc aucun autre service ne dépend.
Dans un makefile, le travail a réaliser est décrit par un ensemble de règles qui définissent les actions à mener pour réaliser une cible tout en précisant les prérequis. Nous allons d'abord rédiger un premier Makefile principal que nous nommerons /etc/init.make et qui sera invoqué par init via le fichier /etc/inittab-finit qui recueillera un ensemble de règles génériques. Un deuxième makefile précisera de son coté quels sont les services finaux attendus pour chaque niveau d'exécution et les dépendances entre services.
DIR=/var/finit
all: dolevel$(LEVEL)
@ echo "Level $(LEVEL) initializations done."
%.s: /etc/init.d/%
@ $< start 2>&1 | tee $(DIR)/$@.log
%.s: /etc/init.d/%.sh
@ $< start 2>&1 | tee $(DIR)/$@.log
%.k: /etc/init.d/%
@ $< stop 2>&1 | tee $(DIR)/$@.log
%.k: /etc/init.d/%.sh
@ $< stop 2>&1 | tee $(DIR)/$@.log
mod.%:
@ modprobe $(patsubst mod.%,%,$@)
include /etc/init.d/rules.make
Le makefile contenant les règles de dépendance suit le principe générale de fonctionnement de make. Pour réaliser les traitements commandés par une règle, il faut d'abord que toutes les dépendances soit satisfaites, c'est à dire que toutes les cibles mentionnées dans la partie droite de la règle soient atteintes. Par contre cela n'impose rien sur l'ordre de traiter les multiples cibles qui son regroupées en tant que dépendance d'une unique règle, et, si la commande make utilisée le permet, rien n'empêche de les traiter en parallèle. Ce qui est le cas pour la version GNU de make.
Supposons que nous ayons quatre services à démarrer : serv0, servA, servB et serv9. Les services servA et servB doivent attendre que serv0 soit démarré pour s'initialiser à leur tour. De son coté serv9 doit attendre que servA et servB soient tous les deux démarrés. On traduira ces contraintes dans la syntaxe make en s'appuyant sur les règles génériques exposées au paragraphe précédents ainsi :
dolevel2: serv9
servA.s: serv0.s
servB.s: serv0.s
serv9.s: servA.s servB.s
La première règle précise simplement que l'entrée dans le niveau d'exécution 2 demande le démarrage de serv9, comme lui même, par application de la dernière règle, requière que d'autres services soient démarrés. Par application transitives des règles, tous les services mentionnés dans cet exemple seront démarrés avec le respect des contraintes exposées plus haut.
On pourra éventuellement si on le souhaite conserver en parti l'ancien système de démarrage Unix system V. Lors de nos expérimentation nous n'avons pas souhaiter perturber l'arrêt ni le reboot du système. Nous avons donc simplement renvoyé le traitement des niveaux d'exécution 0 et 6 vers le script qui s'en charge à l'origine :
dolevel0:
/etc/rc.d/rc 0
dolevel6:
/etc/rc.d/rc 6
Il reste maintenant à relier nos makefile à init pour que la commande make soit correctement invoquée à chaque transition de niveau d'exécution :
# Le niveau d'exécution par défaut
id:5:initdefault:
# Initialisations préliminaires
si::sysinit:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=SI
# Pour chaque niveau d'execution, appliquer les règles...
l0:0:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=0
l1:1:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=1
l2:2:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=2
l3:3:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=3
l4:4:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=4
l5:5:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=5
l6:6:wait:/usr/bin/make -j -r -i -f /etc/init.make LEVEL=6
# quelques consoles textes sont toujours utiles
1:12345:respawn:/sbin/getty 38400 tty1
2:2345:respawn:/sbin/getty 38400 tty2
3:2345:respawn:/sbin/getty 38400 tty3
4:2345:respawn:/sbin/getty 38400 tty4
Pour chaque niveau d'exécution la même commande make est invoquée, la variable LEVEL précisant la valeur du niveau à prendre en compte. Quelques options supplémentaires ont été utilisées :
On pourra également conserver quelques entrées issues d'un fichier inittab pour conserver la faculté de redémarrer le système par la combinaison CTRL-ALT-SUPPR ou tout autre définition qui n'est pas directement liée au processus normal de démarrage et d'arrêt du système.
Configurations testées avec la distribution eeebuntu :
Les optimisations incluent une configuration et compilation du noyau afin de ne plus utiliser d'image de démarrage initrd ainsi que la sélection et la parallélisation des services par GNUMake. Ces deux axes ont été suffisants pour réduire la durée de démarrage de plus de sa moitié ce qui représente déjà un gain confortable et appréciable au quotidien sans avoir eu besoin de recourir à des modifications profondes de la distribution utilisée comme base de départ. Il est donc relativement aisé d'améliorer la durée de démarrage de la plupart des distributions GNU/Linux actuelles. Il subsiste encore quelques anomalies qui ne permettent pas encore l'application sur un système en production.
Les contraintes de démarrages des services udev, dbus et hal n'ont pas encore été suffisamment bien cernées et nous sommes confrontés au dilemme de devoir soit augmenter considérablement la durée du démarrage, soit nous contenter de fonctionnalités limitées de ces services, c'est à dire qu'en l'état actuel, certains aspect dynamiques de la gestion du matériel ne sont pas opérationnels. La principale lacune étant que le montage et l'ouverture automatique des périphériques de masse USB ne fonctionnent pas.
L'affichage pendant le démarrage est très chaotique puisque nous avons volontairement supprimé tout affichage graphique de barre de progression et les comptes rendus textuels du démarrage des services sont illisibles. Ils sont imbriqués et mélangés en raison de la parallélisation des démarrages ce qui entraine des écritures simultanées sur la console par plusieurs programmes.
Enfin, le gain de performance général même s'il est très significatif, n'est pas au niveau de ce qui a été réalisé par d'autres et nous sommes encore assez loin des quelques cinq secondes qui semble être le meilleur résultat atteignable à ce jour pour un système assez complet pour une utilisation de type bureautique.
Copyright (c) detexia 2009, mis à jour le : mardi 2 mars 2010, 14:56:53 (UTC+0100)