Ce TP donnera lieu à une évaluation. Vous pouvez travailler en binômes.
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
nom_prenom-TP2
" ou "nom1_prenom1-nom2_prenom2-TP2
"
adresses.c
" pour la question 1, contenant en commentaire les réponses aux questions,
tests.c
pour la question 2.
malloc-with-comments.c
" contenant votre version commentée du fichier "malloc.c
" de MINIX (question 3)
alloc_info.c
pour la question 4.
malloc.c
" contenant votre version de "malloc.c
" avec les modifications demandées à la questions 5.
points importants :
Pierre_Hyvernat-TP2
" ; pour créer l'archive, la ligne de commande est :
MINIX$ tar cvf Pierre_Hyvernat.tar Pierre_Hyvernat-TP2/
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.
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-TP.img.bz2 LINUX$ bunzip2 minix-TP.img.bz2
Pour démarrer MINIX :
LINUX$ qemu-system-i386 -m 256 -net user -net nic,model=rtl8139 -hda minix-TP.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-TP.img
" par "-drive file=minix-TP.img,if=ide,media=disk,cache=writeback
".
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 :
openssh-server
sous Debian ou Ubuntu),
LINUX$ qemu-system-i386 -m 256 -net user,hostfwd=tcp::2232-:22 -net nic,model=rtl8139 -hda minix-TP.img
LINUX$ scp -P 2232 etu@localhost:chemin_fichier_source chemin_fichier_but
LINUX$ scp -P 2232 chemin_fichier_source etu@localhost:chemin_fichier_but
Sous MINIX, la mémoire (virtuelle) de chaque processus est divisée en trois parties (« segments ») indépendants :
text
(texte) contenant le texte (ie code exécutable) du programme,
stack
(pile d'exécution) contenant les données de taille fixe du programme, les arguments de la fonction en cours d'exécution, ...
data
(tas) contenant les données de taille dynamique du programme.
adresses.c
qui :
data
,
stack
.
MINIX$ cc -com adresses.c -o adresses MINIX$ ./adresses Dans le segment "D"ata ====================== - 0x.... - 0x.... Dans le segment "S"tack ======================= - 0x.... - 0x....
text
.
int tab[100];
),
int *t = malloc(sizeof(int)*taille);
),
main()
,
adresses.c
pour afficher tout ces types d'adresses.
-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.
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>
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 :
NULL
, et son bloc de données est toujours vide. (Ou presque vide s'il n'etait pas aligné correctement...)
_bottom
contient un pointeur vers le premier bloc.
_top
contient un pointeur vers le dernier bloc.
_empty
contient un pointeur vers le premier bloc libre.
-
struct ...
") pour représenter les blocs,
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.
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 :
for( i=0; i<taille; i++) { /* on fait une boucle avec i qui varie de 0 à taille-1 */
for (ntries = 0; ntries < 2; ntries++) { ... }
É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).
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.