4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry Pi 5 のペリフェラルチップRP1にレジスタアクセスしてみる。

Last updated at Posted at 2026-01-18

はじめに

Raspberry Pi 5 の40pinのGPIOは直接SoCに繋がっておらず、RP1というチップに集約され、PCIe経由で接続している構成であることがわかった。このRP1に直接レジスタアクセスできないか?を試してみた。

Raspberry Pi RP1 Peripherals のドキュメント

下記PDFがドキュメント。メモリマップを見ると下記となっていた。

Block Address
uart0 0x40030000
spi0 0x40050000
spi1 0x40054000
i2c0 0x40070000
i2c1 0x40074000
pwm0 0x40070000
pwm1 0x4009C000
io_bank0 0x400d0000

これがラズパイ上、どのように物理アドレスにマッピングされているのかcat /proc/iomemで確認すると 0x1f_0000_0000にマッピングされていそうで、例えばGPIOのピン制御をするio_bank00x1f000d0000のよう。

$ cat /proc/iomem
00000000-00000000 : reserved
00000000-00000000 : System RAM
・・・
00000000-00000000 : pcie@1000120000
00000000-00000000 : pcie@1000120000
  00000000-00000000 : PCI Bus 0002:01
    00000000-00000000 : 0002:01:00.0
      00000000-00000000 : 1f00008000.mailbox mailbox@8000
      00000000-00000000 : 1f00018000.clocks clocks@18000
      00000000-00000000 : 1f00030000.serial serial@30000
      00000000-00000000 : 1f00050000.spi spi@50000
      00000000-00000000 : 1f00074000.i2c i2c@74000
      00000000-00000000 : 1f00098000.pwm pwm@98000
      00000000-00000000 : 1f0009c000.pwm pwm@9c000
      00000000-00000000 : 1f000c8000.adc adc@c8000
      00000000-00000000 : 1f000d0000.gpio gpio@d0000
      00000000-00000000 : 1f000d0000.gpio gpio@d0000
      00000000-00000000 : 1f000d0000.gpio gpio@d0000
      00000000-00000000 : 1f00100000.ethernet ethernet@100000
      00000000-00000000 : 1f00178000.pio pio@178000
      00000000-00000000 : 1f00188000.dma dma@188000
      00000000-00000000 : usb@200000
        00000000-00000000 : xhci-hcd.0 usb@200000
      00000000-00000000 : 1f00200000.usb usb@200000
      00000000-00000000 : usb@300000
        00000000-00000000 : xhci-hcd.1 usb@300000
      00000000-00000000 : 1f00300000.usb usb@300000
    00000000-00000000 : 0002:01:00.0
      00000000-00000000 : 1f00400000.sram sram@400000
    00000000-00000000 : 0002:01:00.0

mmap()でアクセスしてみる

/dev/memだとアクセス制限でmmap()ができなかったので、他の方法がないか確認してみる。/dev 配下に /dev/gpiomem0,1,2,3,4というのがあったので、素性を知るためdmesgで確認。gpiomem0io_bank0に一致。サイズが0x30000なのでアドレス配置的に io_bank0(0x1f_000d0000)〜pads_bank2(0x1f_000fc000)までアクセスできそう。

$ dmesg | grep gpiomem
[    7.118194] rpi-gpiomem 107d508500.gpiomem: window base 0x107d508500 size 0x00000040
[    7.118371] rpi-gpiomem 107d508500.gpiomem: initialised 1 regions as /dev/gpiomem1
[    7.118414] rpi-gpiomem 107d517c00.gpiomem: window base 0x107d517c00 size 0x00000040
[    7.118445] rpi-gpiomem 107d517c00.gpiomem: initialised 1 regions as /dev/gpiomem2
[    7.118465] rpi-gpiomem 107d504100.gpiomem: window base 0x107d504100 size 0x00000020
[    7.118628] rpi-gpiomem 107d504100.gpiomem: initialised 1 regions as /dev/gpiomem3
[    7.118654] rpi-gpiomem 107d510700.gpiomem: window base 0x107d510700 size 0x00000020
[    7.118680] rpi-gpiomem 107d510700.gpiomem: initialised 1 regions as /dev/gpiomem4
[    7.118762] rpi-gpiomem 1f000d0000.gpiomem: window base 0x1f000d0000 size 0x00030000
[    7.118930] rpi-gpiomem 1f000d0000.gpiomem: initialised 1 regions as /dev/gpiomem0

Cでコードを書くと

gpiomem0.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

int main() {
    const size_t SIZE = 0x30000;
    // mmapでOpen (/dev/gpiomem0 size=0x30000)
    int fd = open("/dev/gpiomem0", O_RDWR | O_SYNC);
    if (fd < 0) {
        perror("open");
        exit(1);}
        
    void *map = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(1);}
    close(fd);

    // 出力ファイル
	FILE *outfile = fopen("gpiomem0_dump.txt", "w");
	if (!outfile) {
		perror("fopen");
		munmap(map, SIZE);
		exit(1);}

    // 32bitずつ出力
    for (size_t i = 0; i < (SIZE/4); i++) {
        uint32_t val = ((volatile uint32_t *)map)[i];
		fprintf(outfile, "%08zx : %08x\n", i * 4, val);        
    }

    munmap(map, SIZE);
    return 0;
}
$ gcc gpiomem0.c -o gpiomem0
$ ./gpiomem0

結果は下記の通り。

00000000 : 0abe0000
00000004 : 00000085
00000008 : 0abe0000
0000000c : 00000085
00000010 : 06700000
00000014 : 00000083
00000018 : 0abe0000
0000001c : 00000083
00000020 : 04400000
00000024 : 0000009f
00000028 : 04400000
0000002c : 0000009f
00000030 : 088e0000
00000034 : 00300085
00000038 : 0aae3300
0000003c : 00000085
00000040 : 0abe3300
00000044 : 00000085
00000048 : 06700000
0000004c : 00000080
00000050 : 06700300
00000054 : 00000080
00000058 : 06703000
0000005c : 00000080
00000060 : 04403000
00000064 : 00000080
00000068 : 06703000
0000006c : 00000080
00000070 : 0aae3300
00000074 : 00000084
00000078 : 0aae0000
0000007c : 00000084
00000080 : 04400000
00000084 : 0000009f
00000088 : 04400000
0000008c : 0000009f
00000090 : 04400000
00000094 : 0000009f
00000098 : 04400000
0000009c : 0000009f
000000a0 : 04400000
000000a4 : 0000009f
000000a8 : 04400000
000000ac : 0000009f
000000b0 : 0abe3300
000000b4 : 00000085
000000b8 : 04400000
000000bc : 0000009f
000000c0 : 04400000
000000c4 : 0000009f
000000c8 : 04400000
000000cc : 0000009f
000000d0 : 0abe3300
000000d4 : 00000085
000000d8 : 0abe3300
000000dc : 00000085
・・・・・

参考

以上

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?