【问题标题】:Viewing Memory in GDB Outside of Process Space (mmap)在 GDB 中查看进程空间之外的内存 (mmap)
【发布时间】:2012-07-17 06:47:32
【问题描述】:

问题:

出于教育目的,我正在尝试准确了解 RaspberryPI 如何与其 GPIO 接头接口。我有一个简单的程序,可以控制扩展板上的 LED,效果很好。但是,我想使用 GDB 来查看程序更改映射控制寄存器中的位。通常我会在 GDB 中做这样的事情:

x /t 0x20200000

但这似乎会导致如下错误,推测是因为目标内存不在进程空间中:

0x20200000: Cannot access memory at address 0x20200000

我尝试映射内存区域,但似乎没有帮助。

mem 0x20200000 0x20208192

我也确实编写了一个从 GDB 调用的函数,但不知道如何编写返回我感兴趣的整个内存块的东西,因此可以查看为二进制文件(我不想偷看每个字节因为写入位在区域上相当分散)。 有什么方法可以在 GDB 中做到这一点?

支持代码

要映射的内存地址:

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

指向映射内存的指针:

static volatile uint32_t *gpio ;

映射例程:

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 ;
}

【问题讨论】:

    标签: c gdb mmap raspberry-pi


    【解决方案1】:

    物理内存地址0x20200000 被映射到您的进程地址空间中存储在变量gpio 中的地址,因此您应该在gdb 中检查该地址。只需在调用gpio_init() 后打印gpio 的内容并使用该值即可。

    顺便说一句,映射完​​成的方式很混乱。无需使用malloc 分配内存块然后对其进行映射,并且它也无法关闭文件描述符。整个函数最好写成:

    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 ;
    }
    

    【讨论】:

    • 很高兴我不是唯一一个看到 MAP_FIXED + malloc 并想知道发生了什么的人。
    • 感谢重写,将测试。如果没有您的更改,执行此“x /t gpio”会导致“0xABCDEF:无法访问地址 0xABCDEF 处的内存”。您希望您的更改会改变这一点吗?
    • @Scruffers:听起来gpio_init() 还没有被调用。
    • @caf - 我确定它有。阅读这个帖子,也许我正在尝试的事情是不可能的? stackoverflow.com/questions/654393/…
    • @Scruffers:啊,是的——你说得对,/dev/mem 设备显然没有实现 ptrace 访问器。
    猜你喜欢
    • 2011-06-26
    • 2011-10-23
    • 2012-06-15
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 2016-08-14
    • 2020-10-10
    • 2014-09-30
    相关资源
    最近更新 更多