L4 est un micronoyau de seconde génération conçu par . Les micronoyaux du début des années 1990 étant extrêmement lents par rapport à leurs concurrents monolithiques, Liedtke décide de développer ses propres micronoyaux. Il développe ainsi les micronoyaux L3 et ensuite L4. Les nombreuses améliorations apportées à ceux-ci et leurs successeurs ont depuis permis d'accroître considérablement la vitesse de ces anciens noyaux pour en arriver ensuite aux micronoyaux actuels.

L’idée générale de L4 est ainsi résumée par Liedtke lui-même :

Motivations

Les micronoyaux minimisent les fonctionnalités du noyau. Le noyau fournit un ensemble de services de base : ordonnancement, synchronisation, messages etc. tandis que les services du système d'exploitation fonctionnent dans le monde utilisateur .. Les systèmes d'exploitation à base de noyau monolithique comme le noyau de Linux mettent l’accent sur la performance en permettant à de nombreux services de fonctionner en mode privilégié et en simplifiant l'accès aux ressources du système. Les micronoyaux privilégient la sécurité et la stabilité. Ceci fait toujours l'objet de controverses, comme celle qui a opposé Linus Torvalds à Andrew S. Tanenbaum même si la popularité du noyau Linux a temporairement tranché la question. Les premiers systèmes d'exploitation à base de micronoyaux étaient notoirement lents.

C’est dans l’objectif d’améliorer les performances des systèmes d’exploitation à base de noyaux minimalistes que Jochen Liedtke commence à développer les . Le principe fondamental de ces noyaux consiste simplement en : . Ce type de noyau fournit ainsi exclusivement les fonctions fondamentales telles que les communications, le mappage Il impose également les politiques. Un micronoyau ne fait aucun travail réel (le travail du micronoyau consiste seulement au contrôle et à la gestion des tâches qu’il délègue aux processus dans l’espace utilisateur)..

Histoire

Il y a , Jochen Liedtke démontra avec son que les communications interprocessus des micronoyaux pouvaient être plus rapides que ce à quoi l’on aurait pu s’attendre à l’époque.. L4 fut conçu à partir d’une version antérieure appelée L3 et développée par John Liedtke au début des sur les plateformes i386. Il a été déployé commercialement sur plusieurs milliers d’installations (principalement dans des écoles). Comme tous les micronoyaux de l’époque, L3 souffrait d’un coût des communications interprocessus de l’ordre de .

Liedtke utilisait initialement L3 pour expérimenter de nouvelles idées. Celui-ci a utilisé pour la première fois le nom « L4 » avec l’ABI v2 déjà présent dans la communauté . Par la suite, il sera complètement réécrit en assembleur pour les ordinateurs i486 et fut très vite porté pour les Pentium..

Ce travail initial déclencha une évolution de suivie de multiples révisions des ABI ainsi que de nouvelles implémentations. Celle-ci a commencé par la réimplémentation de l’ABI Dresde et UNSW sur pour les processeurs Alpha et MIPS, ces derniers ayant intégré les opérations les plus lentes en . Ces deux noyaux ont ainsi pu obtenir des communications interprocessus inférieures à une microseconde, ce qui fut facilité par le fait qu’ils étaient des noyaux à code source ouvert. Le noyau UNSW Alpha constitua le premier noyau L4 multiprocesseurs.

Liedtke, qui avait quitté GMD pour IBM Watson, apporta son expérience lors de l’implémentation d’une ABI qui sera par la suite connue sous le nom de . GMD et IBM imposaient une politique de propriété intellectuelle très restrictive pour les autres chercheurs, ce qui poussa le projet « Dresde » à repartir à zéro en implémentant une nouvelle version appelée « Fiasco », en référence à leur mauvaise expérience et en essayant de mieux traiter les questions de propriété intellectuelle.

« Fiasco » est la première version du qui fut complètement écrite dans un langage de haut niveau (C++) et la plus ancienne version du code de base des encore activement maintenue. Il a été le premier commercialisé de manière significative (estimation: plus de ).

Quand Liedtke est arrivé à Karlsruhe en Allemagne, lui et adaptèrent dans une nouvelle version écrite en C et appelée « Hazelnut », qui fut le premier porté sur d’autres architectures (de Pentium à ARM).

L’expérience de Karlsruhe avec l’ABI et celle de L4Ka::Hazelnut entraîna une révision majeure de l’ABI V4 afin d’améliorer la portabilité du noyau. Après la mort de Liedtke , ses étudiants ont implémenté un nouveau : L4Ka::Pistachio avec L4Ka. Il fut écrit en C++ et d’abord porté sur x86 et PowerPC, ensuite sur UNSW/NICTA et peu après sur MIPS, Alpha, PowerPC et ARM.

À la , ils ont tout de suite reciblé leur installation afin de l’utiliser dans des systèmes embarqués contraints en ressources. En conséquence, une nouvelle version du noyau à partir d’une copie du code de « Pistachio » vit le jour et fut appelée NICTA::Pistachio-embarqué (« L4-embarqué »). Il fut massivement commercialisé lorsque Qualcomm décida de l’utiliser comme système d’exploitation dans le micrologiciel de leurs modems sans fil. La filiale de NICTA devint le support et le développement du noyau qu'il rebaptisa « OKL4 ». Une autre version fut déployée, PikeOS, un clone commercialisé par et certifié pour une utilisation dans les systèmes critiques de l’aéronautique et également dans les avions et les trains.

Quelques concepts de base

L’idée principale de L4 étant d’améliorer la vitesse des micronoyaux, plus particulièrement celle des communications interprocessus tout en conservant les concepts des micronoyaux, il fallut réadapter certains concepts et en introduire d’autres. Nous présenterons ci-dessous les concepts qui permirent à Liedtke de relever son défi.

Minimalité

Les fournissent une API simple, minimale et une abstraction qui supportent la création, l’exécution et les communications interprocessus (IPC) entre les threads en plus de permettre l’isolation et la gestion des différentes tâches..

Les principaux moteurs de conception de Liedtke mettaient l'accent sur la minimalité et sur la performance des communications interprocessus en ayant la ferme conviction d’améliorer les points faibles de L3. Il formula le principe de minimalité des micronoyaux comme suit :

Ce principe fut le fondement de la conception des noyaux L4. Mais selon Kevin Elphinstone et Gernot Heiser, aucun concepteur de micronoyau ne peut affirmer avoir créé un micronoyau pur dans le strict respect du principe de minimalité. Pour preuve, ils possèdent tous un ordonnanceur dans le noyau qui met en œuvre une politique d'ordonnancement particulière. À cette époque, ils pensaient que personne ne pouvait concevoir un micronoyau dans lequel toute la politique de planification est déléguée dans l'espace utilisateur sans imposer de coûts énormes.

Espaces d’adressage

Au niveau matériel, un espace d’adressage est un mappage qui associe chaque page virtuelle à une page physique, ou bien la marque comme « non accessible ». Le mappage est implémenté par la TLB et la table de pages..

C’est l’unité de gestion de la mémoire qui fournit l’isolation spatiale. Il contient toutes les données directement accessibles par un thread. L’espace d’adressage dans L4 peut être construit récursivement. Un thread peut mapper des parties communes à son espace d’adressage dans celui d’un autre thread et ainsi partager les données de ces parties de son espace mémoire..

Le concept de tâche est équivalent à celui de l’espace d’adressage. , une tâche est un ensemble de threads partageant un espace d’adressage.

Threads et IPC

La communication interprocessus par passage de messages est l’un des paradigmes les plus utilisés par les micronoyaux et d’autres applications client-serveur. Il aide à améliorer la modularité, la flexibilité, la sécurité ainsi que la scalabilité..

Pour communiquer entre des threads possédant des espaces d’adressage différents, la méthode classique consiste à faire transmettre les messages entre threads via le noyau. IPC implique toujours un certain accord entre les deux parties : l’expéditeur décide d’envoyer des informations et détermine son contenu, alors que le récepteur détermine s’il est disposé à recevoir des informations et s’il est libre d’interpréter le contenu du message..

Selon Liedtke, . Il existe deux types d’IPC : les IPC synchrones et asynchrones. Les micronoyaux de première génération ont utilisé des IPC asynchrones (par exemple Mach). Le noyau garde le message dans une mémoire tampon jusqu’à ce que le récepteur soit prêt à recevoir le message ; cela a pour conséquence la double copie du message et c'est ceci qui fit perdre beaucoup de performance à Mach. Les micronoyaux de deuxième génération (comme L4) ont adopté les IPC synchrones pour la communication entre les threads. Dans ces communications, le premier communiquant attend jusqu’à ce que l’autre soit prêt : le message peut alors être directement copié entre ces threads, ce qui évite une copie temporaire inutile dans le noyau. Les IPC synchrones satisfont ainsi une implémentation efficace et nécessaire.

Interruptions

L’abstraction naturelle des interruptions correspond aux communications interprocessus. Le matériel est considéré comme un ensemble de threads qui ont des identifiants spéciaux et qui envoient des messages contenant uniquement l’identifiant de l’expéditeur aux threads logiciels qui leur sont associés. Le thread récepteur vérifie l’identifiant de l’expéditeur du message et si le message est une interruption matérielle, il est alors interrompu immédiatement. La transformation de l’interruption en message est faite par le noyau, mais ce dernier n’est pas impliqué dans le traitement de l’interruption. En réalité, le noyau ignore complètement la sémantique de traitement des interruptions..

Les pilotes dans l'espace utilisateur

Un pilote de périphérique est un processus qui a directement accès aux ports d’entrées-sorties mappés directement dans son espace d’adressage et reçoit des messages (interruptions) du matériel à travers les mécanismes standards IPC. Dans la philosophie des , ils ne doivent jamais être intégrés dans le micronoyau. Les interruptions entrantes sont transformées en messages aux threads associés. Ceci est la base pour implémenter les pilotes de périphérique comme des serveurs de l’espace utilisateur..

Famille du micronoyau L4 Depuis le développement de L4 par Liedtke, plusieurs implémentations ont suivi dont Fiasco, L4Ka::Pistachio, P4, , L4Ka::Hazelnut, L4/MIPS, L4/Alpha, L4/x86

Fiasco

Fiasco a été développé par l’équipe Fiasco de l’université technique de Dresde et il est à l’origine du système DROPS (). On dit souvent « L4/Fiasco » pour parler de Fiasco, ce qui met en évidence sa relation avec L4..

. Dans le système L4/Fiasco, il y a un environnement L4 (L4Env) qui est un environnement de programmation pour L4/Fiasco.

Le modèle de programmation de “L4/Fiasco” est basé sur l’architecture client-serveur. L’ordonnanceur est préemptif avec une basse priorité, et un ordonnancement de type rotation entre les tâches ayant le même propriétaire..

L4Ka::Pistachio

Pistachio est développé par l’équipe de l’Institut de technologie de Karlsruhe (Allemagne) en collaboration avec le de l’Université de Nouvelle-Galles du Sud (Australie). Il est distribué sous la .

Il a été porté sur les architectures suivantes : Alpha (21164 et 21264), AMD64 (, Simics), ARM (SA1100, XScale, ARM925T), IA32 (Pentium et compatibles), IA-64 (Itanium1, Itanium2, Ski), MIPS 64 bits (R4000, ), PowerPC () et (POWER3, POWER4). Il supporte les systèmes multiprocesseurs.

La dernière version, la X.2, est sortie en ..

seL4