Ce document présente le premier travail dirigé (TD n°1) de la matière "Systèmes d'exploitation", conçu pour les étudiants universitaires. Il vise à approfondir la compréhension des concepts clés liés aux systèmes d'exploitation, ainsi qu'aux processus de compilation et d'édition de liens.
Il couvre les notions suivantes:
- Le rôle et les différents types de systèmes d'exploitation (multiprogrammé, temps partagé, par lots).
- La gestion des processus (père, orphelin) et les interruptions.
- Le rôle des compilateurs, interpréteurs et éditeurs de liens.
- Un exercice pratique détaillé sur l'édition de liens de modules objets, incluant le calcul d'adresses et la résolution des dépendances.
Systèmes d'exploitation - Travaux Dirigés
Cette page contient une série d'exercices sur les concepts fondamentaux des systèmes d'exploitation, des compilateurs et de l'édition de liens, destinée à un public de niveau Licence en Systèmes Réseaux et Distribution (RSD).
TD n°1
Exercice 1 : Questions de cours
-
Quel est le rôle d’un système d’exploitation ? Les interpréteurs de commandes et les compilateurs font-ils partie du système d’exploitation ?
Explication : Un système d'exploitation (OS) est un logiciel essentiel qui gère les ressources matérielles et logicielles d'un ordinateur. Il agit comme une interface entre l'utilisateur et le matériel, facilitant l'exécution des programmes, la gestion de la mémoire, des processus, des fichiers et des périphériques d'entrée/sortie. Les interpréteurs de commandes (shells) et les compilateurs sont des outils logiciels qui s'exécutent sur le système d'exploitation, mais ne sont pas considérés comme une partie intrinsèque du noyau du système d'exploitation lui-même. Ils font partie de l'environnement utilisateur ou des utilitaires système.
-
Qu’est-ce qu’un système multiprogrammé ? Qu'est-ce qu'un système de traitement par lots ? Qu'est-ce qu’un système en temps partagé ?
Explication :
- Un système multiprogrammé est un système d'exploitation capable d'avoir plusieurs programmes résidant simultanément en mémoire principale. L'objectif est d'optimiser l'utilisation du processeur en basculant entre les programmes lorsqu'un d'entre eux attend une opération d'entrée/sortie.
- Un système de traitement par lots exécute des tâches en séquence sans intervention de l'utilisateur. Les tâches sont regroupées (en lots) et exécutées une par une. Ce type de système est adapté aux travaux nécessitant peu d'interaction mais beaucoup de calculs.
- Un système en temps partagé est une extension des systèmes multiprogrammés qui permet à plusieurs utilisateurs d'interagir simultanément avec un ordinateur. Le processeur alterne rapidement entre les différents programmes ou utilisateurs, donnant l'illusion que chaque utilisateur dispose de sa propre machine.
-
Dans le système UNIX, est-ce que tout processus a un père ? Que se passe-t-il lorsqu’un processus devient orphelin (mort de son père) ?
Explication : Dans un système UNIX, à l'exception du processus initial (
initou un équivalent commesystemd, qui a un PID de 1 et est le "père de tous les processus"), tout processus a un processus parent. Lorsqu'un processus parent se termine avant ses processus enfants, ces derniers deviennent "orphelins". Dans ce cas, le système d'exploitation attribue généralement ces processus orphelins au processusinit(ousystemd) qui devient leur nouveau parent.initest alors responsable de la gestion de ces processus orphelins, notamment en collectant leur statut de sortie lorsqu'ils se terminent pour éviter les processus "zombies". -
Citez quelques événements qui provoquent l’interruption de l’exécution d’un processus.
Explication : Les événements pouvant interrompre l'exécution d'un processus incluent :
- Interruption matérielle : Par exemple, une requête d'entrée/sortie (lecture depuis un disque), une pression de touche, un événement réseau, ou une interruption du timer.
- Interruption logicielle (appel système) : Lorsqu'un processus demande un service au noyau du système d'exploitation (par exemple, pour lire un fichier, allouer de la mémoire).
- Exception : Une erreur arithmétique (division par zéro), un accès mémoire non autorisé (faute de page), une instruction illégale.
- Signal : Un signal envoyé par un autre processus ou par le système d'exploitation (par exemple,
SIGTERMpour terminer un processus,SIGSTOPpour le suspendre). - Expiration du quantum de temps : Dans un système en temps partagé, un ordonnanceur peut interrompre un processus après une certaine durée pour en exécuter un autre.
-
Quel est le rôle de l’ordonnanceur ?
Explication : L'ordonnanceur (ou planificateur de tâches) est un composant crucial du système d'exploitation. Son rôle principal est de décider quel processus doit être exécuté par le processeur à un instant donné et pendant combien de temps. Il gère l'allocation des ressources CPU entre les processus concurrents, en se basant sur diverses politiques d'ordonnancement (par exemple, FIFO, Round Robin, priorité). L'objectif est d'optimiser les performances du système, comme le temps de réponse, le débit ou l'équité entre les processus.
-
Pourquoi le partage de données pose des problèmes dans un système multiprogrammé en temps partagé ?
Explication : Le partage de données dans un environnement multiprogrammé en temps partagé introduit plusieurs défis majeurs :
- Conditions de concurrence (Race Conditions) : Plusieurs processus tentent d'accéder et de modifier les mêmes données partagées simultanément, ce qui peut entraîner des résultats imprévisibles et incorrects selon l'ordre d'exécution.
- Incohérence des données : Si un processus modifie une donnée pendant qu'un autre processus la lit ou la modifie, la donnée peut devenir incohérente.
- Interblocages (Deadlocks) : Des processus peuvent se retrouver dans une situation où chacun attend une ressource détenue par un autre processus, créant une impasse où aucun ne peut progresser.
- Famine (Starvation) : Un processus peut être indéfiniment empêché d'accéder à une ressource partagée par d'autres processus plus prioritaires ou plus rapides.
-
Quel est le rôle d’un compilateur ? Quelles sont ses principales phases de travail ? En quoi se différencie-t-il d’un interpréteur ?
Explication :
- Rôle d'un compilateur : Un compilateur est un programme informatique qui traduit un code source écrit dans un langage de programmation (langage de haut niveau) en un autre langage, généralement un langage de niveau inférieur comme le code machine ou le code assembleur, qui peut être exécuté directement par le processeur de l'ordinateur.
- Phases de travail : Les principales phases de la compilation incluent :
- Analyse lexicale : Découpage du code source en unités élémentaires (mots clés, identificateurs, opérateurs).
- Analyse syntaxique : Vérification de la structure grammaticale du code par rapport aux règles du langage.
- Analyse sémantique : Vérification de la cohérence logique et du sens du programme.
- Génération de code intermédiaire : Traduction du code dans une forme plus simple et abstraite.
- Optimisation de code : Amélioration du code intermédiaire pour le rendre plus efficace.
- Génération de code cible : Traduction du code optimisé en code machine ou assembleur.
- Différence avec un interpréteur :
Un compilateur traduit l'intégralité du programme source en code exécutable avant toute exécution. Le fichier exécutable peut ensuite être lancé de manière autonome. L'interpréteur, quant à lui, lit et exécute le code source ligne par ligne (ou instruction par instruction) au moment de l'exécution, sans produire de fichier exécutable distinct. La compilation est généralement plus lente que l'interprétation pour la première exécution, mais le code compilé est ensuite beaucoup plus rapide à exécuter. L'interprétation offre plus de flexibilité pour le développement et le débogage.
-
Quel est le rôle d’un éditeur de liens ? Qu’est-ce qu’un « lien à satisfaire » ? Qu’est-ce qu’un « lien utilisable »?
Explication :
- Rôle d'un éditeur de liens : L'éditeur de liens (ou linker) est un programme qui combine plusieurs fichiers objets (produits par un compilateur) et/ou des bibliothèques pour créer un fichier exécutable final. Son rôle est de résoudre toutes les références symboliques (liens) entre les différents modules et d'organiser les sections de code et de données en mémoire.
- « Lien à satisfaire » (unresolved symbol ou external reference) : Il s'agit d'une référence à une fonction ou une variable qui est utilisée dans un module mais dont la définition se trouve dans un autre module ou dans une bibliothèque. L'éditeur de liens doit trouver la définition correspondante pour "satisfaire" ce lien.
- « Lien utilisable » (defined symbol ou exported symbol) : Il s'agit d'une fonction ou d'une variable qui est définie dans un module et qui est rendue disponible pour être utilisée par d'autres modules. C'est la définition que l'éditeur de liens recherche pour satisfaire les "liens à satisfaire".
Exercice 2 : Édition de liens de modules objets
On dispose de cinq modules compilés, mémorisés dans les fichiers cmpdisk.o, cmpfile.o, disk_io.o, lsbrk.o, printstr.o. Ces cinq modules constituent la base d'un programme, qui nécessite en plus des modules de bibliothèque.
On dispose de deux outils :
- L’outil
listliens: qui imprime les liens des modules, en indiquant leur type ainsi que éventuellement leur valeur. Le résultat de l'application de cet outil sur les cinq modules est donné dans la Table 1, oùlassignifie « lien à satisfaire » etlusignifie « lien utilisable ». - L’outil
taille: qui donne la taille d'un module objet, c'est-à-dire le nombre d'emplacements occupés par ce module. Le résultat de l'application de cet outil sur les cinq modules est donné dans la Table 2.
On se propose de faire l'édition des liens des cinq modules dans l'ordre suivant : cmpdisk.o, cmpfile.o, disk_io.o, lsbrk.o, printstr.o.
Table 1 : Résultat de "listliens"
cmpdisk.olas bloc_transfer_drlas close_printerlas compare_filelu compare_hierarch 1862las exitlu exit_prog 2820lu file_error 422las freelas get_memorylu main 2460las open_drivelas open_printerlas print_stringcmpfile.olas bloc_transfer_drlu compare_file 200las file_errordisk_io.olu bloc_transfer_dr 2118las exitlas exit_proglas get_memorylu open_drive 236las print_stringlsbrk.olas exit_proglu get_memory 0las lmalloclas print_stringprintstr.olu ask_confirm 758lu close_printer 1028las getcharlu open_printer 996lu print_string 340las write
Table 2 : Résultat de "taille"
cmpdisk.o- 3376
cmpfile.o- 644
disk_io.o- 3862
lsbrk.o- 82
printstr.o- 1196
Calculez les adresses d'implantation des modules.
Donnez le contenu de la table des liens après prise en compte des liens des cinq modules (premier passage). Justifiez.
Donnez la liste des références croisées.
Certains liens ne sont pas définis. Donnez lesquels. Comment seront-ils satisfaits ?
Indiquez les liens qui ne sont à satisfaire dans aucun module.
Questions Fréquemment Posées (FAQ)
- Qu'est-ce qu'un système d'exploitation (OS) ?
- Un système d'exploitation est le logiciel central qui gère toutes les ressources matérielles et logicielles d'un ordinateur. Il fournit une interface pour les utilisateurs et les applications, et est responsable de l'exécution des programmes, de la gestion de la mémoire, des périphériques et des fichiers. C'est la base sur laquelle tous les autres logiciels fonctionnent.
- Quelle est la différence principale entre un compilateur et un interpréteur ?
- La principale différence réside dans la manière dont ils exécutent le code source. Un compilateur traduit le programme entier en code machine exécutable avant l'exécution. L'interpréteur exécute le code source instruction par instruction, sans créer de fichier exécutable distinct. Le code compilé est généralement plus rapide à l'exécution une fois compilé, tandis que l'interprétation offre plus de flexibilité pour le développement et le débogage.
- Pourquoi l'édition des liens (linking) est-elle une étape cruciale ?
- L'édition des liens est cruciale car elle permet de combiner différents modules de code compilés (fichiers objets) en un seul programme exécutable. Elle résout les références externes entre ces modules, s'assure que toutes les fonctions et variables utilisées sont correctement définies et localisées, et intègre les fonctions nécessaires des bibliothèques. Sans cette étape, un programme composé de plusieurs fichiers sources ne pourrait pas fonctionner correctement.