85 lines
2.5 KiB
C
85 lines
2.5 KiB
C
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
|
|
/*
|
|
* 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;
|
|
}
|