Projet système PC : 2021 - D'EMMANUELE Valentin, VIGNAL Nathan

De Ensiwiki
Aller à : navigation, rechercher
Wizard of os.png
Titre du projet Wizard of OS
Cadre Projet système

Équipe Nathan VIGNAL Valentin D'EMMANUELE
Encadrants Yves Denneulin , Gregory Mounie, Patrick Reignier

Présentation

Ce projet consiste en l'implantation d'un noyau de système d'exploitation (kernel) en plusieurs étapes sur une architecture Intel x86.

Équipe

Nathan VIGNAL

Valentin D'EMMANUELE

Organisation

Nous nous répartissons le travail et effectuons des revues de code pour chaque commit.

Phases du développement

Phase 1 : Prise en main de l'environnement

100 %

Implémentation de la fonction console.putbytes en suivant les instructions du tp : premier TP de PSE. Pas de problème spécifique sur cette partie.

Conseils

  • La phase 1 est assez simple donc une personne suffit
  • Pour la tabulation le plus simple est de tronquer les 3 derniers bits du numéro de colone puis d'ajouter 8

Phase 2

100 %

Pour cette phase les deux TP que nous avons suivis sont :

Difficulté

  • Nous avions initialement mal géré la taille de la pile, nous donnions 4 fois plus de mémoire que ce qui était demandé.

Conseils

  • Seul Idle doit avoir un sti

Phase 3

100 %

Récupérer un processus

  • Avoir une table des processus indexé par pid nous permet de récupérer un processus en O(1), mais nécessite le recyclage des pids.

Filiation

  • Pour stocker les fils nous utilisions un code de liste chainé sous license "GNU Lesser General Public License", par soucis de simplicité nous sommes repassé sur la queue disponible directment dans le projet(queue.h). Dans cette queue nous trions les fils par Etat et avons fait en sorte d'avoir les fils Zombie en dernier en leur mettant le code de struct max, on trouve les fils zombies rapidement en parcourant par la fin.

Primitive système de gestion de processus

  • Nous avions quelques erreurs sur ces méthodes, les tests côtés kernel nous ont bien aidé à trouver nos erreurs.

Ordonanceur

  • Nous avions un problème caché pendant asssez longtemps dans l'ordonanceur : un processus élu ne pouvait le rester que si aucun autre processus n'était ready. Les tests kernel passait pourtant jusqu'au N°12.

Difficultés

  • Nous tentions de free le processus actuel dans ordonnance, ce qui ne peut pas marcher.(voir conseils ci dessous).

Conseils

  • Ne pas faire d'état "mort" pour les processus, ce n'est pas nécessaire, ormis le processus actuel on peut free les processus directement.
  • Attention on ne peut pas free le process actuel même dans l'ordonnanceur, car l'ordonnanceur tourne sur la pile du processus actuel.

tests

  • Nous avons utilisé les tests donnés pour le côté utilisateur afin de valider cette partie.

Phase 4

100 %

Nous avions commencer cette partie à l'aide d'un tampon rotatif pour stocker les messages, nous avons utilisé la queue fournis finalement par soucis de simplicité. Nous avons eu beaucoup de problèmes sur le test 13, nous avons repris notre code profondémment.

Conseils

  • Utiliser les queues pour se simplifier la tâche, un tampon rotatif est plus compliqué.
  • Bien penser aux cas spéciaux comme la mort d'un processus en attente de lecture/écritue

Phase 5

100 %

Création de processus user

  • On sauvegarde le sommet de la pile kernel dans la TSS lors du passage du mode kernel vers le mode user.
  • Pour passer vers le mode utilisateur on simule un retour d'interruption iret. On empile : le registre ss, l'adresse de la pile user, les flags (0x202 pour réactiver les interruptions en mode user), le registre cs et la prochaine instruction à executer (registre eip). On change également les registres fs, gs, ds et es avec 0x4b qui correspond au user data segment.

Exécution de processus user

  • Pour revenir côté système à partir du mode user, on passe par les appels systèmes. Pour cela, on a développé une bibliothèque d'appel système qui s'occupent de sauvegarder les registres et d'enregistrer les paramètres de l'appel dans les registres avant de faire une interruption 49 pour retourner côté système.
  • On gère l'interruption 49 par un traitant. Le traitant regarde sur le registre eax quel appel système est demandé et on récupère les arguments des registres qui sont ensuite empilés selon la convention d'appel C pour appeler notre syscall handler écrit en C. On appelle ensuite la fonction demandée par l'utilisateur.
  • Les registres de rang (ds, es, fs et gs) doivent TOUJOURS être positionnés avec la bonne valeur (0x4b en mode user, 0x18 en mode kernel). Ils ne sont pas modifiés automatiquement par les appels à int 49 ou à iret contrairement à cs et ss. Il est absolument nécessaire de le modifier dans chaque traitant d'interruption, ce qui inclut aussi le traitant d'horloge.

Phase 6

100 %

L'objectif de cette phase est d'écrire un pilote pour clavier. Il faut créer le traitant de l'interruption lié au clavier. Nous avons utilisé un buffer rotatif pour l'implémentation du buffer. La fonction à implémenter est keyboard_data.

Conseil

  • Ne pas oublier d'acquiter les interruptions

Phase 7

100 %
  • Pour le shell, nous avons repris un skelette de code de shell par G. Mounie ensimag-shell sous licence GPLv3+.
  • Nous avons réaliser une commande help
Commandes disponibles sur Wizard of OS
  • Nous avons également une commande sysinfo
sysinfo de Wizard of OS

Extensions

  • Commande CTRL + C permettant de tuer le processus intéractif(en attente sur IO) le plus prioritaire ou à défaut le processus élu.
  • Appel système sleep permettant de dormir n secondes
  • Commande clear permmettant de nettoyer la console
  • reboot : Appel système utilisable en tant que commande. Permet de redémmarer le système.
  • Gestion des segmentation faults : on kill les processus qui émettent des exceptions d'erreurs de page. Vu que la mémoire virtuelle n'est pas demandée pour les apprentis, toutes erreurs de page signifient que le processus a un comportement anormal.

Journal de bord

Semaine 1

Lundi 7 juin

  • Changement de contexte et horloge.
  • Début Implémentation de la fonction console.putbytes en suivant les instructions du tp : premier TP de PSE.

Mardi 8 juin

  • Fin console.putbytes.
  • Création de processus
  • Ordonnanceur

Mercredi 9 juin

  • Debug
  • Primitives systèmes : chprio, getPrio, getPid, wait_clock(début)

Jeudi 10 juin

  • Primitives systèmes : wait_clock, kill
  • Exit et return
  • Préparation gestion des messages
  • Débug taille de la pile, taille maintenant bien en octet

Vendredi 11 juin

  • Début de création de tests kernel à partir des tests utilisateurs
  • Début filiation + waitpid

Semaine 2

Lundi 14 juin

  • Filiation + waitpid ok
  • Sleep

Mardi 15 juin

  • Tests kernel jusqu'au 7

Mercredi 16 juin

  • Début message
  • Test 8 et 9 ok

Jeudi 17 juin

  • Test 10 à 12 ok
  • Kernel vers userspace
  • Userspace vers kernel
  • Return et exit

Vendredi 18 juin

  • Debug pour test 13
  • Appels systèmes

Semaine 3

Lundi 21 Juin

  • Debug mode user
  • Fix makefile : mauvais ordre de création des .o
  • test ->5 ok en usermode

Mardi 22 Juin

  • Phase 5 ok
  • Début gestion clavier
  • Debug scheduler

Mercredi 23 Juin

  • Test 13 -> 18 et 20 ok. Debug partie message
  • Test 9 ok côté utilisateur désormais après correction dans la façon de faire l'appel système.
  • Bannière du terminal

Jeudi 24 Juin

  • Ajout appel système manquant current_clock
  • Cons_read et cons_echo
  • Correction mineure sur la tabulation (phase 1)
  • Début shell
  • Page fault

Vendredi 25 Juin

  • Ajouts de commentaires
  • Travail sur le wiki
  • Commande CTRL + C OK
  • Appel système/commande reboot (redémarer le système)

Difficultés

Consigne

Au début nous étions un peu perdu dans ensiwiki, nous ne savions pas où trouver les informations, avec le temps ça s'est amélioré.

tests

Nos tests sont rarement passé du premier coup, il est nécessaire de faire une liste plus précise de ce qui doit être fait et mieux lire les spécifications.

Code open-source

  • Pour le shell, nous avons repris un skelette de code de shell par G. Mounie ensimag-shell sous licence GPLv3+