Projet système PC : 2019 - COURTOIS Brian, DEPREUX Rémi, EJ-JENNANE Gloria, LASBLEIS Corentin, LEVOTRE Antoine, MOREAU Antoine

De Ensiwiki
Aller à : navigation, rechercher

Sommaire

Présentation

Le but de ce projet est d'implémenter notre propre noyau de système d'exploitation. Ce projet fait suite au projet PCSEF du premier semestre. Ce wiki présentera les différentes phases que nous avons réussi a implémenter, le journal de bord du projet ainsi que les difficultés que nous avons rencontrées.

Equipe

Membres

Pour ce projet, notre équipe est constituée de 6 membres :

Groupes de travail

Nous avons décidé de former 3 binômes pour paralléliser le travail, nous avons donc formé les groupes suivants :

  • Antoine Moreau et Corentin (Phases 2 et 5)
  • Antoine Levotre et Brian (Phases 1 et 4)
  • Gloria et Rémi (Phases 3 et 6)

La répartition du travail en binôme n'a pas été stricte non plus tout le temps. Il arrivait que certains abordent les phases des autres pour les aider ou faire profiter des connaissances acquises dans leurs parties si cela était pertinent.

Planning

Planning prévisionnel

Au début du projet nous avons décidé de mettre en place un planning prévisionnel afin de se donner un objectif. Nous avons bien essayé de prendre en compte la difficulté des différentes phases (notamment la phase 5 qui a l'air d'être celle qui pose le plus de soucis).

Planning v1.png

Planning réalisé

Planning realise.png

Les phases 3, 4 et 5 ont pris beaucoup plus de temps que prévu. Pour la phase 5, c'était prévisible (nous avions déjà prévu plus de temps pour cette phase que pour les autres).

Réalisation des différentes phases du projet

//TODO 1) Dire ce qu'il a été fait 2) Indiquer les éventuelles difficultées 3) Mettre à disposition des captures d'écran si cela est pertinent/vidéos de démo 4) Mettre à disposition le binaire du noyau pour le tester dans un émulateur

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

100 %

La phase 1 a été relativement rapide dû au fait que les fonctionnalités à implémenter avaient déjà été vues en PCSEF. Rien de particulier n'est à relever pour cette partie, les différentes fonctionnalités sont opérationnelles.

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

100 %

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

100 %

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

100 %

La gestion des messages a été plus longue que prévue à gérer du fait de la complexité des différentes fonctionnalités. Nous avons mis du temps à comprendre comment les différentes fonctions devaient interagir entre elles.

Ceci étant dit, la gestion des messages est opérationnelle. Le point délicat est encore la gestion de preset.

Pour wait_clock, on passe le test de base décrit dans la spécification et il passe nos tests personnels l'utilisant.

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

90 %

La mise en place de la mémoire virtuelle et de la séparation des espaces mémoire et noyau n'a pas été finalisée avec succès, mais nous avons mis en place la plupart des mécanismes nécessaires à son execution


Allocateur de Mémoire physique

La première étape de cette phase a été de mettre en place un allocateur physique. Dans la mémoire physique, l'espace en 0 et 64Mo est reservé au kernel : nous allouons donc des cases de 4Ko entre 64Mo et 256Mo. A chaque début de case, on met l'adresse de la prochaine case libre, et on garde en mémoire l'adresse de la première case libre.


Initialisation du page directory

Chacun des processus ayant sa propre structure de pagination, il a fallu initialiser un page directory a chaque création de processus, et stocker son adresse parmi les registres du contexte d'execution. Nous copions alors le page directory propre au kernel dans ce nouveau page directory, étant donné qu'ils partagent tous la traduction 1:1 coté kernel.


Module de mapping

la fonction mm_map permet de mapper une adresse virtuelle à une adresse physique, c'est à dire de remplir les pages des tables (de les créer si besoin) pour lier l'adresse virtuelle à l'adresse physique. C'est aussi ici que vous devons gérer les flags, ce qu'on pense être mal fait dans le projet.


Edition du context switch

Au changement de processus, il faut également changer le CR3, car les adresses virtuelles peuvent être les mêmes, mais pointent vers différentes adresses physiques. Ainsi, l'adresse du page dir d'un processus étant stocké dans le contexte d'execution, passé en paramètre du context_switch, nous éditons le registre cr3 directement dans le context_switch avec le nouveau page dir du nouveau processus.


Passage en mode User (Ring 3)

C'est sur cette partie délicate que nous nous sommes arrêtés. Le passage du mode Kernel au mode User se fait via l'instruction d'assembleur "iret". Seulement, iret a besoin de dépiler plusieurs paramètres, qui sont automatiquement empilé à l'execution d'une interruption. Dans notre cas, aucune interruption n'empile ces valeurs : nous avons donc simulé cet empilement avec le programme "iret_ass". Les valeurs à empiler sont :


Pile kernel
   +-----------+
   |   *EIP*   |     --> L'adresse du code à executer après le iret
   +-----------+
   |    *CS*   |     --> Le segment de code, dans notre cas, 0x43
   +-----------+
   | *EFLAGS*  |     --> Les flags, qu'on set à 0x202
   +-----------+
   |   *ESP*   |     --> La valeur de la pile User du processus (Ici, 4Go - 2 (1 pour le code, deux pour l'argument)
   +-----------+
   |   *SS*    |     --> La segment de pile, 0x2B ici.
   +-----------+
Gestion de la symbol_table

La symbol_table est une table qui contient les structures d'application de toutes les applications users (struct uapps). Cependant, l'accès à une structure d'application est alors en O(n), nous avons donc transformé cette liste en table de hachage qui contient ces structures. Lors d'un appel à la fonction start, un nom est passé en paramètre. Si ce nom est dans la hash_map, alors c'est une application user, et on l'instancie telle quelle (même si ça ne marche pas). Sinon, si ce nom n'apparait pas dans la hash_map, on en déduit qu'on lance un processus kernel, et on prend comme code à executer le pointeur passer en paramètre.

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

50 %

Le but de cette phase est d'implémenter un pilote de console. Bien que la phase 5 ne soit pas terminé, nous avons décidé de commencer à travailler sur la phase 6 pour avancer. Le fonctionnement de cette phase ne peut donc pas être complètement testé, mais nous avons essayer de comprendre son fonctionnement et de l'implémenter.

Nous avons donc implémenté les fonctions suivantes :

  • keyboard_data : void keyboard_data(char *str)
  • cons_read : unsigned long cons_read(char *string, unsigned long length)
  • cons_write : int cons_write(const char *str, long size)

Nous avons dans un premier temps laissé de coté la fonction kbd_leds pour nous concentrer sur les 3 fonctions décrites ci-dessus.

Chaque fois qu'une touche du clavier est enfoncée, il faut lancer une interruption. Nous avons donc défini le traitant d'interruption traitant_IT_9 sur le même modèle que le traitant_IT_32. Nous avons mis un peu de temps à comprendre comment écrire la fonction réalisant le traitant de l'interruption, car le type d'interruption pour la gestion du clavier (IRQ1) est différent des interruption d'horloge (IRQ0).

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

0 %

Journal de bord

Première semaine

05/02/2019

  • Prise en main de l'environnement
  • Lecture du sujet
  • Récupération du projet sur le Git

08/02/2019

  • Lecture du sujet
  • Formation des binômes de travail
  • Début de la gestion de l'affichage à l'écran

Deuxième semaine

13/02/2019

  • On continue la phase 1 (gestion de l'affichage)
  • Début de la phase 2 (gestion des processus)
  • Elaboration d'un premier planning prévisionnel

15/02/2019

  • On continue la phase 2 (gestion des processus)
  • Début de la phase 3 (ordonnancement)

Troisième semaine

20/02/2019

  • On continue la phase 3 : gestion de l'ordonnancement, de l'endormissement et de la terminaison de processus (pour l'instant on ne gère pas les états bloqués)
  • Phase 2 presque terminée (gestion des interruptions)
  • Début d'implémentation d'un système pour automatiser les tests
  • Le planning est trop bien respecté pour l'instant, c'est quand même super cool, tout le monde est content

22/02/2019

Quatrième semaine

06/02/2019

  • On continue la phase 3
  • Début de la phase 4
  • Implémentation de tests pour la phase 2

08/03/2019

  • Tests sur la phase 3
  • On continue la phase 4
  • Pour la phase 4, un peu de difficulté à comprendre comment on gére l'accès aux processus

Cinquième semaine

13/03/2019

  • On continue la phase 3. Petits bugs au niveau de l'endormissement et de la terminaison des processus à gérer.
  • La phase 4 suit son cours
  • Début de lecture de la documentation pour la phase 5

15/03/2019

  • Découverte de Minetest
  • Documentation et tentative de compréhension de la mémoire virtuelle

Sixième semaine

20/03/2019

  • Documentation et tentative de compréhension de la mémoire virtuelle
  • Développement des files de messages pour les processus
  • Debuggage de la phase 3 sur l'ordonnancement

22/03/2019

  • Documentation et tentative de compréhension de la mémoire virtuelle
  • Développement des files de messages pour les processus
  • Debuggage de la phase 3 sur l'ordonnancement

Septième semaine

27/03/2019

  • Documentation et tentative de compréhension de la mémoire virtuelle
  • Développement des files de messages pour les processus
  • Debuggage de la phase 3 sur l'ordonnancement

29/03/2019

  • Compréhension de la mémoire virtuelle. Attention, ça va casser.
  • Développement des files de messages pour les processus
  • Debuggage de la phase 3 sur l'ordonnancement

Huitième semaine

03/04/2019

  • Débuggage des files de messages pour les processus
  • Fin de la phase 3 sur l'ordonnancement

05/04/2019

  • Débuggage des files de messages pour les processus
  • Compréhension de la phase 6

Neuvième semaine

10/04/2019

  • Débogage des files de messages pour les processus. Aled
  • Tentative de début d'implémentation de la phase 6
  • Début du codage de l'allocateur physique

12/04/2019

  • Mémoire virtuelle :
    • Fin + Débogage + Tests Réussi pour l'allocateur physique. Un petit allocateur pour l'OS, un grand pas pour notre projet.
    • Codage du module de mapping addr_lin=>addr_phys;

Dixième semaine

17/04/2019

  • Implémentation de keyboard_data et cons_read pour la phase 6

19/04/2019

Onzième semaine

03/05

  • Mémoire virtuelle :
    • Codage d'une fonction init_pgdir + test (ca a l'air de passer)

Douzième semaine

06/05

  • Mémoire virtuelle :
    • Liste d'apps vers hash_map et modification de create_proc pour inclure la structure de pagination (A tester)
  • Phase 6
    • Implémentation de cons_write, phase 6 à tester

Difficultées rencontrées

  • Mémoire virtuelle

Cette partie a été très compliquée, notamment à cause de la multitude de sources d'informations qu'il était très facile d'oublier, ou qu'il était difficile à trouver. Ainsi, nous avons dû demander de l'aide à d'autre groupe, qui nous ont alors indiqué d'autres sources, dont plusieurs en dehors de ce wiki. Par ailleurs, la grande complexité de cette partie l'a rendu difficile à partitionner entre les différents membres de l'équipe.

  • Travail en groupe

Nous avons attribué les différentes phases à chaque binôme assez rapidement, cependant, le travail a été bien plus difficile pour les membres du binome travaillant sur la phase 5. Nous aurions pu constituer une plus grosse équipe pour cette phase, mais il n'est même pas sur que cela aurait été efficace compte tenu de la difficulté du travail à réaliser. Nous avons également eu du mal à mettre en commun notre travail car chaque binome travaillait de façon assez indépendante. Une communication plus efficace et des phases de mise en commun du travail plus fréquemment nous auraient sans doute évité une perte de temps.

  • Format des séances encadrées

Les séances encadrées étaient au nombre de deux séances de 1h30 par semaine. Une séance de 3h par semaine au lieu de deux de 1h30 (comme au premier semestre pour PCSEF) aurait sans doute été plus avantageuse.