Projet système PC : 2021 - Benjamin CATHELINEAU, Halima MOUNSIT, Thomas MAGNIN

De Ensiwiki
Aller à : navigation, rechercher
DetresseOsScreenShot.png
Titre du projet DetresseOS
Cadre Projet système

Équipe Benjamin CATHELINEAU, Halima MOUNSIT, Thomas MAGNIN
Encadrants Mathieu BARBE


BIENVENUE SUR LA PAGE ENSIWIKI DE DestresseOS


Objectif

Dans la continuité des cours au seins de l'ENSIMAG, ce projet système a pour objectif principale l'élaboration, à partir d'un squelette fourni, d'un noyau fonctionnel de système d'exploitation sur une architecture RISCV.


Équipe

Nous sommes tous les 3 des étudiants de deuxième année de la filière ISI.

Benjamin CATHELINEAU

Halima MOUNSIT

Thomas MAGNIN

Organisation

En plus du discord commun à toutes les équipe (PCSEA_x86, sur lequel il y avait aussi les équipes RISCV), nous avions également notre propre groupe discord. Nous avons fait beaucoup appel à l'enseignant, Mathieu Barbe, tout au long du projet, car il y a beaucoup de détails à connaître pour RISCV et nous nous posions beaucoup de questions. Nous le remercions donc pour son aide. Nous avons beaucoup utilisés le peer programing, surtout vers la fin du projet, cela nous a permis de régler certains problèmes presque impossibles à détecter sans un regard extérieur. Nous utilisions régulièrement notre Discord pour communiquer ainsi que les issues de Gitlab pour avoir une vision globale de notre projet.

Nous nous somme répartis le travail en suivant les grands axes du projet (Interruptions, Mémoire virtuelle, Gestion des processus, ...). Au fur et à mesure, chacun de nous s'est spécialisé dans l'une de ces parties mais toujours en gardant une bonne vision globale grâce aux réunions discord.

Phases du développement

Phase 1 : Prise en main et gestion de l'affichage à l'écran

100 %

En ce qui concerne la prise en main, ce ne fut pas si facile, car certains membres du projet avaient l'habitude de travailler sur les PC de l'ensimag, hors ça n'était pas possible ici (en tout cas dans un premier temps), car ces derniers n'avaient pas la bonne version de qemu. Il a donc fallut installer l'environnement sur nos PC personnel, heureusement une image docker était fournie. L'affichage à l'écran était fournis. (fichier cons_write.c)

Nous avons rapidement réussi à passer en mode superviseur même s'il a fallu de plonger dans la Spécification RISCV qui peut sembler compliquée au début. Finalement elle s'est avérée bien construite et très utile tout au long du projet notamment pour la partie mémoire virtuelle qui diffère du projet x86.

Phase 2 : Gestion basique des processus

100 %

La gestion basique des processus, c'est à dire en mode noyau, fut simple à un détail près. Le contexte switch n'était pas fourni, et il fut assez compliqué de l'écrire correctement (notamment l’interfaçage avec la sauvegarde de contexte déjà faite dans le traitant d'interruption), mais nous y sommes arrivés. La gestion du timer, pour faire des interruptions qui permettent de changer de processus, est assez guidée et ne fut pas si compliquée.

Phase 3 : Gestion avancée des processus, en mode noyau

100 %

Une fois l'obstacle du context switch franchi (enfin nous pensions mais nous faisions encore des lw(c'est à dire 32 bits) au lieu des ld(64 bits), ce qui a causé des problèmes) les fonctions "avancées" n'étaient pas si compliquées car certaines avaient déjà été abordée avant (l’ordonnancement en mode tourniquet par exemple). La partie la plus dure fut la gestion de la terminaison des processus, implicite qui nécessitait de mettre l'adresse de ra avec la valeur de exit mais aussi de gérer correctement le nombre d'états grandissant que pouvait prendre un processus. L'ordonnanceur nous a aussi posé quelques problème notamment lors de l'ajout des files de messages (voir plus bas).

Phase 4 : Communication inter-processus et endormissement

100 %

La communication inter-processus, avec les files et la mémoire partagée nous a occupé tout le long du projet. (maudi test13 sur les files). Les autres étapes furent démarrées en parallèle.

Les files de message nous ont posé un certain nombre de problèmes et nous ont forcé à revoir la conception de notre ordonnanceur et la structure de nos processus. Nous avons toutefois réussi à obtenir une implémentation fonctionnelle. Chaque file est représentée par un tableau d'entier et deux files de processus (les bloqués en production et les bloqués en conso).

L'endormissement des processus, ayant été abordé précédemment et PCSEF, fut une formalité.

Phase 5 : Utilisation de la mémoire virtuelle et passage en mode utilisateur

100 %

Nous avons débuté le travail concernant la mémoire virtuelle dès le début du projet avec la réalisation d'un distributeur de frame de 4K. Cette partie est restée en suspend jusqu'à la réalisation du mode superviseur, du système de processus et du portage des premiers tests.

Nous avons ensuite commencé à développer une API permettant de mettre en place de nouveaux directory et de mapper des pages à l'intérieur en récupérant les adresses virtuelles correspondantes.

Cette mémoire virtuelle a ensuite été utilisée pour les processus en mode user afin de séparer les espaces mémoire.

Enfin nous avons développé l'API de mémoire partagée permettant le partage de pages entre processus. Les pages allouées sont stockées dans une liste chainée. Nous utilisons un système simple qui compte pour chaque page virtuelle le nombre de processus ayant une référence vers cette page. Chaque fois qu'une page est acquise/libérée, le compteur est incrémenté/décrémenté. S'il tombe à 0, la page est démappée et la frame physique correspondante libérée. Si un processus "oublie" de release une page partagée et est tué, on force la libération en décrémentant le compteur lors de sa mort.


En ce qui concerne le mode user, ce fut plus simple que ce nous pensions mais nous avons mis du temps à nous lancer (en réalité nous avons commencé dans les deux dernières semaines, en comptant l'extension accordée par le généreux Mathieu Barbe, ainsi que Gregory Mounié). Les system call furent simples à implémenter car le code traitant était exactement le même pour chacun d'entre eux. Il y a quelques "broutilles" en assembleur non triviales à écrire également mais nous y sommes arrivés à force de gdb et de réflexion.

Phase 6 : Création d'un pilote de clavier

99 %

Cette étape fut commencée avant le mode user (pour "multiplexer" le travail). Ce ne fut pas simple et le code est passé par plusieurs réécritures. En effet il y avait des problèmes si plusieurs caractères étaient écris en rapide succession (martyriser son clavier par exemple). Le code actuel fonctionne assez bien mais il serait malhonnête de dire qu'il est parfait. Si de nombreux caractères sont tapés en rapide succession, certains effacés puis réécris, alors la chaine sera mal reconnue. Cependant, cela ne bloque pas au moins le shell par exemple, puisqu'il va juste voir que la commande est fausse et juste en "redemander" une nouvelle. Les tabulations ne sont pas supportées également.

Phase 7 : Développement d'un Shell

100 %

Il y a un shell pour le mode user et un shell pour le mode superviseur. Ces deux shells sont bien plus simplistes que le shell du SEPC du premier semestre, ils ont donc été simples à écrire (basiquement un while(1) sur un cons_read et start).

Phase d'extension

0 %

Pas eu le temps malheureusement, une semaine de plus aurait été appréciée :). Nous étions attirés par l'extension du système de fichier particulièrement.

Journal de bord

Du 04/02/2021 au 04/03/2021 - Mise en place du projet et première étapes

  • Prise en main de l'environnement, exploration des sources fournies
  • Installation de l'environnement avec docker, ou de la toolchain pour Thomas.
  • Debut de la gestion des interruptions timer
  • écriture de fichier assembleur pour prendre en charge ces interruptions.
  • Distributeur de frame physiques

Du 04/03/2021 au 04/04/2021 - Processus en mode noyau, clavier

  • implémentation d'une gestion des processus en mode noyau (Struct processus, primitive start)
  • ordonnancement entre ces processus
  • implémentation des primitives systèmes en mode noyau (getpid, chprio, wait_clock,...)
  • implémentation de la gestion du clavier (ce ne fut pas simple), primitive cons_read


Du 04/04/2021 au 07/05/2021 - Mode user et mémoire virtuelle, finition du projet

  • Dans un premier temps : port de tout les tests en espace noyau
  • Création de directory et mappage/démappage de pages en mémoire virtuelle
  • également : ajout des primitives supplémentaires, tel que la gestion des files et la mémoire partagés, qui nécessitent donc la mise en place de la mémoire virtuelle
  • API de partage de pages en mémoire virtuelle
  • Puis mode user, et tout ce que cela implique (appels systèmes)
  • Nettoyage du code, écriture de la page de wiki