GP2X Problem Reading Kernel Memory


ldesnogu

Well-Known Member
Joined
Dec 26, 2006
Messages
1,049
Age
55
Location
France
Website
Visit site
I am trying to read kernel memory by using /dev/mem.
I have been trying both by mmap'ing and by file reading, but both methods fail to provide me with information about where exception vectors should be (either 0 or 0xFFFF0000).
The funny thing is that for both methods the 4k page @0 is full of 0, while the page @FFFF0000 is full of 0 when reading through file functions, but locks the console when trying to read with mmap.

Other areas look fine (at least they match the binary kernel contents).

For reference here is the code:

Code:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

typedef volatile uint8_t mem_t;

#define MAP_SIZE  4096U
#define MAP_MASK  (MAP_SIZE - 1)

static
void dump(FILE *fout, mem_t *mem, uint32_t start, uint32_t end)
{
  uint32_t addr;

  fprintf(fout, "Dump %08x-%08x\n", start, end);
  for (addr = start; addr < end; addr++) {
	if ((addr % 16) == 0 || addr == start) {
	  if (addr != start)
	fputc('\n', fout);
	  fprintf(fout, "%08x: ", addr);
	}
	fprintf(fout, " %02x", *(mem + (addr & MAP_MASK)));
  }
  fputc('\n', fout);
}

int main(int argc, const char *argv[])
{
  int	   ret;
  int	   memfd;
  mem_t	*mmem;
  uint32_t  start, end;
  uint32_t  map_size;

  ret = 0;

  start = 0x00000000;
  end   = 0x00000020;
  if (argc == 3) {
	sscanf(argv[1], "%x", &start);
	sscanf(argv[2], "%x", &end);
  }

  memfd = open("/dev/mem", O_RDONLY | O_SYNC);
  if (memfd == -1) {
	fprintf(stderr, "Failed to open /dev/mem\n");
	goto end;
  }

  map_size = MAP_SIZE; // 0x400000

  printf("/dev/mem opened successfully - fd = %d\n", memfd);

  mmem = (mem_t *)mmap((void *)0x0, map_size, PROT_READ, MAP_PRIVATE,
			   memfd, start & ~MAP_MASK);
  if (mmem == MAP_FAILED) {
	fprintf(stderr, "mmap failed\n");
	ret = 1;
	goto end_close;
  }

#if 1
  dump(stdout, mmem, start, end);
#else
  {
	mem_t *my_mem;
	fprintf(stderr, "seek=%lx\n", lseek(memfd, start, SEEK_SET));
	my_mem = (mem_t *)malloc(end - start);
	fprintf(stderr, "read=%x\n", read(memfd, my_mem, end - start));
	dump(stdout, my_mem, start, end);
	free(my_mem);
  }
#endif

  if (munmap((void *)mmem, map_size)) {
	ret = 1;
	fprintf(stderr, "munmap failed\n");
  }
 end_close:
  close(memfd);
 end:
  return ret;
}

Anyone has an idea?
 
Yeah, I had the same problem with the MMU hack, lseek/read/write etc worked for some locations, and mmap worked for others.

I do believe however that Linux sets the bit for having the vectors at 0xFFFF0000, but if you escape linux by doing something like a watchdog reset, then you need to write at 0x0, as that is of course the vector location after reset.
 
I found the problem: I simply forgot that vector are remapped by the MMU, so it's VA FFFF0000 -> PA 1000.

In fact read was returning 0 byte...

Two reasons to feel dumb :)
 
Back
Top