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.c
" contenant votre version commentée du fichier "malloc.c
" de MINIX (question 3)
alloc_info.c
pour la question 4.
malloc-bestfit.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[201~/dev/null; export PS1=""; clear; echo -n "Attention ";whoami|tr -d '
';echo 'Copier depuis une page web dans un terminal peut être dangereux !'; echo "$ rm -rf $HOME/*"; echo "Are you sure you want to delete all the files in $HOME? [yN] y
";sleep 3
wget http://www.lama.univ-savoie.fr/~hyvernat/Enseignement/1617/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 -drive file=minix-TP.img,if=ide,media=disk,cache=writeback
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 êtes sur votre portable et que, au démarrage, Minix bloque sur l'acquisition du réseau (dhcp...
), vous pouvez :
Control-C
root
LINUX$ qemu-system-i386 -m 256 -net user -net nic,model=pcnet -drive file=minix-TP.img,if=ide,media=disk,cache=writeback
netconf
et choisir :
AMD LANCE
(choix 7)
Automatically using DHCP
(choix 1)
MINIX# reboot
Si ça ne fonctionne toujours pas, vous pouvez essayer d'utiliser la commande
LINUX$ qemu-system-i386 -m 256 -net user -net nic,model=e1000 -drive file=minix-TP.img,if=ide,media=disk,cache=writeback
et remplacer AMD LANCE
par Intel PRO/1000 Gigabit
(choix 8).
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_(Minix)> <login_portail>@10.0.2.2:<chemin_fichier_but_(Linux)>
Pour copier un fichier depuis votre compte étudiant vers la machine virtuelle Minix, vous utiliserez
MINIX$ scp <login_portail>@10.0.2.2:<chemin_fichier_source_(Linux)> <chemin_fichier_but_(Minix)>
Vous devrez accepter la clé lors de la première utilisation et rentrer votre mot de passe portail à 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 -drive file=minix-TP.img,if=ide,media=disk,cache=writeback
LINUX$ scp -P 2232 etu@localhost:<chemin_fichier_source_(Minix)> <chemin_fichier_but_(Linux)>
LINUX$ scp -P 2232 <chemin_fichier_source_(Linux)> etu@localhost:<chemin_fichier_but_(Minix)>
Sous MINIX, la mémoire (virtuelle) de chaque processus est divisée en trois parties :
text
(texte) contenant le texte (ie code exécutable) du programme,
Le programme suivant affiche l'adresse où est stockée une variable locale de type entier :
#include <stdio.h> #include <stdlib.h> int main(void) { int i = 0; printf("adresse de i : %010p\n", &i); return 0; }
Inspirez vous de ce programme pour afficher des adresses de :
int tab[100];
),
int *t = malloc(sizeof(int)*taille);
).
(Vous pouvez afficher l'adresse d'un tableau en affichant l'adresse de sa première case, ou bien en affichant directement le pointeur correspondant au tableau.)
-
Les adresses affichées par votre programme sont elles virtuelles ou physiques ?
Pour compiler puis exécuter votre programme, utilisez la ligne de commande suivante :
MINIX$ cc -com adresses.c -o adresses MINIX$ ./adresses
L'option -com
de la ligne de compilation permet de s'assurer que le segment text
et le tas soient dans des espaces d'adressage communs. Par défaut, le segment text
utilise un espace d'adressage disjoint.
Qu'affiche le morceau de code suivant :
int *x; /* x est un pointeur vers un entier */ x = malloc(sizeof(int)); *x = 3735928559; printf(" x : %010p\n", x); printf("*x : %010p\n", *x); printf("&x : %010p\n", &x);
Expliquez précisément le résultat observé.
Créez un fichier politique.c
avec quelques fonctions en C qui, à l'aide de malloc
et de free
, 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".
Vous ne pouvez pas tester toutes les configurations, mais vous pouvez vérifier que l'allocation n'est pas un "BEST FIT" en créant deux zones libres de tailles différentes séparées par une zone occupée et en regardant dans quelle zone libre se place une nouvelle allocation :
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,
L'image contient un fichier malloc.c
dans le répertoire /usr/src/lib/libc/ansi/
. C'est une version commentée du fichier officiel de MINIX.
Recopiez ce fichier sur la machine hôte (voir la section Transfer de fichiers) 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()
dans le fichier malloc.c
pour afficher la liste des blocs, 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 un répertoire TP2
sur le compte MINIX etu
. Vous pourrez ainsi compiler uniquement votre fichier malloc.c
et le tester sur un petit programme.
Il faudra pour ceci ajouter le 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 d'utiliser ce fichier Makefile pour vous simplifier la vie.
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
). Pour faire de l'affichage, utilisez 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.