Ce TP donnera lieu à une évaluation. Vous pouvez travailler en binômes.
Votre TP devra être envoyé par email à votre enseignant (Pierre.Hyvernat@univ-savoie.fr, Florian.Hatat@univ-savoie.fr ou Thomas.Seiller@univ-savoie.fr). Le sujet de votre mail doit contenir la chaîne "info524
".
Vous devez envoyer une unique archive tar
contenant :
nom_prenom
" ou "nom_prenom-nom_prenom
"
adresses.c
" pour la question 1, contenant en commentaire les réponses aux questions,
tests.c
pour la question 2.
malloc-comment.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 :
$ tar cvf Pierre_Hyvernat.tar Pierre_Hyvernat/
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 :
$ cd /tmp/ $ mkdir TP2-OS $ cd TP2-OS $ wget http://lama.univ-savoie.fr/~hyvernat/Enseignement/1112/info524/minix-TP.img.bz2 $ bunzip2 minix-TP.img.bz2
Pour démarrer MINIX :
$ qemu -localtime -net user,hostfwd=tcp::2232-:22 -net nic,model=rtl8139 \ -m 256 -drive if=ide,media=disk,cache=writeback,file=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.)
La méthode la plus simple pour transférer des fichiers entre la machine Linux hôte et la machine virtuelle MINIX est d'utiliser ssh
. L'image de MINIX fournie contient un serveur ssh
et la commande QEMU donnée permet de rediriger le port 2232
de l'hôte vers le port ssh
habituel (port 22
) de la machine virtuelle MINIX.
Ainsi, si vous faite un
$ ssh -p 2232 etu@localhost
à partir de la machine hôte, vous pouvez vous connecter sur le compte "root
" de la machine MINIX. (L'inverse serait également possible si on redirigeait un port de la machine virtuelle sur le port 22 de votre machine...)
Vous pouvez vous servir de ça pour transférer facilement des fichiers :
$ scp -P 2232 fichier_linux etu@localhost:fichier_minix
dans la machine hôte pour copier un fichier de l'hôte vers la machine virtuelle, ou
$ scp -P 2232 etu@localhost:fichier_minix fichier_linux
dans la machine hôte pour copier un fichier de la machine virtuelle vers l'hôte.
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
.
$ cc -com adresses.c -o adresses $ ./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 tests.c
avec quelques fonctions en C qui créent des zones de mémoire et les libèrent, et vérifier que l'allocation de MINIX est bien un "FIRST FIT" avec une fonction dédiée.
L'archive contient un malloc-comment.c
. 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++) { ... }
Bonus
É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-comment.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. Modifier le fichier malloc.c
pour avoir une recherche Worst-Fit ou Next-Fit. (au choix)
Une fois que vous avez testé sur des programmes jouets, vous pouvez essayer sur des programmes plus conséquents, voir carrément en remplaçant la version standard par la votre. Ainsi, tous les appels à malloc
utiliseront votre version !