Projet système PC : 2019 - DAMAY Theodore, DEBEAUPUIS Enguerran, KRAUTH Lucille, LIM Olivier, DUBOIS Florian, TAVEAU Alexandre

De Ensiwiki
Aller à : navigation, rechercher


Cette page a pour but de présenter le travail réalisé dans le cadre du Projet système.


Présentation

L'objectif de ce projet est de réaliser le noyau d'un système d'exploitation sur une architecture Intel x86. Ce système doit permettre de réaliser les opérations suivantes :

  • Création et l'exécution des processus
  • Leur synchronisation et leur ordonnancement
  • Gestion des entrées/sorties (clavier, écran)
  • Implémentation d'un interprète de commandes

Équipe

Notre équipe se compose de six membres, tous issus de la filière SEOC :

Répartition des tâches

Théodore
  • Ordonnancement
  • Mémoire virtuelle
Enguerran
  • Mémoire virtuelle
  • Ordonnancement
Lucille
  • Mémoire virtuelle
  • Communication entre les processus
Olivier
  • Implémentation de la communication et synchronisation entre les processus via les files de messages
  • Tests
Florian
  • Création et terminaison dynamique des processus
  • Tests
Alexandre
  • Gestion du clavier et implémentation d'un pilote de console
  • Mémoire virtuelle

Réalisation

Phase 1 : Gestion de l'affichage de l'écran

100 %

Cette partie consiste à se familiariser avec les outils de travail, notamment ceux de débogage et QEMU.
Pour réaliser l'affichage, nous avons importé le code que nous avons conçu pendant le premier semestre en PCSEF.

Phase 2 : Création et lancement de processus de niveau noyau

100 %

Cette étape consistait à créer de premiers processus et à les lancer au niveau kernel, il fallait notamment lancer idle avec une priorité adéquate, afin d'assurer qu'il y ait toujours un processus qui tourne. Cela a été relativement aisé au vu du travail réalisé au premier semestre, qui avait été assez bien compris par les membres du groupe.

Phase 3 : Ordonnancement, création dynamique et terminaison de processus de niveau noyau

100 %

L'ordonnanceur est extrait de nos projets PCSEF. Il se contente de choisir un processus disponible à ordonnancer et fait appel à la fonction fournie en assembleur context_switch (ctx_sw) pour changer de processus. La création de processus est dynamique, comme dans les derniers cas réalisés lors du premier semestre. La terminaison de processus a dû être améliorée par rapport au travail déjà réalisé, par exemple pour permettre de débloquer le père et de notifier les autres fils de ce père qu'il est débloqué. Nous avons également modifié la fonction start qui constitue l'entrée du système. Nous avons également eu besoin de créer une fonction chprio permettant de changer les priorités des processus au cours de l'exécution.

Phase 4 : Gestion des communications et synchronisation de processus de niveau noyau

100 %

Les files de messages permettent aux processus de communiquer et se synchroniser entre eux. Les processus se bloquent en envoi ou en réception de messages. Par exemple, un processus sera bloqué en attente d'un message et pourra être débloqué par un autre en envoyant un message ou en réinitialisant la file de messages.

Phase 5 : Séparation des espaces mémoire noyau et utilisateur : gestion de processus utilisateur

40 %

Cette partie a été la plus difficile à implémenter. Dans les sources nous avions déjà au préalable une gestion du page directory pour la partie kernel, il s'agissait donc de gérer correctement le reste, notamment en stockant les bonnes valeurs dans le registre cr3, ce qui n'a pas été évident au niveau de la compréhension. Il a fallu également gérer les "page table", mais la partie la plus délicate a été de comprendre correctement la façon dont fonctionne la pile (notamment lors d'un context switch) pour séparer les données relatives à chaque processus, ce qui se passe différemment dans le cas des processus kernel et user. Des registres supplémentaires ont été nécessaires (SS, ESP etc pour la pile kernel par exemple). Nous nous sommes arrêtés sur un bogue bloquant que nous n'avons pas eu le temps de faire examiner par un enseignant, et n'avons donc pas pu ni tester ni compléter notre implémentation.

Phase 6 : Gestion du clavier et implémentation d'un pilote de console

70 %

Le clavier est géré par interruption : lors de l'appui d'une touche, une fonction est appelée qui permet de traduire le scancode obtenu en caractère. Ce caractère peut être affiché à l'écran si l'écho est activé. Il est de plus stocké dans le buffer associé au clavier. Cependant, le blocage du processus pour attendre que des caractères soient tapés n'est pas géré.

Phase 7 : Implémentation d'un interprète de commandes

0 %

Nous n'avons pas implémenté la phase 7, bien que nous ayons déjà réalisé un programme similaire en SEPC, nous n'avons pas eu le temps de l'adapter à ce projet.

Résultats

Nous avons réussi à créer un système d'exploitation avec une bonne gestion de l'écran et des interruptions, et avons atteint les objectifs premiers qui étaient de permettre la création et la gestion (ordonnancement en particulier) de processus. Notre système permet également de tuer/libérer des processus, et leur permet de communiquer entre eux. Le système a également à sa disposition un allocateur de mémoire physique fonctionnel, et un allocateur de mémoire virtuelle qui comporte encore certaines erreurs. La séparation des privilèges au niveau utilisateur et noyau n'est pas totalement implémentée. Nous avons commencé l'implémentation d'un shell interactif, avec la gestion des entrées et sorties, mais l'interpréteur de commandes n'est pas encore fonctionnel.

Journal de bord

Semaine 1 - Du 04/02 au 08/02/19

  • Configuration du git
  • Lecture du sujet
  • Prise en main des codes fournis
  • Début d'implémentation de la gestion des processus

Semaine 2 - Du 11/02 au 15/02/19

  • Mise en place de la gestion de l'écran implémentée lors du cours de PCSEF
  • Suite implémentation de la gestion dynamique des processus. Ordonnancement commencé avec file de processus à priorité
  • Gestion des interruptions

Semaine 3 - Du 18/02 au 22/02/19

  • Poursuite implémentation ordonnancement et file de processus
  • Ajout terminaison et endormissement des processus
  • Début implémentation file de messages
  • Modification des tests d'ordonnancement
  • Début de la gestion du "exit"

Semaine 4 - Du 04/03 au 08/03/19

  • Améliorations notables de getpid et d'exit
  • Modifications au niveau des allocations, notamment ajout de malloc.h
  • Ajout de la primitive chprio
  • Fonction permettant de tuer des processus terminée

Semaine 5 - Du 11/03 au 15/03/19

  • Modifications de certains éléments dans la structure du projet
  • Améliorations d'éléments concernant l'horloge, afin de passer un maximum de tests

Semaine 6 - Du 18/03 au 22/03/19

  • Ajout d'une liste chaînée de processus, puis d'une file de processus
  • Ajout du processus idle et factorisation du code de waitpid
  • Ajout de la libération des processus
  • Début de la pagination : mise en place du squelette du code

Semaine 7 - Du 25/03 au 29/03/19

  • Tests sur les files de messages et améliorations diverses
  • Résolutions de quelques problèmes dus à une mauvaise gestion du git de notre part
  • Travail de compréhension sur la mémoire virtuelle

Semaine 8 - Du 01/04 au 05/04/19

  • Résolution d'erreurs sur les files de messages
  • Travail sur la mémoire virtuelle

Semaine 9 - Du 08/04 au 12/04/19

  • Suite du travail sur la mémoire virtuelle : en particulier gestion du cr7, après des erreurs de compréhension

Semaine 10 - Du 15/04 au 19/04/19

  • Début de la gestion de la console et du clavier
  • Mémoire virtuelle (notamment utilisation des différentes piles) et privilèges d'accès

Semaine 11 - Du 29/04 au 03/05/19

  • Gestion de la console et du clavier
  • Encore du travail sur la mémoire virtuelle
  • Travail sur les privilèges et la séparation des parties kernel et utilisateur

Difficultés rencontrées

Recherche d'informations

Dans un premier temps, nous avons tenté de nous contenter de la documentation fournie sur l'Ensiwiki pour développer nos différentes phases. Il s'avère qu'il était attendu que nous nous renseignons dans la documentation Intel ou autres sources (livre de Andrew Tanenbaum), auxquels nous avons eu recours trop tard dans le projet.

Mémoire virtuelle

Nous avons rencontré de grosses difficultés de compréhension sur la réalisation de la mémoire virtuelle. Notre connaissance était très succincte et mésestimait le travail à accomplir. Elle consistait simplement en la connaissance d'une page directory avec des pages tables et un registre cr3 qui pointait vers la page directory. Nous avons progressivement découvert les étapes supplémentaires, en particulier la gestion côté user et côté kernel et de leurs autorisations, qui sont très différentes. Comprendre comment les processus s'exécutent dans un environnement isolé, dans lequel ils ont accès à un espace mémoire qui est très loin de ressembler à ce à quoi ils ont accès est très perturbant. Nous avons rencontré un bogue bloquant sur lors de l'initialisation de la mémoire, qui, peu avant le rendu, nous a empêché de terminer cette partie.

Répartition des tâches

Nous avons voulu travailler de manière incrémentale sur ce sujet, en réalisant progressivement les phases proposées en parallèle, or, à la phase 5 nous n'avons pas pu se répartir le travail au sein d'une même phase, et nous avons perdu beaucoup de temps là où nous aurions pu notamment nous avancer sur la phase 6 puis 7.

Conclusion

Ce projet nous a permis d'approfondir notre connaissance des systèmes d'exploitation, notamment de leur gestion de mémoire. Nous avons passé beaucoup de temps sur la mémoire virtuelle, ce qui premièrement nous a convaincu de son utilité, et deuxièmement nous a permis de mieux comprendre son implémentation - en particulier pour bien distinguer toutes les notions de pagedir et pagetable par exemple, souvent évoquées dans divers cours mais sans utilisation concrète. Le fait de travailler de façon incrémentale nous a apporté une meilleure compréhension de la conception des premiers systèmes d'exploitation, et nous avons globalement apprécié cet aspect historique du travail réalisé. Ce projet nous a également permis de mieux appréhender la différence entre la compréhension théorique et la compréhension pratique du fonctionnement d'un système, et les limites imposées. Nous avons pu travailler de façon plus proche du matériel, ce qui est une chose intéressante à faire pour avoir ensuite une meilleure vue d'ensemble du fonctionnement global d'un ordinateur.