Projet système PC : 2016 - Valentin Ehkirch, Léa Klein, Elie Richaud

De Ensiwiki
Aller à : navigation, rechercher
MOOSE

Moose.png

Développeurs Valentin Ehkirch
Léa Klein
Elie Richaud

Présentation

Objectifs

Le projet système consiste en la réalisation d'un système d'exploitation basé sur une architecture de processeur Intel Pentium x86. Il comprend l'implémentation de diverses fonctionnalités telles que la gestion de processus et leur ordonnancement dynamique, la gestion de files de messages, la gestion d'entrées/sorties, une invite de commandes. Sa structure comprend un mode kernel et un mode user entre lesquels il alterne pour changer de niveau de privilèges.

Cahier des charges

Les spécifications de ce projet sont listées sur le wiki du projet : Projet système : spécification. Elles sont à réaliser en 7 phases distinctes.

Plannings

Planning prévisionnel

Previsionnel 2016 ehkirch klein richaud.png

Le planning prévisionnel présenté ici se base sur une division proportionnelle du temps en fonction de la difficulté estimée de chaque phase ainsi que sur la parallélisation possible de chaque étape.

Planning réalisé

Effectif 2016 ehkirch klein richaud.png

Le planning prévisionnel a globalement bien été respecté.

Une plus grande parallélisation des tâches a été mise en place, ce qui a permis de libérer du temps pour les phases complexes ou nécessitant plus de temps que prévu (eg. la phase 5 ou 7).

Etat du projet

Phase 1

Tâches:

  • Prise en main du projet
  • Gestion de l'affichage à l'écran


La prise en main des différents outils utilisés au cours du projet — qemu, vinagre et gdb — a été rapide. Nous avions en effet déjà utilisé ces derniers auparavant, notamment au cours de notre 1re année de cours à l'Ensimag.

Pour la gestion de l'affichage nous avons récupéré le code réalisé lors du cours de Logiciel de base de 1re année.

Aucune difficulté particulière n'a été rencontrée à ce stade du projet.

Phase 2

Tâches:

  • Création de processus
  • Changement de contexte entre processus
  • Gestion des interruptions déclenchées par un timer


Les spécifications complètes et claires ont été d'une grande aide pour la partie concernant les processus. Malgré tout, le changement de contexte a soulevé des questionnements et il a été nécessaire de s'accorder plusieurs moments de réflexion afin de comprendre pleinement le fonctionnement du context_switch.

Les TPs réalisés en première année en Logiciel de base ont été très utiles pour se rappeler les principes de fonctionnement du timer et des interruptions. Cela a donc permis de conclure cette partie assez rapidement.

Phase 3

Tâches:

  • Mise en place d'un ordonnanceur dynamique des processus
  • Gestion du cycle de vie du processus (démarrage, arrêt, attente)
  • Gestion de la filiation des processus


Plusieurs interrogations sur le comportement attendu des processus vis-à-vis de la filiation ont été formulées au sein du groupe. De même, nous avons passé du temps sur les valeurs de retour afin que celles-ci soient correctement transmises lors de la terminaison d'un processus.

Outre ces deux points, les spécifications techniques nous ont permis de franchir sans encombre la phase 3.

Phase 4

Tâches:

  • Gestion des files de messages
  • Gestion de l'endormissement des processus


À première vue simple, le comportement des files des messages a été quelque peu problématique. En effet, des spécifications pas toujours clairement explicitées ont engendrées une 1re implémentation des files non conforme à ce qui était attendu. Grace aux tests ainsi qu'aux explications fournies, ce défaut a pu être corrigé.

Avant cette phase, beaucoup de travail sur les processus avait déjà été réalisé. L'endormissement n'a représenté qu'un simple ajout et n'a, par conséquent, pas été problématique.

À la fin de cette phase, les tests fournis (à l'origine destinés aux phases 5 et plus) ont été adaptés afin de les faire fonctionner coté kernel. Cela a permis de régler des nombreux bugs avant d'entrer pleinement dans la phase 5.

Phase 5

Tâches:

  • Protection de la mémoire
  • Gestion des appels système
  • Protection d'exécution


Bien que peu de lignes de code soient à fournir pour faire fonctionner la séparation kernel/user, cette phase a été la plus complexe du projet. Elle a ainsi demandé une grande réflexion afin de comprendre comment fonctionne la protection mémoire.

La gestion des appels systèmes a été assez simple puisque celle-ci reprend le mécanisme d'interruption déjà vu lors des premières phases.

Enfin, l'utilisation en mode user des fonctionnalités existantes a permis de déceler de nouveaux bugs dans les phases précédentes.

Phase 6

Tâches:

  • Gestion des entrées/sorties du clavier


La gestion des I/O au clavier se basant principalement sur les interruptions, cette phase n'a pas présenté de difficulté majeure. En effet, le principe de fonctionnement est très similaire à celui utilisé pour les interruptions de la phase 2 (timer). Par la suite, il s'est avéré que le fonctionnement implémenté pour la fonction cons_read() était différent de celui attendu. Encore une fois, les tests fournis nous ont permis de déceler cette différence et de la corriger.

Phase 7

Tâches:

  • Ajout d'une invite de commandes


Nous avons récupéré une partie du code du TP Shell réalisé lors du cours de Système d'exploitation. N'ayant pas la nécessité d'une invite de commandes avancée, ce code a été simplifié au maximum et agit comme un simple parser du texte entré par l'utilisateur. Le shell propose les commandes suivantes :

  • calc - démare le calculateur
  • clear - nettoie l'écran
  • echo (on|off) - active ou désactive l'écho de la console
  • exit - quitte le shell
  • calc - lance le programme de démo réalisé pour la soutenance
  • help - affiche la liste des commandes disponibles
  • ps - affiche la liste des processus (numéro, état et nom) existant
  • sinfo - affiche la liste des sémaphores (numéro, compte et processus bloqués) existant
  • test [-o|-p] - lance les tests (tous par défaut, -p pour lancer les tests fournis, -o pour nos propres tests)


Améliorations:

Les fonctionnalités de base sont présentes, mais des nouvelles commandes peuvent être implémentées pour rendre le shell plus complet. Une meilleure gestion des commande, notamment concernant le parsing, est également à prévoir si l'on souhaite faire évoluer le shell.

Extensions

Sémaphores

Les 8 appels système ont été implémentés selon leur spécification. L'implémentation est d'une nature similaire aux files de messages. En effet, un sémaphore possède une file de processus en attente, que l'on doit réveiller progressivement au fur et à mesure que d'autres processus libèrent une place dans le sémaphore.

Il a fallu être particulièrement attentif aux interactions entre les sémaphores et d'autres appels système tels que kill ou exit. Lorsqu'un processus se termine prématurément, avant d'avoir libéré le sémaphore qu'il possède, il faut automatiquement le libérer.

Mode graphique

Le mode graphique consiste à exploiter le mode VGA 13h, permettant d'afficher 256 couleurs sur 320x200 pixels. Ce mode est disponible sur toutes les cartes graphiques compatibles VGA et est accessible en settant certains registres. Par la suite, on peut écrire dans la mémoire, pour changer la couleur d'un pixel ou pour changer une des 256 couleurs de la palette.

Grâce aux ressources disponibles sur OSdev.org, nous avons récupéré une partie du code mis à disposition par Chris Giese qui permet de basculer entre différents modes. Nous avons également pris exemple sur le guide VGA de DJ Delorie pour accéder aux palettes.

Pour les images utilisées, nous avons récupéré un élan [1] et créé le logo à partir de celui-ci et d'un texte [2]. Après édition sous GIMP et indexation en 256 couleurs, il suffit de les exporter en fichier .h pour en exploiter facilement les données.

Nous n'avons pas grandement exploité cette fonctionnalité, puisqu'elle sert uniquement au démarrage à l'heure actuelle. Avec plus de temps il aurait été intéressant de pouvoir l'intégrer à d'autres parties du système.

Screenshot1.png

Conclusion

Apports du projet

Ce projet nous a sensibilisé de façon à la fois didactique et intéressante à l'utilisation par le système d'exploitation des outils mis à disposition par le processeur afin d'implémenter certaines de ses fonctionnalités. Il a été très instructif de découvrir et d'implémenter les mécanismes, qui s'apparentent parfois à des astuces, servant à passer d'un processus à un autre, en jouant sur les registres, la pile d'exécution et les instructions de retour de fonction et d'interruption.

Le passage dans le monde utilisateur nous a donné un aperçu du cloisonnement mis en place dans les systèmes d'exploitation. Il a fallu être particulièrement rigoureux et méthodique dans cette étape qui nécessite plus de réflexion que de codage.