Projet système PC : 2019 - GRAVALLON Guillaume, MOISSIARD Anael

De Ensiwiki
Aller à : navigation, rechercher

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

100 %

Cette phase est la plus complexe du projet. Elle nécessite peu de code, mais il faut absolument avoir bien compris ce que l'on veut faire et se documenter. Certaines pages de présentation des projets effectués les années précédentes ainsi que certaines ressources trouvables sur internet semblent nécessaires pour compléter les aspects de la spécification qui est en soit assez peu explicite sur certains points très techniques.

L'objectif est ici de mettre en place le mode utilisateur. Cela va permettre de lancer non plus des processus kernel, mais des processus utilisateurs, évoluant dans la zone mémoire dédiée aux processus utilisateurs, et qui vont interagir avec le kernel via des appels système.

Pour ce faire il faut tout d'abord bien comprendre ce qui se passe lors d'un appel système. Lorsqu'un programme utilisateur fait un appel système, il sauvegarde les registres dans sa pile, fait appel à l'interruption 49 qui va être traitée au niveau du kernel, réalise l'action requise et procède au retour d'interruption qui va permettre de repasser en mode utilisateur.

Lorsque notre programme se lance, on lance un processus idle qui est un processus kernel. L'objectif est que ce processus lance un autre processus qui lui sera le point d'entrée de tout ce qu'on va vouloir faire en mode utilisateur (dans notre cas, cela va être le processus exécutant la fonction user_start). Vient alors un problème: si on sait comment on voudra passer de user à kernel puis retourner à user grâce aux interruptions, on ne sait pas comment passer simplement du mode kernel au mode user au début. Pour résoudre ce problème on va donc simuler un retour d'interruption pour arriver en mode user. Pour simuler ce retour d'interruption, il va falloir mettre certaines données à des endroits précis afin de simuler l'état su système tel qu'il serait si on était arrivé en mode kernel non pas parce qu'on vient de lancer le système mais parce qu'on avait déclenché une interruption 49.

Pour simuler ce retour d'interruption, on va devoir maintenant créer non plus une seule pile kernel mais également une seconde pile utilisateur, et mettre dans la pile kernel certaines valeurs de sorte que l'instruction assembleur iret nous fasse sauter de la pile kernel à la pile user, pile user dans laquelle on trouvera l'adresse de la fonction user_start à exécuter.

Le déroulement souhaité est donc être le suivant:

  • Créer la pile user
  • Créer la pile kernel en mettant dedans les informations nécessaires
  • Appeler le contexte switch de sorte que la valeur d'esp permette de sauter dans une fonction assembleur kernel_to_user
  • Mettre certains registres à une valeur
  • Procéder au retour d'interruption qui va dépiler les données de la pile kernel
  • Sauter sur la fonction user_start

Une fois arrivé ici, nous sommes en mode user !

Il faut alors mettre en place une bibliothèque qui va réaliser les appels systèmes afin d’accéder aux fonctions implantées précédemment dans le kernel. Cette partie est assez triviale comparé à la première partie de la phase, et ne nécessite que de répliquer le code assembleur permettant de faire l'appel correctement.

Une fois cette phase terminée, les tests 1 à 18 et 20 peuvent êtres réalisés en mode utilisateur.