mercredi 2 avril 2008

Fonctions remplies par un noyau

Fonctions généralement remplies par un noyau

Les noyaux ont comme fonctions de base d’assurer le chargement et l’exécution des processus, de gérer les entrées/sorties et proposer une interface entre l’espace noyau et les programmes de l’espace utilisateur.

À de rares exceptions, les noyaux ne sont pas limités à leurs fonctionnalités de base. On trouve généralement dans les noyaux les fonctions des micro-noyaux : un gestionnaire de mémoire et un ordonnanceur, ainsi que des fonctions de communication inter-processus.

En dehors de fonctions précédemment listées, de nombreux noyaux fournissent également des fonctions moins fondamentales telles que la gestion des systèmes de fichiers ; plusieurs ordonnanceurs spécialisés (batch, temps réel, entrées/sorties, etc.) ; des notions de processus étendues telles que les processus légers ; des supports réseaux (TCP/IP, PPP, pare-feu, etc.) ; des services réseau (NFS, etc.). Enfin, la plupart des noyaux fournissent également des modèles de pilotes et des pilotes pour le matériel.

En dehors des fonctionnalités de base, l’ensemble des fonctions des points suivants (y compris les pilotes matériels, les fonctions réseaux et systèmes de fichiers ou les services) ne sont pas nécessairement fournies par un noyau de système d’exploitation. Ces fonctions du système d’exploitation peuvent être implantées tant dans l’espace utilisateur que dans le noyau lui-même. Leur implantation dans le noyau est faite dans l’unique but d’augmenter les performances. En effet, suivant la conception du noyau, la même fonction appelée depuis l’espace utilisateur ou l’espace noyau a un coût temporel notoirement différent. Si cet appel de fonction est fréquent, il peut s’avérer utile d’intégrer ces fonctions au noyau pour augmenter les performances.

Il faut noter que ces techniques sont utilisées pour pallier des défauts des noyaux tels que les latences élevées. Autant que possible, il est préférable d’écrire un logiciel hors du noyau, dans l’espace utilisateur. En effet, l’écriture en espace noyau suppose l’absence de mécanismes tels que la protection de la mémoire. Il est donc plus complexe d’écrire un logiciel fonctionnant dans l’espace noyau que dans l’espace utilisateur, les bogues et failles de sécurité sont bien plus dangereux.

Ordonnanceur

4 tâches ordonnancées. La tâche 3 est en priorité haute, la tâche 4 est en priorité faible. Ce diagramme est explicatif, en pratique les instructions ordonnées sont directement exécutées

4 tâches ordonnancées. La tâche 3 est en priorité haute, la tâche 4 est en priorité faible. Ce diagramme est explicatif, en pratique les instructions ordonnées sont directement exécutées

L’ordonnanceur d’un système d’exploitation n’a de sens qu’en système multitâche. Il gère l’ordre dans lequel les instructions de différentes tâches sont exécutées et est responsable de la sauvegarde et de la restauration du contexte des tâches (ce contexte est constitué des registres processeurs), appelée également commutation de contexte.

La plupart des ordonnanceurs modernes permettent d’indiquer sur quel processeur sont exécutées les tâches. Certains permettent également de migrer des tâches sur d’autres machines d’une grappe de calcul.

L’algorithme d’ordonnancement détermine quelle tâche doit s’exécuter en priorité et sur quel processeur. Cet algorithme doit permettre d’utiliser efficacement les ressources de la machine.

L’ordonnancement peut être de type « coopératif » : les tâches doivent être écrites de manière à coopérer les unes avec les autres et ainsi accepter leur suspension pour l’exécution d’une autre tâche. L’ordonnancement peut être également de type « préemptif » : l’ordonnanceur a la responsabilité de l’interruption des tâches et du choix de la prochaine à exécuter. Certains noyaux sont eux-mêmes préemptifs : l’ordonnanceur peut interrompre le noyau lui-même pour faire place à une activité (typiquement, toujours dans le noyau) de priorité plus élevée.

Gestionnaire de mémoire

Le gestionnaire de mémoire est le sous-ensemble du système d’exploitation qui permet de gérer la mémoire de l’ordinateur. Sa tâche la plus basique est d’allouer de la mémoire à des processus lorsqu’ils en ont besoin. Cette mémoire allouée est par défaut propre au processus qui en fait la demande.

Gestionnaire de mémoire, espace utilisateur et espace noyau
Gestionnaire de mémoire, espace utilisateur et espace noyau

Sur les noyaux récents, le gestionnaire de mémoire masque la localisation physique de la mémoire (en mémoire vive ou sur disque dur, dans l’espace de mémoire paginée) et présente au programme une mémoire globale uniforme dite mémoire virtuelle. Ainsi, tout processus croit manipuler une mémoire qui a les propriétés suivantes:

  • la mémoire allouée commence systématiquement à l’adresse 0 ;
  • la mémoire peut être étendue jusqu’aux capacités théoriques de la machine;
  • la mémoire est privée (protégée), un processus ne peut pas accéder à la mémoire d’un autre processus (sauf allocations et autorisations spécifiques).

L’intérêt de ne pas indiquer au processus l’emplacement physique des données est de permettre au gestionnaire de mémoire de placer et déplacer à sa convenance les données en mémoire, sans affecter les processus. Ces données peuvent notamment être fragmentées dans la mémoire vive lorsqu’un processus demande un bloc de mémoire d’une taille supérieure au plus grand bloc physique libre. Le contenu de la mémoire peut aussi être migré. Cette migration est faite sur les différents supports mémoires tels que dans la mémoire physique (plus ou moins proche du processeur), dans la mémoire paginée, dans la mémoire accessible par réseaux (grappe de calcul).

La virtualisation de la mémoire permet aussi une gestion optimiste des ressources : la mémoire allouée mais pas encore utilisée peut être virtuellement allouée à plusieurs processus (noyau Linux).

Les programmes dans l’espace utilisateur disposent de pouvoirs restreints sur la mémoire : ils doivent demander au noyau de la mémoire. Le noyau fait appel à son gestionnaire de mémoire pour allouer (ou non) la mémoire au processus qui la demande. Si un programme tente d’utiliser des zones de mémoire ne lui appartenant pas, il est évincé automatiquement. Le mécanisme d’éviction repose sur un mécanisme du processeur, nommément une unité de gestion de la mémoire, ou MMU, qui signale au noyau l’existence d’un accès fautif. C’est le noyau lui-même qui prend la décision de suspendre ou détruire immédiatement le processus fautif.

Appels système

Les appels système sont des fonctions :

  • appelées depuis un programme de l’espace utilisateur ;
  • dont l’exécution (le traitement) est effectué dans l’espace noyau ;
  • dont le retour est effectué dans le programme appelant dans l’espace utilisateur.

En plus d’un changement de mode d’exécution, l’appel système suppose au moins deux commutations de contextes :

  1. Contexte du programme appelant ;
    • changement de contexte ;
  2. Contexte du noyau ;
    • changement de contexte ;
  3. Contexte du programme appelant.

Le coût d’un appel système est nettement plus élevé qu’un simple appel de fonction intra-processus : alors qu’un appel de fonction ne suppose que quelques instructions primitives (chargement et exécution d’une zone mémoire), le coût d’un appel système se compte en milliers ou dizaines de milliers d’instructions primitives, générant à la fois une charge et des délais d’exécution supplémentaires. Pour ces raisons, les fonctions qui sont utilisées de manière intense sont déplacées dans l’espace noyau. Les programmes utilisateurs font alors un nombre restreint d’appels système de haut niveau. Les nombreuses interactions de bas niveau générées par ces appels système sont effectuées dans l’espace noyau. Cela concerne notamment les pilotes de périphériques.

Les entrées/sorties font également l’objet d’un traitement par l’ordonnanceur.

Gestion du matériel

La gestion du matériel se fait par l’intermédiaire de pilotes de périphériques. Les pilotes sont des petits logiciels légers dédiés à un matériel donné qui permettent de faire communiquer ce matériel. En raison du très grand nombre d’accès à certains matériels (disques durs par exemple), certains pilotes sont très sollicités. Ils sont généralement inclus dans l’espace noyau et communiquent avec l’espace utilisateur via les appels système.

En effet, comme cela a été vu dans le précédent paragraphe, un appel système est coûteux : il nécessite au moins deux changements de contexte. Afin de réduire le nombre des appels système effectués pour accéder à un périphérique, les interactions basiques avec le périphérique sont faites dans l’espace noyau. Les programmes utilisent ces périphériques au travers d’un nombre restreint d’appels système.

Cependant, indépendamment de l’architecture, de nombreux périphériques lents (certains appareils photographiques numériques, outils sur liaison série, etc.) sont/peuvent être pilotés depuis l’espace utilisateur, le noyau intervenant au minimum.

Il existe des couches d’abstraction de matériel qui présentent la même interface à l’espace utilisateur et simplifient ainsi le travail des développeurs d’applications. Dans les systèmes de type UNIX, l’abstraction utilisée est le système de fichiers : les primitives open, close, read et write sont présentées à l’espace utilisateur pour manipuler toutes sortes de périphériques. On parle dans ce cas de système de fichiers synthétique.

Aucun commentaire: