Projet système PC : 2016 - Jérémy RAKOTOARISOA, Thibaut BATAL

De Ensiwiki
Aller à : navigation, rechercher
OSselet
Os.jpg
Projet Système d'Exploitation 2016

Développeurs RAKOTOARISOA Jérémy
BATAL Thibaut]

Présentation

Objectifs

Le principal objectif de ce projet est de réaliser un noyau de système d'exploitation minimaliste permettant la gestion des processus (temps partagé, synchronisation entre processus) et des entrées-sorties (interpréteur de commande).

Cahier des charges

Le cahier des charges du projet est disponible sur l'Ensiwiki à l'adresse suivante: Projet système : roadmap. Ce cahier des charges expose une présentation générale des différents points importants à aborder au cours du projet. Pour nous simplifier la tâche, le projet se retrouve subdivisé en 7 étapes ordonnées qui nous permettent d'implémenter notre système d'exploitation de manière incrémentale. De plus, au sein de chacune des explications de ces phases se trouvent des liens vers des pages d'explications des concepts, qui nous ont énormément aiguillé lors de blocage sur certaines phases.

Gestion de projet

Organisation

Pour ce projet, nous avons choisi d'utiliser un board "Trello" pour suivre les avancées des différents membres de notre équipe (que nous avions déjà eu l'occasion d'utiliser).

Pour le suivi des tâches, nous avons procédé par flux : le tableau Trello a été découpé en 4 phases : product backlog (icebox), en-cours, tests, done. Il s'agissait de déplacer une tâche d'une colonne à l'autre au fur et à mesure de développement. Cela a permis de ne pas négliger les tests, et de prendre conscience du temps passé sur chaque tâche.

Pour les tâches critiques, nous avons soit binômé soit précisé les specifications en équipe. Dès lors que l'on rencontrait une difficulté quelconque, nous ajoutions des notes pour garder une trace et pour notifier l'ensemble de l'équipe. A ce système écrit s'ajoutait une communication spontanée à l'oral.

Concernant le code source, nous sommes partis sur l'utilisation de Git pour le versionner, afin de conserver un historique de nos modifications.

Planning prévisionnel

GanttPrevisionnelRJBTVV.png

Planning réalisé

GantEffectifRJBTVV.png

Réalisations

Phase 1 - Prise en main de l'environnement

Durée: 2 jours

L'objectif principal de cette phase est de prendre en main l'environnement de développement/test utilisé: - Qemu pour lancer une machine virtuelle - GDB pour le déboguage

Dans un second temps, nous avons mis en place l'affichage de caractères alphanumériques à l'écran. Cette partie se basant essentiellement sur les TPs de Logiciel de Base de l'année précédente, nous n'avons pas éprouvé de difficulté à réintégrer notre code au source du projet.

Phase 2 - Gestion des processus, changement de contexte

Durée: 1 jour

La phase 2 aborde des notions prépondérantes pour le projet: les processus et la gestion du basculement d'un premier processus à un second.

Il nous a donc fallu créer une structure de processus particulière contenant ses différents attributs, puis réussir à passer du contexte d'un processus à un autre. Cela nous a permis d'entamer l'ordonnancement à 2 processus, ce qui nous sera utile par la suite pour N processus.

Pour basculer du processus principal à un autre, nous avons du reprendre l'implémentation des interruptions matérielles de l'horloge des TPs de Logiciel de base de l'année dernière, et le code du changement de contexte nous avait été donné dans le cahier des charges du projet.

Le plus difficile restait de comprendre l'initialisation des structures de processus et la gestion de la pile.

Cette phase ne nous a donc pas non plus posé de problèmes particuliers.


Phase 3 - Gestion des processus, changement de contexte

Durée: 3 jours

Nous avons implémenté les différentes étapes de la vie d'un processus:

- Start: démarrage d'un processus. Cela nécessite de connaître la structure d'un processus, et d'initialiser la pile de ce dernier. Cela n'a pas posé trop de problème car le modèle avait été clairement établi à trois.

- Terminaison: la terminaison peu s'effectuer de diverses manières et présentes de nombreux pièges algorithmiques. La terminaison peut prendre plusieurs formes: exit (le processus se termine de lui-même) ou kill (il est tué par un autre processus). Dans les deux cas, il faut libérer les espaces alloués et gérer correctement le changement d'état du processus. Il faut également penser au père qui pourrait être en attente de sa mort, et aux fils qui ne doivent pas survivre à leur père.

- Etat bloqué: lorsqu'un processus est en attente d'un événement (une information, un timing, la mort d'un fils, etc..), il ne doit plus prendre du temps processeur. Il faut pouvoir le réveiller au bon moment. Cet état a été rapidement développé.

- Waitpid: en lien avec la terminaison, la fonction waitpid permet de bloquer un processus jusqu'à la mort d'un de ses fils. Elle a nécessité quelques phases de débuggage, en lien avec la terminaison, pour s'assurer que le cycle de vie de tous les processus est respecté.

- Etat zombie: un processus qui a été tué passe en état zombie jusqu'à ce que son père le tue pour de bon, à sa propre mort ou lors d'un waitpid.


Phase 4 - Files de messages

Durée: 1 jour

Les processus peuvent communiquer via ses files de messages dans lesquelles on peu produire ou consommer des messages.

A leur création, les files de messages reçoivent une limite du nombre de messages qu'elles peuvent stocker. En conséquence, les processus doivent pouvoir être bloqués en attente de disponibilité des files.

Il a fallu veiller à ce qu'un processus qui meurt libère éventuellement sa place dans les files.


Phase 5 - Files de messages

Durée: 2 jours

La phase 5 n'est pas fonctionnelle.

Nous avons commencé par réfléchir à trois à la protection d'éxecution du code par niveaux de privilèges, et à l'utilisation des interruptions. Après ce brainstorming, les concepts nous sont apparus assez clairs.

Peu après avoir commencé ce chantier, nous avons décidé de nous consacrer aux tests des phases 1 à 4 et avons donc interrompu le développement de cette phase. Nous avons terminé le premier jet de code à la fin du projet, mais n'avons pas eu le temps de le débugguer.

Nous avons pu tester notre système d'interruptions et il fonctionne bien. D'ailleurs, l'horloge et le clavier l'utilisent.


Phase 6 Pilote de clavier

Durée: 1 jour

La phase 6 reprend le principe des interruptions matérielles (à l'instar des interruptions de l'horloge de la Phase 2). Nous n'avons donc pas eu de problèmes particulier pour implémenter les primitives correspondantes.

Phase 7 Shell

Durée: 1 jour

Cette partie semble être la plus intéressante du projet puisque nous pouvons personnaliser notre OS à souhait avec notre interpréteur de commande. Cependant, nous avons fait cette partie côté noyau puisque la phase 5 n'était pas totalement implémenter. Les différentes commandes de notre shell sont les suivantes:

  • echo - active ou désactive l'écho de la console
  • exit - quitte le shell
  • kill <pid> - tue le processus de pid <pid>
  • start <nom_processus> <priorité> - démarre le processus <nom_processus> avec la priorité <priorité>
  • ps - affiche la liste des processus
  • sleep <nb_secondes> - met le shell en attente <nb_secondes>
  • test [num_test] - lance les tests de la partie utilisateur en mode noyau
  • help - affiche l'aide pour connaitre les commandes disponibles
  • clear - efface l'écran
  • print <chaine> - affiche <chaine>
  • chprio <pid> <priorité> - change la priorité du processus <pid> avec la priorité <priorité>