Testen Sie es mit busybox devmem
busybox devmem
ist ein winziges CLI-Dienstprogramm, das mmaps verwendet /dev/mem
.
Sie können es in Ubuntu bekommen mit: sudo apt-get install busybox
Verwendung: 4 Bytes von der physikalischen Adresse lesen 0x12345678
:
sudo busybox devmem 0x12345678
Schreiben Sie 0x9abcdef0
an diese Adresse:
sudo busybox devmem 0x12345678 w 0x9abcdef0
Quelle: https://github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85
MAP_SHARED
Beim Mapping /dev/mem
möchten Sie wahrscheinlich Folgendes verwenden:
open("/dev/mem", O_RDWR | O_SYNC); mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)
MAP_SHARED
Schreibt das Schreiben sofort in den physischen Speicher, was das Beobachten erleichtert und für das Schreiben von Hardware-Registern sinnvoller ist.
CONFIG_STRICT_DEVMEM
und nopat
Um das /dev/mem
reguläre RAM in Kernel v4.9 anzuzeigen und zu ändern, müssen Sie Folgendes tun:
- deaktivieren
CONFIG_STRICT_DEVMEM
(standardmäßig unter Ubuntu 17.04 festgelegt) - Übergeben Sie die
nopat
Kernel-Befehlszeilenoption für x86
IO-Ports funktionieren auch ohne diese.
Siehe auch: https://stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-mit-invalid-argument-for-virt-to-phys-address-but-addre/45127582#45127582
Cache-Spülung
Wenn Sie versuchen, in den RAM-Speicher anstelle eines Registers zu schreiben, wird der Speicher möglicherweise von der CPU zwischengespeichert: https://stackoverflow.com/questions/22701352/how-to-flush-the-cpu-cache-for-a-region -of-address-space-in-linux und ich sehe keine sehr tragbare / einfache Möglichkeit, sie zu leeren oder die Region als nicht cachbar zu markieren:
Also vielleicht /dev/mem
nicht zuverlässig verwendet werden, um Speicherpuffer an Geräte zu passieren?
Dies kann leider in QEMU nicht beobachtet werden, da QEMU keine Caches simuliert.
Wie teste ich es?
Nun zum Spaß. Hier sind ein paar coole Setups:
- Userland-Speicher
volatile
Variable in einem Userland-Prozess zuordnen - erhalte die physikalische Adresse mit
/proc/<pid>/maps
+/proc/<pid>/pagemap
- die physische Adresse mit
devmem2
und beobachten Sie, wie der Benutzerlandprozess reagiert:
- Kernelland-Speicher
- Kernelspeicher mit zuweisen
kmalloc
- Holen Sie sich die physische Adresse mit
virt_to_phys
und geben Sie sie an das Benutzerland zurück - Ändern Sie die physische Adresse mit
devmem2
- Fragen Sie den Wert vom Kernel-Modul ab
- IO Mem und QEMU Virtual Platform Device
- Erstellen Sie ein Plattformgerät mit bekannten physischen Registeradressen
- verwenden Sie
devmem2
, um in das Register zu schreiben - beobachten Sie, wie
printf
s als Antwort aus dem virtuellen Gerät kommt