c - 在进程空间之外查看 GDB 中的内存 (mmap)

标签 c gdb mmap raspberry-pi

问题:

出于教育目的,我正在尝试准确理解 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 ;
}

最佳答案

物理内存地址 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 ;
}

关于c - 在进程空间之外查看 GDB 中的内存 (mmap),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11517306/

相关文章:

c - 对于决策错误,调试 Xtext 甚至无法执行 k=1

c - 字符串长度始终为 0

c - 为什么 isnormal() 说一个值是正常的,而实际上不是?

c - 进程在不应运行的线程中崩溃

c - 缓冲区溢出问题

c - 为什么要在函数序言/结语中使用 ebp?

objective-c - 在越狱的 iPod touch 上使用 gdb 调试 iOS 应用程序 | Objective-C 符号

c++ - 使用 mmap 读/写寄存器

c - mmaping 大文件(用于持久性大数组)

c - fork() 之后无法从子进程检索 mmap 共享内存