Liens utiles

Consignes

Ce TP donnera lieu à une évaluation. Vous pouvez travailler en binômes.

Estimation du temps

Envoyer votre TP

Le TP sera à rendre, à la fin de votre seconde séance de TP

Le rendu de TP se fera uniquement à travers l'interface web TPLab. Vous devrez fournir une archive .tar (ou .tar.gz) contenant

points importants :

  1. votre archive doit contenir un répertoire, pas seulement des fichiers en vrac. Mon répertoire de travail s'appelle "Pierre_Hyvernat-TP2" ; pour créer l'archive, la ligne de commande est :

    MINIX$ tar cvf Pierre_Hyvernat.tar Pierre_Hyvernat-TP2/
    
  2. tous vos fichiers doivent commencer par un entête contenant vos noms et prénoms, ainsi que votre filière.

Si ces consignes ne sont pas respectées, l'enseignant se réserve le droit de vous enlever 5 points (ou même plus) sur la note finale.

Utiliser l'image fournie

L'archive fournie pour ce TP contient une image QEMU avec un MINIX déjà installé et configuré.

Pour l'utiliser, il suffit de télécharger l'image dans le répertoire /tmp et la décompresser :

LINUX$ cd /tmp/
LINUX$ mkdir TP2-OS
LINUX$ cd TP2-OS
LINUX$ wget http://lama.univ-savoie.fr/~hyvernat/Enseignement/1213/info524/minix.img.bz2
LINUX$ bunzip2 minix.img.bz2

Pour démarrer MINIX :

LINUX$ qemu-system-i386 -m 256 -net user -net nic,model=rtl8139 -hda minix.img

Le mot de passe pour l'utilisateur root est root, et le mot de passe pour l'utilisateur etu est etu. Pour ce TP, vous n'avez pas besoin du compte administrateur. (Sauf si vous voulez installer votre propre version de malloc() dans le système lors de la dernière question.)

Si vous travaillez sur votre portable, il est possible que les entrées/sorties soient très lentes. Si vous avez l'impression que c'est le cas, remplacez l'option "-hda minix.img" par "-drive file=minix.img,if=ide,media=disk,cache=writeback".

Transfert de fichiers

Il est possible de copier des fichiers de la machine virtuelle vers la machine hôte en utilisant "scp". Pour cela, il faut que la machine hôte ait un serveur SSH. (C'est la cas pour les machines de l'université...)

À l'intérieur de la machine virtuelle, l'adresse IP de la machine hôte est 10.0.2.2. Pour copier un fichier depuis la machine virtuelle vers votre compte étudiant, vous utiliserez la commande suivante :

MINIX$ scp chemin_fichier_source login@10.0.2.2:chemin_fichier_but

Pour copier un fichier depuis votre compte étudiant vers la machine virtuelle Minix, vous utiliserez

MINIX$ scp login@10.0.2.2:chemin_fichier_source chemin_fichier_but

Vous devrez accepter la clé lors de la première utilisation, et rentrer votre mot de passe à chaque copie.

Si vous utilisez votre portable et que vous n'avez pas de serveur ssh installé, vous devrez, au choix :

1. Modèle mémoire des processus sous MINIX (et Linux)

Sous MINIX, la mémoire (virtuelle) de chaque processus est divisée en trois parties (« segments ») indépendants :

  1. le segment text (texte) contenant le texte (ie code exécutable) du programme,
  2. le segment stack (pile d'exécution) contenant les données de taille fixe du programme, les arguments de la fonction en cours d'exécution, ...
  3. le segment data (tas) contenant les données de taille dynamique du programme.

1.1. Afficher des adresses

  1. Écrivez un programme C adresses.c qui :
    • affiche quelques adresses appartenant au segment data,
    • affiche quelques adresses appartenant au segment stack.

    MINIX$ cc -com adresses.c -o adresses
    MINIX$ ./adresses
    Dans le segment "D"ata
    ======================
      - 0x....
      - 0x....
    
    Dans le segment "S"tack
    =======================
      - 0x....
      - 0x....
    
  2. Essayez d'afficher une adresse du segment text.
  3. Est-ce que les adresses affichées sont des adresses virtuelles ou physiques ?
  4. Où sont allouées
    • les variables globales,
    • les variables locales,
    • les arguments des fonctions,
    • les tableaux statiques (int tab[100];),
    • les tableaux dynamiques (int *t = malloc(sizeof(int)*taille);),
    • la fonction main(),
    • les autres fonctions,
    • ...
    Modifiez votre programme adresses.c pour afficher tout ces types d'adresses.
  1. L'option -com de la ligne de compilation permet de s'assurer que le segment text et les segments data et stack soient dans des espaces d'adressage communs. Par défaut, le segment text utilise un espace d'adressage disjoint.
  2. Le programme adresses.c doit être du C valide et n'utiliser que des fonctions standards. (Pas besoin d'inclure des fichiers systèmes...) Par exemple, l'entête de mon propre fichier ne contient que

    #include <stdio.h>
    #include <stdlib.h>
    

1.2. Allouer de la mémoire aux processus

Préliminaires

Chaque processus peut, à tout moment, réclamer une portion de mémoire dans son tas (segment D) grâce à la fonction "malloc()". Cette fonction ne fait pas partie du noyau du système d'exploitation mais utilise des fonctions bas niveau ("brk()" et "sbrk()"). "malloc()" est une fonction de la bibliothèque standard du langage C et elle fait partie de la norme POSIX, alors que "brk()" et "sbrk()" n'en font pas partie.

La fonction est définie dans le fichier /usr/src/lib/libc/ansi/malloc.c.

"malloc(s)" va essayer d'allouer un bloc de s octets dans le tas. S'il y a déjà une zone libre suffisamment grande, elle est utilisée. On peut utiliser l'algorithme First-Fit par exemple pour la découvrir. Si aucune zone libre suffisamment grande n'est trouvée, "malloc()" va utiliser la fonction "brk()" qui permet d'agrandir le tas. (Bien entendu, s'il n'y a plus de mémoire disponible, "brk()" va échouer, ainsi que "malloc()".)

Points importants :

-

Créez un fichier politique.c avec quelques fonctions en C qui créent des zones de mémoire et les libèrent pour décider si l'allocation malloc de MINIX est un "FIRST FIT", un "BEST FIT", un "NEXT FIT", ou un "WORST FIT".

Votre fonction devra afficher ce qu'elle fait et terminer en précisant la politique d'allocation utilisé par le système.

Comprendre comment fonctionne l'allocation

L'image contient un malloc-with-comments.c dans le repertoire /usr/src/lib/libc/ansi/, à coté du fichier malloc.c officiel de MINIX. Ouvrez le fichier et commentez la fonction malloc pour expliquer ce qu'elle fait. (C'est une étape préliminaire à la question suivante...)

Remarques :

Afficher les blocs

Écrivez une fonction alloc_info() pour afficher la liste des bloc, la liste des blocs libre, leurs tailles, etc.

Pour tester votre fonction, le plus simple est de recopier les fichiers malloc-debug.{c,h} dans le répertoire TP2. Vous pourrez ainsi compiler uniquement votre fichier malloc.c (ou malloc-with-comments.c) et le tester sur un petit programme. Il faudra pour ceci ajouter un fichier malloc.h que vous inclurez à la place de stdlib.h. Pour forcer votre exécutable à utiliser votre version de malloc(), il faudra faire l'édition de liens avec votre fichier malloc.o.

Je vous conseille de faire un Makefile pour vous simplifier la vie. Et pour les fainéants, voici une archive tar...

ATTENTION : votre fichier malloc.c ne peut pas utiliser lui même la fonction malloc ou des fonctions qui l'utilisent indirectement (comme la fonction printf). Si vous voulez faire de l'affichage pour déboguer, je vous conseille d'utiliser uniquement les fonctions définies dans le fichier affiche.c (avec le fichier affiche.h correspondant).

Modifier l'allocateur

La version MINIX de "malloc()" utilise un algorithme First-Fit pour chercher une zone libre. Créez un fichier malloc-best_fit.c pour avoir une politique Best-Fit.

Vérifiez que la politique d'allocation du malloc a bien été modifiée en recompilant le fichier politique.c avec le nouveau malloc.

Testez votre fonction malloc en fournissant un ficher test-malloc.c et un fichier Makefile pour utiliser votre fonction malloc.

Attention : les tests devront être conséquents, avec de nombreuses allocations / désallocations... La qualité des tests sera prise en compte.