Chargeur (informatique) - Loader (computing)

Dans les systèmes informatiques, un chargeur est la partie d'un système d'exploitation qui est responsable du chargement des programmes et des bibliothèques . C'est l'une des étapes essentielles du processus de démarrage d'un programme, car il place les programmes en mémoire et les prépare à l'exécution. Le chargement d'un programme implique la lecture du contenu du fichier exécutable contenant les instructions du programme en mémoire, puis la réalisation d'autres tâches préparatoires requises pour préparer l'exécutable à l'exécution. Une fois le chargement terminé, le système d'exploitation démarre le programme en passant le contrôle au code du programme chargé.

Tous les systèmes d'exploitation qui prennent en charge le chargement de programmes ont des chargeurs, à l'exception des systèmes informatiques hautement spécialisés qui n'ont qu'un ensemble fixe de programmes spécialisés. Les systèmes embarqués n'ont généralement pas de chargeurs, et à la place, le code s'exécute directement à partir de la ROM ou similaire. Afin de charger le système d'exploitation lui-même, dans le cadre du démarrage , un chargeur de démarrage spécialisé est utilisé. Dans de nombreux systèmes d'exploitation, le chargeur réside en permanence en mémoire, bien que certains systèmes d'exploitation qui prennent en charge la mémoire virtuelle peuvent permettre au chargeur d'être situé dans une région de la mémoire paginable .

Dans le cas des systèmes d'exploitation qui prennent en charge la mémoire virtuelle, le chargeur peut ne pas copier réellement le contenu des fichiers exécutables dans la mémoire, mais plutôt simplement déclarer au sous-système de mémoire virtuelle qu'il existe un mappage entre une région de mémoire allouée pour contenir les fichiers exécutables. le code du programme et le contenu du fichier exécutable associé. (Voir fichier mappé en mémoire .) Le sous-système de mémoire virtuelle est alors informé que les pages avec cette région de mémoire doivent être remplies à la demande si et quand l'exécution du programme atteint réellement ces zones de mémoire non remplie. Cela peut signifier que des parties du code d'un programme ne sont pas réellement copiées en mémoire tant qu'elles ne sont pas réellement utilisées, et le code inutilisé peut ne jamais être chargé en mémoire du tout.

Responsabilités

Sous Unix , le chargeur est le gestionnaire de l' appel système execve() . Les tâches du chargeur Unix incluent:

  1. validation (autorisations, besoins en mémoire, etc.);
  2. copier l'image du programme du disque dans la mémoire principale ;
  3. copie des arguments de ligne de commande sur la pile ;
  4. l'initialisation des registres (par exemple, le pointeur de pile);
  5. sauter au point d'entrée du programme ( _start ).

Dans Microsoft Windows 7 et supérieur, le chargeur est la LdrInitializeThunk fonction contenue dans ntdll.dll , qui effectue les opérations suivantes:

  1. initialisation des structures dans la DLL elle-même (c.-à-d. sections critiques , listes de modules);
  2. validation de l'exécutable à charger;
  3. création d'un tas (via la fonction RtlCreateHeap );
  4. allocation du bloc de variable d'environnement et du bloc PATH;
  5. ajout d'exécutable et de NTDLL à la liste des modules (une liste à double lien );
  6. chargement de KERNEL32.DLL pour obtenir plusieurs fonctions importantes, par exemple BaseThreadInitThunk ;
  7. chargement des importations des exécutables (ie bibliothèques de liens dynamiques ) récursivement (vérifier les importations des importations, leurs importations, etc.);
  8. en mode débogage, augmentation du point d'arrêt du système;
  9. initialisation des DLL;
  10. collecte des ordures;
  11. appelant NtContinue le paramètre de contexte donné à la fonction de chargeur (c'est-à-dire sauter à RtlUserThreadStart , qui démarrera l'exécutable)

Déplacement des chargeurs

Certains systèmes d'exploitation ont besoin de déplacer des chargeurs , qui ajustent les adresses (pointeurs) dans l'exécutable pour compenser les variations de l'adresse à laquelle le chargement commence. Les systèmes d'exploitation qui nécessitent le déplacement des chargeurs sont ceux dans lesquels un programme n'est pas toujours chargé au même emplacement dans l'espace d'adressage et dans lesquels les pointeurs sont des adresses absolues plutôt que des décalages par rapport à l' adresse de base du programme . Certains exemples bien connus sont OS / 360 d' IBM pour leurs mainframes System / 360 et ses descendants, y compris z / OS pour les mainframes z / Architecture .

OS / 360 et dérivés

Dans OS / 360 et les systèmes descendants, la fonction du système d'exploitation (privilégiée) s'appelle IEWFETCH et est un composant interne du superviseur du système d'exploitation, tandis que l'application LOADER (non privilégiée) peut exécuter plusieurs des mêmes fonctions, ainsi que celles du Linkage Editor, et est entièrement externe au superviseur du système d'exploitation (bien qu'il utilise certainement de nombreux services de superviseur).

IEWFETCH utilise des programmes de canaux hautement spécialisés , et il est théoriquement possible de charger et de déplacer un exécutable entier en une seule révolution du support DASD (environ 16,6 ms maximum, 8,3 ms en moyenne, sur les lecteurs «hérités» à 3600 tr / min). Pour les modules de chargement dont la taille dépasse une piste, il est également possible de charger et de déplacer l'ensemble du module sans perdre un tour de média.

IEWFETCH intègre également des fonctionnalités pour les structures dites de superposition, et qui facilite l'exécution d'exécutables potentiellement très volumineux dans un modèle de mémoire minimale (aussi petit que 44 Ko sur certaines versions du système d'exploitation, mais 88 Ko et 128 Ko sont plus courants).

Le noyau du système d'exploitation (la partie toujours résidente du superviseur) lui-même est formaté d'une manière compatible avec une version allégée de IEWFETCH. Contrairement aux exécutables normaux, le noyau du système d'exploitation est "chargé par dispersion": des parties du noyau sont chargées dans différentes parties de la mémoire; en particulier, certaines tables système doivent résider en dessous des 64 Ko initiaux, tandis que d'autres tables et codes peuvent résider ailleurs.

L' application Linkage Editor du système s'appelle IEWL. La fonction principale d'IEWL est d'associer des modules de chargement (programmes exécutables) et des modules objet (la sortie, par exemple, d'assembleurs et de compilateurs), y compris des «appels automatiques» à des bibliothèques («fonctions intégrées» de langage de haut niveau), dans un format qui peut être chargé le plus efficacement par IEWFETCH. Il existe un grand nombre d'options d'édition, mais pour une application conventionnelle, seules quelques-unes d'entre elles sont couramment utilisées.

Le format du module de chargement comprend un «enregistrement de texte» initial, suivi immédiatement de «l'enregistrement de déplacement et / ou de contrôle» pour cet enregistrement de texte, suivi de plusieurs instances d'enregistrements de texte et de paires d'enregistrements de déplacement et / ou de contrôle, jusqu'à la fin de la module.

Les enregistrements de texte sont généralement très volumineux; les enregistrements de déplacement et / ou de contrôle sont petits car les trois tampons d'enregistrement de déplacement et / ou de contrôle d'IEWFETCH sont fixés à 260 octets (des enregistrements de déplacement et / ou de contrôle plus petits sont certainement possibles, mais 260 octets est le maximum possible, et IEWL garantit que cette limitation est respectée, en insérant des enregistrements de réinstallation supplémentaires, si nécessaire, avant l'enregistrement de texte suivant, si nécessaire; dans ce cas particulier, la séquence d'enregistrements peut être: ..., enregistrement de texte, enregistrement de réinstallation, ..., enregistrement de contrôle , enregistrement de texte, ...).

Un octet spécial dans le tampon d'enregistrement de relocalisation et / ou de contrôle est utilisé comme zone de communication "spin de bit désactivé", et est initialisé à une valeur unique. La lecture CCW pour cet enregistrement de déplacement et / ou de contrôle a le bit d'interruption contrôlée par programme défini. Le processeur est ainsi averti lorsque ce CCW a été accédé par le canal via une sortie IOS spéciale . A ce stade, le processeur entre dans la boucle de "spin de bits désactivé" (parfois appelée "la boucle la plus courte du monde"). Une fois que cet octet change par rapport à sa valeur initialisée, la CPU quitte le tour de bit et la relocalisation se produit pendant "l'intervalle" dans le support entre la relocalisation et / ou l'enregistrement de contrôle et l'enregistrement de texte suivant. Si le déplacement est terminé avant l'enregistrement suivant, le NOP CCW suivant la lecture sera changé en TIC, et le chargement et le déplacement se poursuivront en utilisant le tampon suivant; sinon, le canal s'arrêtera au NOP CCW, jusqu'à ce qu'il soit redémarré par IEWFETCH via une autre sortie IOS spéciale. Les trois tampons sont dans une file d'attente circulaire continue, chacun pointant vers son suivant, et le dernier pointant vers le premier, et trois tampons sont constamment réutilisés au fur et à mesure du chargement et du déplacement.

IEWFETCH peut ainsi charger et déplacer un module de chargement de toute taille pratique, et dans le minimum de temps possible.

Lieurs dynamiques

Chargeurs reliant dynamiques sont un autre type de chargeur qui charge et lien bibliothèques partagées (comme .so fichiers , fichiers .dll ou fichiers .dylib) aux programmes en cours d' exécution déjà chargés.

Voir également

Références