2017-10-13 16 views
0

Sous Linux, mmap peut être utilisé pour créer un mappage dans l'espace d'adressage virtuel d'un processus. Un de ses cas d'utilisation est de travailler avec de très gros fichiers. Malheureusement, il ne peut créer qu'un mappage pour quelque chose qui était déjà contigu pour commencer: il accepte seulement un offset et length.Comment créer un mappage à partir d'une mémoire segmentée dans un espace utilisateur?

Je suis à la recherche d'une solution pour mapper plusieurs segments en mémoire à une plage d'adresses contiguës. Un utilisateur de ceci serait un pilote NTFS s'exécutant dans un espace utilisateur qui veut présenter une plage d'adresses contiguës pour un fichier qui a en fait été fragmenté sur le disque. À mon avis, c'est possible pour les pilotes qui fonctionnent dans le noyau, mais je cherche spécifiquement une solution dans l'espace utilisateur.

La solution doit être C/C++. Je n'ai aucune exigence en ce qui concerne la version du noyau. Jusqu'à présent, la meilleure approche que j'ai trouvée est d'écrire un itérateur qui sait comment passer d'un segment à un autre, mais je veux aussi m'interfacer avec des bibliothèques qui n'acceptent qu'un tableau de caractères.

J'espère que cela a eu ma question à travers. Tout conseil est le bienvenu!

Répondre

1

Malheureusement, il ne peut créer un mappage pour quelque chose qui était déjà contigu à commencer par: il accepte juste un offset et length.

Il accepte seulement un offset et length à un moment, vous pouvez appeler mmap plus d'une fois.

De man 2 mmap, notez l'argument addr:

void *mmap(void *addr, size_t length, int prot, int flags, 
      int fd, off_t offset); 

Commencez par créer une grande cartographie (peut-être /dev/zero, peut-être). Ensuite, remappez des parties de cette cartographie comme vous le ferez. Pour remapper, transmettez l'adresse de début au addr et utilisez MAP_FIXED.

+0

Merci pour la réponse rapide. La page de manuel indique "MAP_FIXED - Ne pas interpréter addr comme un indice: placez le mapping exactement à cette adresse, _addr doit être un multiple de la taille de la page._". Il semble donc que vous ne pouvez pas coller librement toutes les adresses que vous voulez. Ou est-ce que cela ne s'applique plus une fois que le mmap initial a été créé? – delins

+0

@delins: Notez que 'offset 'doit aussi être un multiple de la taille de la page. Fondamentalement, tout doit être un multiple de la taille de la page. Cela reflète le fonctionnement de la MMU sur votre processeur. Donc, 'mmap' vous permet de coller des adresses ensemble comme vous le souhaitez ... tant que ces adresses sont des multiples de la taille de la page. –

+0

C'est malheureux. Les segments individuels peuvent avoir n'importe quelle taille, y compris inférieure à la taille de la page (un minimum théorique de 1 octet). Une bonne idée malgré tout! – delins