Files
twx-linux/tools/examples/dev_mem_access.c
Heinrich Toews 6be569be53 tools/examples: add /dev/mem physical memory access example
Add a new example utility that maps a physical MMIO address range using
/dev/mem and mmap, reads 32-bit register values, and dumps a
user-specified number of bytes in hexadecimal format.

Signed-off-by: Heinrich Toews <ht@twx-software.de>
2026-04-02 10:50:58 +02:00

83 lines
2.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#define PHY_ADDRESS_BASE 0x500000000 // Die Startadresse Ihres QSPI MMIO-Bereichs
#define MAP_SIZE 0x100000 // Die Größe des zu mappenden Bereichs
int main(int argc, char *argv[]) {
int fd;
void *virtual_base;
void *vb;
// volatile unsigned int *qspi_register; // oder Pointer auf den Speicherbereich
if (argc != 2) {
fprintf(stderr, "Verwendung: %s <dump_groesse_in_bytes>\n", argv[0]);
return EXIT_FAILURE;
}
// Die gewünschte Dump-Größe aus dem Konsolenparameter lesen
// Wir verwenden strtol für eine robustere Konvertierung
char *endptr;
long size_long = strtol(argv[1], &endptr, 10);
if (endptr == argv[1] || *endptr != '\0' || size_long <= 0) {
fprintf(stderr, "Ungültige Größe angegeben. Bitte eine positive Ganzzahl eingeben.\n");
return EXIT_FAILURE;
}
size_t size = (size_t)size_long;
// 1. /dev/mem öffnen
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
perror("Error opening /dev/mem");
return EXIT_FAILURE;
}
// 2. Physische Adresse in den virtuellen Speicher mappen
virtual_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PHY_ADDRESS_BASE);
if (virtual_base == MAP_FAILED) {
close(fd);
perror("Error mmapping the file");
return EXIT_FAILURE;
}
vb = virtual_base;
vb += 4;
// Jetzt können Sie über den Pointer virtual_base auf die physische Adresse zugreifen
// Beispiel: Lesen eines 32-Bit-Werts
volatile unsigned int value = *((volatile unsigned int *) vb);
printf("TWx: 0x%lx: 0x%x\n", vb, value);
__sync_synchronize();
vb += 4;
value = *((volatile unsigned int *) vb);
printf("TWx: 0x%lx: 0x%x\n", vb, value);
__sync_synchronize();
printf("Dump des Speichers ab virtueller Adresse %p (Groesse: %zu Bytes):\n",
(void*)virtual_base, size);
// Speicherinhalt ausgeben (dumpen)
unsigned char *ptr = virtual_base;
for (size_t i = 0; i < size; i++) {
__sync_synchronize();
// Hexadezimale Ausgabe
printf("%02x ", ptr[i]);
if ((i + 1) % 16 == 0) { // Nach 16 Bytes eine neue Zeile
printf("\n");
}
}
// ... Operationen durchführen ...
// 3. Speicher freigeben und Datei schließen
if (munmap(virtual_base, MAP_SIZE) == -1) {
perror("Error un-mmapping the file");
}
close(fd);
return EXIT_SUCCESS;
}