Pagemap auf speicherzugeordneten Geräten funktioniert nicht

Pagemap auf speicherzugeordneten Geräten funktioniert nicht

Ich versuche, die physischen Adressen von Heap-Variablen, Stack-Variablen und im Speicher abgebildeten Peripherieadressen mithilfe der Datei /proc/{pid}/pagemap zu finden. Dazu verwende ich die in der Datei beschriebenen Schritte:http://lxr.free-electrons.com/source/Documentation/vm/pagemap.txt. Das beschriebene Verfahren funktioniert gut für Stack- und Heap-Variablen. Für speicherabgebildete Peripheriegeräte wird jedoch keine Seite in der Datei /proc/{pid}/pagemap gefunden. Die Ausgabe von 'cat /proc/{pid}/maps' lautet:

00008000-0000a000 r-xp 00000000 b3:02 289852     /home/linaro/ocm_test/write-memory
00011000-00012000 r--p 00001000 b3:02 289852     /home/linaro/ocm_test/write-memory
00012000-00013000 rw-p 00002000 b3:02 289852     /home/linaro/ocm_test/write-memory
00013000-00034000 rw-p 00000000 00:00 0          [heap]
b2efe000-b6dfe000 rw-s 00001000 b3:02 284849     /dev/uio0
b6dfe000-b6ed2000 r-xp 00000000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6ed2000-b6eda000 ---p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6eda000-b6edc000 r--p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edc000-b6edd000 rw-p 000d6000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edd000-b6ee0000 rw-p 00000000 00:00 0 
b6ee0000-b6ee2000 r-xp 00000000 b3:02 27519      /usr/lib/libinterface.so
b6ee2000-b6ee9000 ---p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6ee9000-b6eea000 r--p 00001000 b3:02 27519      /usr/lib/libinterface.so
b6eea000-b6eeb000 rw-p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6efb000-b6f12000 r-xp 00000000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f13000-b6f14000 rw-p 00000000 00:00 0 
b6f14000-b6f15000 rw-s 00000000 b3:02 284849     /dev/uio0
b6f15000-b6f19000 rw-p 00000000 00:00 0 
b6f19000-b6f1a000 r--p 00016000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f1a000-b6f1b000 rw-p 00017000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
bee36000-bee57000 rw-p 00000000 00:00 0          [stack]
bef1f000-bef20000 r-xp 00000000 00:00 0          [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

Wenn ich versuche, die physischen Adressen von 0x00013000 oder 0xbee36000 zu finden, funktioniert es einwandfrei. Die Pagemap-Datei gibt jedoch keine gefundene Seite zurück, wenn ich versuche, die physische Adresse zu finden, die 0xb2efe000 entspricht, die zu /dev/uio0 gehört. Ich versuche dies zu Überprüfungszwecken. Ich weiß, dass eine physische Adresse existiert, weil ich mmap auf 0x1b90000 ignoriert verwendet habe, um 0xb2efe000 zu finden. Kann mir bitte jemand erklären, warum die Datei /proc/{pid}/pagemap die physische Adresse nicht enthält?

Antwort1

Kurze Antwort: Die Pagemap-Schnittstelle stellt Informationen bereit, die in der mit der Adresse verknüpften Strukturseite gespeichert sind. E/A-Adressen sind reine PFN-Zuordnungen ohne verknüpfte Strukturseite und werden daher als Nullen angezeigt.

Längere Antwort Die Neuzuordnung physischer Adressen (einschließlich E/A-Adressen) zum Benutzerbereich erfolgt durch den Aufruf von remap_pfn_range. Diesen neu zugeordneten Adressen ist kein zugeordnet struct page(es handelt sich um reine PFN-Zuordnungen). Um zu berücksichtigen, dass diese Adressen speziell sind, wird diese Funktion VM_PFNMAPauf dem vma gesetzt.

Die Pagemap-Schnittstelle stellt eine Reihe von Feldern bereit, die mit dem Inhalt der mit der Adresse verknüpften Adresse zu tun haben struct page. Für diese Adressen gibt es jedoch keine solche Struktur. Daher überspringt Pagemap sie einfach:

Wenn Pagemap verwendet wird, führt der Kernel einen Pagewalk durch walk_page_range. Mit gekennzeichnete vmas VM_PFNMAPwerden anders behandelt:

/*
 * vma(VM_PFNMAP) doesn't have any valid struct pages behind VM_PFNMAP
 * range, so we don't walk over it as we do for normal vmas. However,
 * Some callers are interested in handling hole range and they don't
 * want to just ignore any single address range. Such users certainly
 * define their ->pte_hole() callbacks, so let's delegate them to handle
 * vma(VM_PFNMAP).
 */

Das pte_hole der Seitenübersicht fügt nur eine Reihe von Nulleinträgen ein (modulo einiger zusätzlicher Flags für VM_SOFTDIRTY). Deshalb wird es nicht angezeigt ...

Mir ist keine Kernelschnittstelle bekannt, mit der man die physische Adresse für solche Zuordnungen abrufen kann. Mit einem Kernelmodul oder mithilfe von wäre das jedoch ganz einfach möglich crash.

verwandte Informationen