Viewing Memory in GDB Outside of Process Space (mmap)

QUESTION:

For educational purposes, I'm in the process of trying to understand exactly how the RaspberryPI interfaces with its GPIO headers. I have a simple program that control an LED on an expansion board that works well. However, I wanted to use GDB to see the program changing bits in the mapped control registers. Normally I would do something like this in GDB:

x /t 0x20200000

But this seems to result in the following error, presumably as the target memory is not in the process space:

0x20200000: Cannot access memory at address 0x20200000

I tried mapping a memory region but didn't seem to help.

mem 0x20200000 0x20208192

I also true to write a function to call from GDB, but couldn't figure out how to write something that returned entire block of memory I am interested in so can view as binary (I don't want to peek each byte as write bits are quite spread out over area). Is there any way I can do this in GDB?

Supporting Code

Memory addresses to map:

#define BCM2708_PERI_BASE   0x20000000
#define GPIO_BASE           (BCM2708_PERI_BASE + 0x200000)

Pointer to mapped memory:

static volatile uint32_t *gpio ;

Mapping routine:

int gpio_init (void)
{
  int      fd ;
  uint8_t *gpioMem;

  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
  {
    fprintf (stderr, "gpio_init: unable to open /dev/mem: %s\n", strerror (errno)) ;
    return -1 ;
  }

  if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  {
    fprintf (stderr, "gpio_init: malloc failed: %s\n", strerror (errno)) ;
    return -1 ;
  }

  if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
    gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;

  gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE,  MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;

  if ((int32_t)gpio < 0)
  {
    fprintf (stderr, "gpio_init: mmap failed: %s\n", strerror (errno)) ;
    return -1 ;
  }

  return 0 ;
}

Answers


The physical memory address 0x20200000 is being mapped into your process address space at an address stored in the variable gpio, so that's the address you should be examining in gdb. Just print the contents of gpio after gpio_init() has been called and use that value.

As an aside the way the mapping is done is confused. There is no need to allocate a memory block with malloc and then map over it, and it also fails to close the file descriptor. That entire function could be better written as:

int gpio_init (void)
{
  int      fd ;

  if ((fd = open ("/dev/mem", O_RDWR) ) < 0)
  {
    fprintf (stderr, "gpio_init: unable to open /dev/mem: %s\n", strerror (errno)) ;
    return -1 ;
  }

  gpio = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;

  if (gpio == MAP_FAILED)
  {
    fprintf (stderr, "gpio_init: mmap failed: %s\n", strerror (errno)) ;
    close(fd);
    return -1 ;
  }

  close(fd);
  return 0 ;
}

Need Your Help

Override layout of "layout" folder for normal screen device

android layout screen

I implemented all layout files for hdpi devices. And put them in "layout" forder. Now I tested on a normal-screen device, and there's some screen I urgently need to change, because a required input...

Java compare and swap semantics and performance

java performance concurrency jvm compare-and-swap

What is the semantics of compare and swap in Java? Namely, does the compare and swap method of an AtomicInteger just guarantee ordered access between different threads to the particular memory loca...