Tribune Libre
Ténors de l'Informatique Libre
Copyright © 1999 par Éditions O'Reilly
Chapitre 7. Linux à la pointe du progrès
Linus Torvalds
- Le portage sur Amiga et Motorola
- Micro-noyaux
- De l'Alpha à la portabilité
- Espace noyau et espace utilisateur
- GCC
- Modules noyau
- La portabilité aujourd'hui
- L'avenir de Linux
Linux, aujourd'hui, compte des millions d'utilisateurs, des milliers de
développeurs, et sa part de marché augmente. Il est utilisé dans des
systèmes embarqués et pour contrôler des robots, il a voyagé
à bord de la navette spatiale. Je voudrais pouvoir dire que je l'avais prévu,
que cela s'inscrivait dans un projet de domination du monde, mais à vrai dire j'ai
été un peu surpris. Le passage du nombre d'utilisateurs de Linux de un
à cent m'est apparu beaucoup plus nettement que la transition entre ces derniers et
le million suivant.
La réussite de Linux ne dépend pas d'une disposition préalable
visant à le rendre portable et répandu mais plutôt de
l'efficacité des principes gouvernant sa conception et son mode de
développement. Ces fondations solides ont permis d'obtenir plus facilement
portabilité et disponibilité.
Comparons Linux aux projets commercialement soutenus, par exemple Java ou MS-Windows
NT. L'engouement créé par Java a convaincu beaucoup de personnes que write once, run anywhere (écrivez une fois,
exécutez partout) vaut quelques sacrifices. Nous entrons dans une période
où un nombre croissant de matériels informatiques différents seront
utilisés, il s'agit donc bien d'un concept important. Sun n'a cependant pas
inventé cette notion de "write once, run anywhere". La portabilité est depuis
longtemps le saint Graal de l'industrie informatique. Microsoft, par exemple, a d'abord
espéré que MS-Windows NT devienne un système d'exploitation portable
pouvant fonctionner sur les machines Intel mais aussi sur les processeurs RISC, courants
dans les stations de travail. Linux n'a jamais eu un objectif si ambitieux. C'est donc une
ironie du sort que Linux soit devenu une plate-forme efficace à ce titre.
Linux a tout d'abord été conçu pour une seule architecture :
l'Intel 386. Il fonctionne aujourd'hui sur tout type de machine, du PalmPilot à la
station Alpha ; il s'agit du système d'exploitation porté sur le plus grand
nombre d'architectures disponible sur PC. Si vous écrivez un programme pour Linux,
il pourra être "write once, run anywhere" pour un grand nombre de machines
différentes. Il est intéressant d'observer les décisions prises lors
de la conception de Linux et la manière dont son développement a
évolué afin de voir comment il a réussi à se transformer en
quelque chose qui n'était pas du tout prévu à l'origine.
Linux est un système d'exploitation de type Unix, mais il ne s'agit pas
d'une version d'Unix, ce qui lui confère un héritage différent de,
par exemple, celui de FreeBSD. Les créateurs de ce dernier ont
débuté avec le code source de Berkeley Unix et leur noyau en est
directement issu. Il s'agit donc d'une version d'Unix, dans la lignée directe de
ses prédécesseurs. Linux, en revanche, a pour but de fournir une interface
compatible avec Unix, mais le noyau a été complètement
réécrit, sans aucune référence au code source d'Unix. Ainsi,
Linux n'est pas un port d'Unix, mais un nouveau système d'exploitation.
Je n'avais vraiment pas l'intention, au début, de porter ce nouveau
système d'exploitation sur d'autres plates-formes. En premier lieu, je voulais
obtenir quelque chose qui fonctionne sur mon 386.
Le premier effort de taille fait pour rendre le code du noyau de Linux portable a
eu lieu afin de commencer son port sur les machines Alpha de DEC. Il ne s'agissait
toutefois pas du premier port.
Le premier port a été réalisé par une équipe qui
rendit disponible le noyau Linux sur la famille Motorola 68000 (puce présente dans
les premiers ordinateurs Sun, Apple et Amiga). Les programmeurs responsables voulaient
vraiment faire quelque chose de bas niveau et en Europe, beaucoup de personnes dans la
communauté Amiga étaient particulièrement rétives à
MS-DOS ou MS-Windows.
Même si la communauté Amiga a réussi à obtenir un
système fonctionnant sur les 68000, je ne considère pas vraiment qu'il
s'agisse d'un port réussi de Linux. Ils ont pris le même style d'approche
que celle que j'avais adoptée lorsque j'ai commencé à écrire
Linux ; écrire, sans aucune référence, un code destiné
à assurer un certain type d'interface. Ainsi, ce premier port pour 68000 pouvait
être considéré comme un système d'exploitation ressemblant
à Linux, un embranchement du code d'origine.
De ce point de vue, ce premier port 68000 de Linux n'a pas aidé à
créer un Linux portable, mais il y contribua d'une autre manière. Quand
j'ai commencé à penser au port pour Alpha, j'ai dû étudier
l'expérience du port 68000. Si nous prenions la même approche avec les
Alpha, j'aurais alors à maintenir trois codes de base différents.
Même si cela aurait été possible au niveau de la programmation, ce
n'était pas gérable. Je ne pouvais veiller au développement de Linux
s'il fallait pour cela maintenir une nouvelle base de code chaque fois que quelqu'un
voulait Linux sur une nouvelle architecture. À la place, je voulais faire un
système où j'aurais une branche spécifique pour les Alpha, une autre
pour les 68000 et une troisième pour les x86, toutes articulées autour
d'une base de code commune.
C'est pourquoi il y eut une réécriture importante du noyau à
cette époque, qui fut aussi motivée par la volonté de permettre
à un nombre croissant de développeurs de travailler de concert.
Quand j'ai commencé à écrire le noyau de Linux une
théorie arrêtée définissait la manière d'écrire un
système portable. Tout le monde préconisait d'utiliser une architecture
fondée sur les micro-noyaux.
Dans les noyaux monolithiques, par exemple celui de Linux, la mémoire est
divisée entre l'espace utilisateur et l'espace noyau. L'espace noyau est l'endroit
où le code réel du noyau réside après son chargement, et
où la mémoire est allouée pour les opérations qui prennent
place à son niveau. Ces opérations incluent l'ordonnancement, la gestion des
processus et des signaux, des entrées/sorties assurées par les
périphériques, de la mémoire et de la pagination. Ce sont autant
d'opérations de base requises par les autres programmes. Le code du noyau assure les
interactions de bas niveau avec le matériel, les noyaux monolithiques semblent
spécifiques à une architecture donnée.
Un micro-noyau effectue un nombre bien plus restreint d'opérations, et sous
une forme plus limitée : la communication entre processus, une gestion
limitée des processus et de l'ordonnancement ainsi qu'une partie des
entrées/sorties de bas niveau. Ainsi, les micro-noyaux se révèlent
être moins spécifiques au matériel car un grand nombre des
particularités du système sont placées dans l'espace utilisateur. Une
architecture à micro-noyau est en quelque sorte une manière de
s'éloigner des détails du contrôle des processus, de l'allocation
mémoire et de celle des ressources, afin que le port vers un autre matériel
ne requière que des changements minimes.
Ainsi, au moment où j'ai commencé à travailler sur Linux, en
1991, on supposait que la portabilité devait découler d'une approche de type
micro-noyau. Elle constituait alors la marotte des chercheurs en informatique
théorique. Cependant, je suis pragmatique et pensais alors que les micro-noyaux
-
étaient expérimentaux,
-
étaient manifestement plus complexes que les noyaux monolithiques
-
avaient une vitesse d'exécution bien inférieure à celle des noyaux
monolitiques.
La rapidité importe beaucoup dans la réalité, c'est pourquoi on
dépensait beaucoup d'argent dans le domaine de la recherche sur les optimisations pour
micro-noyaux afin qu'ils puissent fonctionner aussi rapidement que leurs pendants plus
classiques. Une des choses amusantes à la lecture de ces articles est qu'on
s'apercevait que bien que les chercheurs appliquent leurs astuces d'optimisation sur des
micro-noyaux, on pouvait aussi facilement utiliser ces dernières sur des noyaux
traditionnels pour les accélérer.
En fait, cela m'a amené à estimer que l'approche fondée sur des
micro-noyaux était fondamentalement malhonnête car destinée à
obtenir davantage de subsides pour la recherche. Je ne pense pas nécessairement que
ces chercheurs étaient consciemment malhonnêtes. Peut-être
étaient-ils tout simplement stupides, ou induits en erreur. Je le dis dans son sens
premier : la malhonnêteté vient de la forte pression qui s'exerçait
à ce moment précis à l'intérieur de la communauté
scientifique pour favoriser l'étude des micro-noyaux. Dans un laboratoire
d'informatique, vous étudiiez les micro-noyaux ou bien vous n'étudiiez pas du
tout les noyaux. Ainsi, tout le monde, y compris les concepteurs de MS-Windows NT,
était embarqué dans cette approche malhonnête. Alors même que
cette équipe savait que le résultat final ne ressemblerait en rien à
un micro-noyau, elle était consciente qu'elle devait lui rendre des hommages peu
sincères.
Heureusement, je n'ai jamais subi de réelle pression pour aller vers les
micro-noyaux. Les chercheurs de l'université d'Helsinki étudiaient les
systèmes d'exploitation depuis la fin des années 1960 et ne trouvaient plus
grand intérêt dans la recherche sur les noyaux. Dans un sens, ils avaient
raison : les bases des systèmes d'exploitation, et par extension du noyau Linux,
étaient bien comprises au début des années 1970 ; tout ce qui a
été fait ensuite n'a été, d'une certaine manière, qu'un
exercice d'auto-satisfaction.
Si vous voulez rendre un code portable, vous n'avez pas nécessairement besoin
de créer un niveau d'abstraction pour assurer la portabilité. Vous pouvez
aussi programmer intelligemment. Essayer de rendre les micro-noyaux portables est par
essence une perte de temps, cela revient à construire une voiture exceptionnellement
rapide équipée de pneus carrés. L'idée de s'abstraire de la
partie qui doit être ultra rapide — le noyau — est de façon
inhérente contre-productive.
Bien entendu, dans la recherche sur les micro-noyaux, il y a plus que cela. Mais la
partie cruciale du problème est la différence d'objectifs. Le but de la
majeure partie de la recherche sur les micro-noyaux était de concevoir un
idéal théorique, de définir un mode de conception aussi portable que
possible sur toutes les architectures imaginables. Je ne caressais pas, avec Linux,
d'objectif aussi noble. J'étais intéressé par la portabilité
entre des systèmes réels et non théoriques.
Le portage Alpha a débuté en 1993 et dura environ un an. Il
n'était pas complètement achevé au bout d'un an, mais toutes les bases
s'y trouvaient. Alors que ce premier port était difficile, il a établi
quelques principes de conception gouvernant Linux depuis, qui ont rendu les autres portages
plus simples.
Le noyau Linux n'est pas écrit pour être portable sur toute
architecture. J'ai décidé que si une architecture était suffisamment
saine et satisfaisait certaines règles simples, alors Linux devrait pouvoir y
être adapté sans problème majeur. Par exemple, la gestion de la
mémoire peut être très différente d'une machine à
l'autre. J'ai lu des documents décrivant la gestion de la mémoire des 68000,
Sparc, Alpha et PowerPC et trouvé, malgré des différences dans les
détails, qu'il y avait beaucoup de points communs dans l'utilisation de la
pagination, du cache etc. Il suffisait que la gestion de la mémoire du noyau Linux
soit écrite sur la base du dénominateur commun de toutes ces architectures
pour qu'il ne soit ensuite pas trop difficile de modifier ce code pour régler les
détails propres à une architecture particulière.
Quelques suppositions simplifient beaucoup le problème des ports. Si, par
exemple, vous déclarez qu'un microprocesseur doit pouvoir utiliser la pagination il
doit disposer d'une sorte de table de traduction (en anglais Translation Lookup Buffer ou TLB), qui lui
dit à quoi correspond la mémoire virtuelle. Bien entendu, vous ne pouvez
savoir quelle sera la forme de la TLB. Mais en fait, les seules choses que vous devez
connaître sont les méthodes pour la remplir et pour la purger lorsque vous
décidez que vous n'en avez plus besoin. Ainsi, dans cette architecture bien
pensée, vous savez que vous aurez besoin de placer dans le noyau quelques parties
spécifiques à la machine, mais que le plus gros du code exploite des
mécanismes généraux sur lesquels reposent des choses comme la
TLB.
Une autre règle que j'applique est qu'il est toujours préférable
d'utiliser une constante de compilation plutôt qu'une variable et, en utilisant cette
règle, le compilateur fait souvent une bien meilleure optimisation du code. Il est
évident que c'est plus sage, car vous pouvez écrire votre code afin qu'il
soit défini de façon facile à adapter et à optimiser.
Ce qu'il y a d'intéressant dans cette approche — essayer de
définir une architecture commune bien pensée — est que, ce faisant,
vous pouvez présenter au système d'exploitation une architecture meilleure
que celle qu'offre le matériel. Cela semble aller à l'encontre de toute
intuition, mais c'est important. Les généralisations que vous cherchez en
résumant les systèmes sont souvent les mêmes que les optimisations que
vous voudriez faire pour améliorer les performances du noyau.
En fait, quand vous faites un résumé suffisamment important de
problèmes comme la mise en œuvre des tables de pagination et quand vous prenez
une décision fondée sur vos observations — par exemple, le fait que
l'arbre de pagination doit être seulement de profondeur trois —, vous vous
apercevez plus tard que c'était la seule approche raisonnable pour obtenir de bonnes
performances. En d'autres termes, si vous ne vous étiez pas intéressé
à la portabilité en tant que critère de conception, mais aviez
simplement essayé d'optimiser le noyau sur une architecture donnée, vous
auriez souvent atteint la même conclusion — c'est-à-dire que la
profondeur optimale pour représenter l'arbre de pagination au niveau du noyau est
trois.
Cela ne procède pas seulement du hasard. Quand une architecture diffère
par certains détails d'une conception générale fonctionnelle, c'est
souvent parce qu'elle est mal conçue. Ainsi, les mêmes raisons qui vous font
passer outre les particularités de conception à des fins de
portabilité vous obligent aussi à contourner les défauts de conception
tout en préservant une conception générale plus optimisée. J'ai
essayé d'atteindre le juste milieu en combinant le meilleur de la théorie
avec la réalité des architectures actuelles.
Avec un noyau monolithique comme celui de Linux, il est important de faire
très attention lors de l'introduction de nouveau code et de nouvelles
fonctionnalités. Ces décisions peuvent ensuite affecter de nombreuses choses
dans le cycle de développement, au delà du noyau lui-même.
La première règle simple est d'éviter les interfaces. Si
quelqu'un veut ajouter quelque chose qui implique une nouvelle interface système,
vous devez être exceptionnellement attentif. Dès lors que vous fournissez une
interface aux utilisateurs, ils vont commencer à l'utiliser et lorsque quelqu'un
aura commencé à coder par dessus cette interface, vous ne pourrez plus vous
en débarrasser. Voulez-vous maintenir exactement la même interface pour le
reste de la vie de votre système ?
Le reste du code n'est pas si problématique. S'il n'a pas d'interface, par
exemple un pilote de disque, alors il n'y a pas besoin d'y réfléchir
longtemps ; vous pouvez sans grand risque l'ajouter simplement. Si Linux n'avait pas ce
pilote auparavant, l'ajouter ne gênera pas les utilisateurs antérieurs, et
cela l'ouvre à de nouveaux utilisateurs.
Quand la question se pose sur d'autres plans, vous devez faire des compromis. Est-ce
une bonne implémentation ? Est-ce que cela ajoute vraiment une intéressante
fonctionnalité ? Parfois, même si la fonctionnalité est bonne, il se
trouve que soit l'interface est mauvaise, soit l'implémentation est telle que vous
ne pourrez jamais faire autre chose, maintenant ou plus tard.
Par exemple — bien que ce soit en quelque sorte une question d'interface
— supposez que quelqu'un a une implémentation stupide d'un système de
fichiers où les noms ne peuvent pas avoir plus de 14 caractères. Ce que vous
voulez vraiment éviter est d'avoir, pour une interface, ces limitations
gravées dans le marbre. Sinon, lorsque vous voudrez étendre le système
de fichiers, vous serez foutu car devrez trouver une manière de rester dans cette
petite interface jusqu'alors figée. Pire que cela, tout programme qui demande un nom
de fichier peut avoir réservé (par exemple) 13 caractères pour une
variable et ainsi, si vous passez un nom de fichier plus long, vous le planterez.
À présent, le seul éditeur qui fasse une chose aussi stupide est
Microsoft. En simplifiant, pour lire des fichiers MS-DOS/MS-Windows, vous avez cette
ridicule interface où les noms de fichiers comptent onze caractères, huit
plus trois. Avec NT, qui a permis les noms longs, ils ont dû ajouter un ensemble
complet de nouvelles routines pour faire la même chose que les anciennes, sauf que
cet ensemble pouvait aussi prendre en compte de plus grands noms de fichiers. Cela
constitue par là-même un exemple d'interface incorrecte car gênante lors
des travaux ultérieurs.
Un autre exemple de cette situation est donné dans le système
d'exploitation Plan 9. Ils avaient cet appel système vraiment pratique pour faire
une meilleure duplication des processus. En deux mots, ce nouveau fork, appelé par
Plan 9 R-Fork (et que SGI a appelé plus tard S-Proc) crée deux espaces
d'exécution distincts partageant le même espace d'adressage. Cela facilite en
particulier le threading.
Linux permet aussi cela avec son appel système « clone », mais il a
été implémenté de façon correcte. Les concepteurs des
routines SGI et Plan9 ont décidé que les programmes ayant deux branchements
pouvaient partager le même espace d'adressage, mais séparèrent leurs
piles. Normalement, lorsque vous utilisez la même adresse dans les deux threads, vous
obtenez la même position mémoire. Mais le segment de pile est
spécifique de sorte que si vous utilisez une adresse mémoire de la pile, vous
obtenez en fait deux positions mémoires différentes, qui peuvent partager un
pointeur de pile sans écraser l'autre pile. <-- incohérent (?) -->
Ce comportement est astucieux, mais a son revers : le surcoût de la maintenance
des piles le rend, en pratique, vraiment inadéquat. Ils se sont aussi aperçus
trop tard que les performances s'avèrent catastrophiques. Comme des programmes
utilisaient cette interface, il n'y avait plus moyen de la modifier. Il leur a fallu
introduire une interface supplémentaire, correctement écrite, de façon
à utiliser l'espace de pile d'une façon raisonnable.
Un éditeur commercial peut de temps en temps essayer de faire passer le
défaut de conception dans l'architecture mais Linux n'offre pas ce recours.
La gestion du développement de Linux et la prise de décisions de
conception imposent la même approche. D'un point de vue pratique, je ne pouvais
gérer le fait que de nombreuses personnes fournissent des interfaces au noyau. Je
n'aurais pas été capable d'en garder le contrôle. Mais du point de vue
conception, c'était aussi ce qu'il fallait faire : garder le noyau relativement
petit et maintenir au minimum le nombre des interfaces et des autres contraintes
imposées au développement futur.
Bien entendu, Linux n'est pas complètement « propre » de ce point
de vue. Il a hérité des versions précédentes d'Unix un certain
nombre d'interfaces affreuses. Ainsi, dans certains cas, j'aurais été bien
plus heureux de ne pas avoir à maintenir la même interface qu'Unix. Mais Linux
est à peu près aussi propre que peut l'être un système sans
repartir complètement de zéro. Et si vous voulez profiter de la
possibilité de faire fonctionner des applications Unix, il faut bien en accepter
certaines lourdeurs. La possibilité de faire fonctionner ces applications a
joué un rôle primordial dans la popularité de Linux, le jeu en valait
donc la chandelle.
Unix lui-même est une belle histoire à succès en ce qui concerne
la portabilité. Le noyau Unix, comme de nombreux noyaux, repose sur l'existence du C
pour lui donner la plus grande partie de sa portabilité, à l'instar de Linux.
La disponibilité de compilateurs C sur de nombreuses architectures a permis d'y
porter Unix.
Unix montre donc bien l'importance des compilateurs. C'est l'une des raisons pour
lesquelles j'ai choisi de placer Linux sous GPL (GNU Public License). Elle protège
aussi le compilateur GCC. Je pense que tous les autres programmes du projet GNU sont, du
point de vue de Linux, insignifiants en comparaison. GCC est le seul dont je me
préoccupe vraiment et j'en déteste un certain nombre ; l'éditeur
Emacs, par exemple, est horrible. Bien que Linux occupe plus d'espace qu'Emacs, il a au
moins dans son cas l'excuse que c'est nécessaire.
Mais les compilateurs sont vraiment un besoin fondamental.
Maintenant que la structure générale du noyau Linux facilite son
portage, tout au moins vers des architectures raisonnablement conçues, il devrait
être possible de l'adapter à une quelconque plate-forme, pour autant que l'on
dispose d'un bon compilateur. Je ne m'inquiète plus d'éventuels
problèmes structurels qui pourraient entraver l'adaptation du noyau aux processeurs
à venir mais plutôt des compilateurs. Le processeur 64 bits d'Intel
appelé Merced en est un exemple frappant, car il est très différent
des processeurs actuels du point de vue d'un compilateur.
Ainsi, la portabilité de Linux est très liée au fait que GCC est
porté sur les architectures les plus répandues.
Il est très vite devenu évident que nous voulions développer un
système aussi modulaire que possible. Le modèle de développement
à Sources Libres l'impose, parce que sinon, vous ne pouvez pas facilement laisser
plusieurs personnes travailler simultanément. Il est vraiment pénible d'avoir
plusieurs personnes qui se gênent les unes les autres parce qu'elles travaillent sur
la même partie du noyau.
Sans modularité je devrais vérifier tous les fichiers modifiés
afin de m'assurer que ces changements n'affectent pas autre chose. Cela
représenterait un travail énorme. Avec la modularité, quand quelqu'un
m'envoie des corrections pour un nouveau système de fichiers et que je ne lui
accorde pas confiance a priori, je peux toujours être
certain que si personne n'utilise ce système de fichiers, il n'aura aucun impact sur
d'autres parties.
Ainsi, Hans Reiser développe un nouveau système de fichiers, et vient
d'arriver à le faire fonctionner. Je ne pense pas qu'il vaille la peine d'être
inséré dans le noyau 2.2 dès maintenant. Mais, grâce à la
modularité du noyau, je le pourrais si je le voulais vraiment et ce ne serait pas
trop difficile. Il s'agit surtout d'empêcher les gens de se marcher sur les
pieds.
Avec le noyau 2.0, Linux a vraiment pris du poids. C'est le moment où nous
avons ajouté les modules dans le noyau. Ceci a de façon évidente
amélioré la modularité en donnant une structure explicite pour
écrire des modules. Les programmeurs pouvaient travailler sur différents
modules sans risque d'interférence. Je pouvais garder le contrôle de ce qui
était écrit dans le noyau à proprement parler. Ainsi, encore une fois,
la gestion des intervenants et celle du code ont amené à prendre la
même décision de conception. Pour que les personnes travaillant sur Linux
restent coordonnées, nous avions besoin d'une solution ressemblant aux modules
noyau. Mais du point de vue de la conception, c'était aussi la chose à
faire.
L'autre aspect de la modularité est moins évident, et plus
problématique. Il s'agit du chargement dynamique, que tout le monde apprécie
mais qui pose de nouveaux problèmes. Le premier problème est d'ordre
technique, et est donc, comme d'ordinaire, (presque) toujours le plus simple à
résoudre. Le problème le plus important concerne les parties non techniques.
Par exemple, à quel point un module est-il un travail dérivé de Linux
et par conséquent sous GPL ?
Quand la première interface des modules a été faite, des
personnes ayant écrit des pilotes pour SCO ne voulaient pas en publier le code
source, comme requis par la GPL. Néanmoins, ils étaient prêts à
le recompiler pour fournir des binaires pour Linux. À ce point, pour des raisons
morales, j'ai décidé que je ne pouvais pas appliquer la GPL à ce genre
de situation.
La GPL impose que les travaux « dérivés » d'un travail sous
GPL soient protégés par elle. Malheureusement, la définition d'un
travail dérivé est assez vague. Dès que vous essayez de tracer une
frontière pour les travaux dérivés, le problème se transpose
immédiatement au choix de l'endroit où placer la frontière.
Nous avons fini par décider (à moins que ce soit moi qui aie fini par
décréter) que les appels systèmes ne seraient pas
considérés comme un lien au noyau. Tout programme fonctionnant au-dessus de
Linux ne pouvait donc pas être considéré comme couvert par la GPL.
Cette décision a très rapidement été prise et j'ai même
ajouté un fichier spécial LISEZMOI (voir Annexe B)
pour en informer tout le monde. Pour cette raison, les éditeurs commerciaux peuvent
écrire des programmes pour Linux sans avoir à s'inquiéter de la
GPL.
Le résultat, du point de vue des programmeurs de modules, était qu'on
pouvait écrire un module propriétaire si l'on n'utilisait que l'interface
normale pour le chargement. Il s'agit cependant toujours d'une zone d'ombre du noyau. Ces
zones d'ombre laissent peut-être toujours des occasions aux gens pour abuser de la
situation et c'est en partie à cause de la GPL qui n'est pas particulièrement
claire à propos de thèmes tels que l'interface de modules. Si quelqu'un
devait passer outre en utilisant les symboles exportés dans le seul but de
contourner la GPL, alors je pense qu'il y aurait une possibilité de poursuites en
justice. Mais je ne pense pas que quiconque veuille utiliser le noyau de façon
malhonnête ; ceux qui ont montré un intérêt commercial dans le
noyau l'ont fait parce qu'ils étaient intéressés par les avantages
apportés par le modèle de développement.
La puissance de Linux réside autant dans la communauté qui
coopère afin de l'améliorer que dans le code lui-même. Si Linux
était détourné — si quelqu'un voulait faire et distribuer une
version propriétaire — son attrait, qui est principalement le modèle
de développement à Sources Libres, serait perdu dans cette version
propriétaire.
Aujourd'hui, Linux a atteint nombre des buts de conception dont certains supposaient
à l'origine qu'ils ne pourraient être atteints que sur une architecture
micro-noyau.
En construisant un modèle général de noyau fondé sur des
éléments communs à des architectures répandues, le noyau Linux
a obtenu beaucoup des avantages de la portabilité qui auraient autrement
demandé l'ajout d'un niveau d'abstraction, et ce sans souffrir de la même
perte de performances que les micro-noyaux.
En autorisant les modules noyau, le code spécifique au matériel peut
souvent être confiné, en laissant ainsi le code du noyau hautement portable.
Les pilotes de périphériques sont un bon exemple de l'usage effectif de
modules noyau pour confiner les spécificités matérielles aux modules.
C'est un bon compromis entre mettre toutes les spécificités
matérielles dans le noyau de base (ce qui le rend rapide mais non portable) et les
mettre dans l'espace utilisateur (ce qui donne un système lent ou instable, voire
les deux).
Mais l'approche de la portabilité adoptée par Linux a été
aussi bénéfique à tout son environnement de développement. Les
décisions qui ont motivé la portabilité ont aussi permis à un
large groupe de personnes de travailler simultanément sur des parties de Linux sans
pour autant que j'en perde le contrôle. Les généralisations
d'architectures sur lesquelles se fonde Linux m'ont donné une base de
référence pour y confronter les changements du noyau, et fournissent
suffisamment d'abstraction pour que je n'aie pas à maintenir des parties
complètement séparées du code pour chaque architecture. Donc,
même si beaucoup de personnes travaillent sur Linux, je peux gérer le noyau en
lui-même. Et les modules noyau fournissent aux programmeurs une solution
évidente pour travailler indépendamment sur des parties du système qui
se doivent d'être indépendantes.
Je suis sûr que nous avons pris la bonne décision avec Linux en lui
faisant effectuer le moins d'opérations possibles en espace noyau. La
vérité est que je n'envisage pas de changements majeurs dans le noyau. Un
projet logiciel réussi doit arriver à maturité à un certain
point, et alors le rythme des changements ralentit. Il n'y a plus beaucoup d'innovations
majeures en stock pour le noyau. Il s'agit plutôt d'offrir un éventail plus
large pour le choix du système matériel : profiter de la portabilité
de Linux pour le rendre disponible sur de nouveaux systèmes.
De nouvelles interfaces naîtront, mais je pense qu'elles proviendront en partie
du port vers un plus grand nombre de systèmes. Par exemple, quand vous commencez
à faire des grappes (clusters), vous voyez
apparaître le besoin de coordonner l'ordre d'exécution de certains ensembles
de processus, ce qui impose une coopération entre les ordonnanceurs. Mais en
même temps, je ne veux pas que tout le monde se focalise sur les grappes et les
super-ordinateurs parce que les ordinateurs portables, les cartes que vous branchez
où que vous alliez et d'autres développements de ce genre peuvent jouer un
grand rôle dans le futur et je voudrais donc que Linux aille aussi dans cette
direction.
Les systèmes embarqués, eux, ne proposent pas la moindre interface
utilisateur. Vous n'accédez au système que pour changer le noyau, et encore,
mais le reste du temps, vous n'y touchez pas. Il s'agit là encore d'une autre
direction pour Linux. Je ne pense pas que Java ou Inferno (le système d'exploitation
embarqué de Lucent) investiront le secteur des périphériques
embarqués. Ils n'ont pas saisi l'importance de la loi de Moore . En premier lieu,
concevoir un système optimisé spécifique à un
périphérique embarqué particulier peut sembler judicieux, mais dans le
même temps, la loi de Moore dit qu'un matériel plus performant sera disponible
pour le même prix, détruisant ainsi la plus-value apportée par la
conception pour un périphérique particulier. Tout devient si bon
marché que vous pourriez aussi bien avoir le même système sur votre
ordinateur de bureau que sur votre périphérique embarqué. Cela rendra
la vie plus facile à tout le monde.
Les systèmes multi-processeurs symétriques représentent un des
domaines qui va être développé. Le noyau Linux 2.2 va gérer
très correctement quatre processeurs et nous l'améliorerons jusqu'à
pouvoir utiliser huit ou seize processeurs. La gestion de plus de quatre processeurs est
déjà présente, mais pas tout-à-fait achevée. Si vous
disposez de plus de quatre processeurs maintenant, vous jetez votre argent par la
fenêtre. Donc ce sera certainement amélioré.
Mais si les gens veulent soixante-quatre processeurs ils devront utiliser une version
spécifique du noyau, parce que les gérer dans le noyau normal causerait une
perte de performances pour l'utilisateur ordinaire.
Certains domaines d'application particuliers continueront à être le fer
de lance du développement du noyau. Les serveurs web ont toujours été
un problème intéressant, car c'est la seule application réelle qui
demande beaucoup au noyau. D'un certain côté, les serveurs web ont
représenté un certain danger de mon point de vue car je reçois tant de
commentaires de la part de la communauté utilisant Linux comme plate-forme de
serveur web que j'aurais facilement pu finir par optimiser uniquement pour ce type
d'applications. Je dois garder à l'esprit le fait que les serveurs web ne sont pas
la seule application intéressante.
Bien entendu, Linux n'est pas utilisé à son plein potentiel, même
par les serveurs web d'aujourd'hui. Apache lui-même ne procède pas Comme Il
Faut en ce qui concerne les threads, par exemple. Ce type
d'optimisation a été ralenti par les limites des réseaux. En ce
moment, vous pouvez saturer les réseaux à dix mégabits par seconde si
facilement qu'il n'y a aucune raison d'optimiser davantage. La seule manière de ne
pas saturer les réseaux à dix mégabits par seconde est d'avoir des tas
de scripts CGI fort consommateurs de ressources. Mais ce n'est pas quelque chose que le
noyau peut éviter. Ce que le noyau pourrait éventuellement faire, c'est de
répondre directement aux requêtes concernant les pages statiques et
transmettre les requêtes plus compliquées à Apache. Une fois que les
réseaux plus rapides seront devenus plus répandus, ce sera plus
intéressant. Mais nous n'avons pour le moment pas suffisamment de matériel
pour le tester et le développer.
La leçon que donnent toutes ces futures directions possibles est que je veux
que Linux soit à la pointe du progrès, et même un peu au-delà,
parce que ce qui est à la pointe aujourd'hui est ce qui sera dans nos ordinateurs
personnels demain.
Mais les développements les plus attrayants pour Linux auront lieu dans
l'espace utilisateur, et non pas dans l'espace noyau. Les changements du noyau sembleront
insignifiants par rapport à ce qui arrivera en dehors du système. De ce point
de vue, savoir ce que le noyau Linux sera n'est pas aussi intéressant que de savoir
quelles seront les fonctionnalités de la Red Hat 17.5 ou quelle sera la situation de
Wine (l'émulateur MS-Windows) dans quelques années.
Je m'attends à ce que, dans une quinzaine d'années, une autre personne
débarque et dise : « je peux faire tout ce que Linux fait, tout en
étant plus concis, parce que mon système ne sera pas alourdi par vingt ans
d'héritages ». Ils diront que Linux était conçu pour le 386 et
que les nouveaux processeurs effectuent les opérations vraiment intéressantes
d'une manière différente. Laissons tomber ce vieux Linux. J'ai
procédé ainsi lorsque j'ai commencé à développer Linux.
À l'avenir, ils pourront regarder notre code, utiliser nos interfaces, fournir une
compatibilité binaire. Et si tout cela se produit, je serai heureux.
|