2017-10-13 1 views
0

In Linux kann mmap verwendet werden, um eine Zuordnung im virtuellen Adressraum eines Prozesses zu erstellen. Einer seiner Anwendungsfälle ist die Arbeit mit sehr großen Dateien. Leider kann es nur ein Mapping für etwas erstellen, das bereits zusammenhängend war: es akzeptiert nur ein offset und length.Wie erstellt man ein Mapping aus segmentiertem Speicher in userland?

Ich suche nach einer Lösung, um mehrere Segmente im Speicher auf einen zusammenhängenden Adressbereich abzubilden. Ein Benutzer davon wäre ein NTFS-Treiber, der in einem Benutzerbereich läuft, der einen zusammenhängenden Adressbereich für eine Datei darstellen möchte, die tatsächlich auf der Platte fragmentiert wurde. Meiner Ansicht nach ist dies für Treiber möglich, die im Kernel ausgeführt werden, aber ich suche speziell nach einer Lösung im Benutzerbereich.

Die Lösung sollte C/C++ sein. Ich habe keine Anforderungen in Bezug auf Kernel-Version. Bis jetzt ist der beste Ansatz, den ich mir vorstellen konnte, ein Iterator zu schreiben, der weiß, wie man von Segment zu Segment springt, aber ich möchte auch mit Bibliotheken arbeiten, die nur ein Zeichen-Array akzeptieren.

Ich hoffe, das hat meine Frage über. Jeder Rat ist willkommen!

Antwort

1

Leider kann es nur eine Zuordnung für etwas schaffen, das bereits zusammenhängende war, mit zu beginnen: es nur ein offset und length akzeptiert.

Es akzeptiert nur einen offset und length zu einer Zeit, können Sie mmap mehr als einmal aufrufen.

Von man 2 mmap Beachten Sie addr Argument:

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

Beginnen Sie mit einer großen Abbildung zu schaffen (vielleicht /dev/zero, vielleicht). Teilen Sie dann Teile dieser Zuordnung neu, wie Sie es tun. Um neu zu ordnen, übergeben Sie die Startadresse an addr und verwenden Sie MAP_FIXED.

+0

Danke für die schnelle Antwort. Die man-Seite besagt "MAP_FIXED - interpretieren Sie Addr nicht als einen Hinweis: platzieren Sie das Mapping an genau dieser Adresse. _addr muss ein Vielfaches der Seitengröße sein._". So scheint es, dass Sie nicht beliebig Adressen zusammenkleben können, die Sie wollen. Oder gilt dies nicht mehr, nachdem die ursprüngliche mmap erstellt wurde? – delins

+0

@delins: Beachten Sie, dass "offset" auch ein Vielfaches der Seitengröße sein muss. Grundsätzlich muss alles ein Vielfaches der Seitengröße sein. Dies spiegelt wider, wie die MMU auf Ihrem Prozessor funktioniert. Mit 'mmap' können Sie also Adressen beliebig zusammenkleben ... solange diese Adressen ein Vielfaches der Seitengröße sind. –

+0

Das ist bedauerlich. Die einzelnen Segmente können eine beliebige Größe aufweisen, einschließlich kleiner als die Seitengröße (ein theoretisches Minimum von 1 Byte). Eine gute Idee, egal! – delins

Verwandte Themen