Jun Hu <jhu_com@xxxxxxx> wrote: > strace your application, like as: > ... It's the lseek that fails: Obviously, /dev/mem is not seekable. What really puzzles me is that dd _does_ work on /dev/mem when looking at ordinary RAM, but I'm reluctant to further debug why. But anyhow, as I think it may at times be also useful for others to have a simple tool that allows to read (and write!) PCI memory, I share the few lines of code that I wrote to fulfill my needs. I hope that the included "documentation" is verbose enough. And I'm certainly interested if anyone finds bugs :-): #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <stdint.h> #include <assert.h> #include <sys/mman.h> void usage(const char *name) { fprintf(stderr, "Usage: %s address access [size]\033[2m\n", name); fprintf(stderr, " Either - prints \"size\" bytes \033[1mfrom\033[2m physical memory,\n"); fprintf(stderr, " starting at \"address\" and using \"access\"\n"); fprintf(stderr, " bytes per access \033[1mto\033[2m stdout\n"); fprintf(stderr, " or - writes as many bytes as are available \033\[1mfrom\033[2m\n"); fprintf(stderr, " stdin \033[1mto\033[2m physical memory starting at \"address\"\n"); fprintf(stderr, " using \"access\" bytes per access.\n"); fprintf(stderr, " Note that both \"address\" and either \"size\" or the\n"); fprintf(stderr, " number of available bytes from stdin must be a multiple of\n"); fprintf(stderr, " \"access\", and \"access\" must either be %d, %d, %d or %d.\033[0m\n", sizeof(uint8_t), sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t)); exit(-1); } template<typename T> void readOrWrite(uint8_t *src, uint8_t *mem) { if(src) *(T *) mem = *(T *) src; else { T t = *(T *) mem; assert(write(1, &t, sizeof(T)) == sizeof(T)); } } int main( int argc, char *argv[]) { int fd, pageSize = getpagesize(), size = 0, n; uint8_t *mem, *b = 0, *buffer = 0; // Paranoia check to ensure that page size is a power of 2. assert((pageSize != 0) && !(pageSize & (pageSize - 1))); if (argc == 3) do { #define CHUNK_SIZE 1000 assert(b = buffer = (uint8_t *) realloc(buffer, size + CHUNK_SIZE)); assert((n = read(0, buffer + size, CHUNK_SIZE)) >= 0); size += n; } while(n); else if(argc == 4) size = strtoul(argv[3], 0, 0); else usage(argv[0]); off_t address = strtoul(argv[1], 0, 0); size_t access = strtoul(argv[2], 0, 0); if(address % access || size % access) usage(argv[0]); assert((fd = open ("/dev/mem", O_RDWR)) >= 0); size_t s = (((address & (pageSize - 1)) + size - 1) / pageSize + 1) * pageSize; mem = (uint8_t *) mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address & ~(pageSize - 1)); assert(mem != MAP_FAILED); for(uint8_t *i = mem; i < mem + size; i += access) { #define ROW(t) sizeof(t): readOrWrite<t>(b, i); break switch(access) { case ROW(uint8_t); case ROW(uint16_t); case ROW(uint32_t); case ROW(uint64_t); default: usage(argv[0]); } if(b) b += access; } free(buffer); munmap(mem, getpagesize()); close(fd); return 0; } _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies