diff --git a/03/Makefile b/03/Makefile new file mode 100644 index 0000000..55ff3d0 --- /dev/null +++ b/03/Makefile @@ -0,0 +1,9 @@ +CC = gcc +CFLAGS = -Wall -g +SRC = main.c + +all: + $(CC) $(CFLAGS) $(SRC) -o mmap + +clean: + rm mmap diff --git a/03/main.c b/03/main.c new file mode 100644 index 0000000..1ac319b --- /dev/null +++ b/03/main.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include + +/* + * Je me suis aidé du template pour les variables à utiliser. Je les ai + * cependant renommées pour mieux m'y retrouver. + */ + +#define PAGE_SIZE 4096 +#define PERSISTENT_SIZE sizeof(int) * 2 + +/* + * __attribute__(()) = macro pour GCC afin de rajouter des informations + * + * section("persistent") : on met dans la section persistent les valeurs au + * lieu de la section text de l'ELF. + * + * aligned(PAGE_SIZE) = on a besoin d'aligner notre "borne supérieur" car on + * est en dehors de la section data et qu'on doit suivre les règles du MMU. + * Cela permet aussi de commencer au début d'une page. + * cf. le template pour + d'infos. + * + * À noter que si on lui assigne une valeur, celle-ci sera écrite dans le + * fichier si on écrit dans le fichier les valeurs de la section persistent. + */ +__attribute__((section("persistent"), aligned(PAGE_SIZE))) int start; + +/* + * Comme il n'y a pas l'attribut de section, cette variable sera mise dans + * la section text au lieu de persistent. La mettre au milieu des 2 autres + * variables ne fait rien. + */ +int foo = 42; + +/* + * on place le compteur dans la section persistent afin de le copier dans le + * lier avec le fichier. + */ +__attribute__((section("persistent"))) int count; + +int setup_persistent(char *name) +{ + /* on ouvre en lecture écriture ou créé le fichier */ + int fd = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (fd < 0) return -1; + + /* + * on le coupe à la bonne taille pour pouvoir lier la section persistent et + * le fichier. Comme la section persistent contient start et count, on + * redimenssionne le fichier pour stocker 2 entiers. + */ + if (ftruncate(fd, PERSISTENT_SIZE)) return -1; + + if (mmap( + &start, /* début de la section persistent */ + PERSISTENT_SIZE, /* taille de la section persistent */ + PROT_WRITE | PROT_READ, /* on accède en lecture/écriture au mapping */ + MAP_SHARED | MAP_FIXED, /* on partage le mapping et on se place à + l'adresse exact du start */ + fd, /* on lie notre fichier mmap.persistent à la + zone mémoire */ + 0) /* on commence au début du fichier */ + == MAP_FAILED) + return -1; + + close(fd); + return 0; +} + +int main() +{ + if (setup_persistent("mmap.persistent")) + { + perror("setup_persistent"); + return -1; + } + + printf("count = %d\n", count++); + printf("foo = %d\n", foo++); + return 0; +} diff --git a/README.md b/README.md index 57cb06e..cf46c16 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,11 @@ On fait un fork basique, avec d'autres épreuves tel qu'une chimère processus-thread, un thread et un processus qui change d'utilisateur. Je n'ai pas fait la denière étape où il faut changer l'UID. + +### 03 - Zone mémoire + +Syscalls utilisés: ftruncate, mmap, open, close. + +Liaison d'un fichier et d'une zone mémoire. Chaque fois qu'on lance le +programme, un compteur est incrémenté de 1. Je me suis aidé du template pour la +création des variables de base.