Help us understand the problem. What is going on with this article?

Golangから物理メモリを読み書きする

More than 1 year has passed since last update.

Golangではシステムコールのmmapを使用することができるので、/dev/mem かUIOで作成した/dev/uioX をmmapすれば物理メモリを読み書きすることができます。
ここではUIOを使った例を紹介します。

UIOのデバイスを登録する

UIOについてはこの記事を参照してください。
LinuxのUIO(User space I/O) その1
この記事に従って、/dev/uio0 が作成できたとして、次にそれをGolangで書かれたプログラムからアクセスする方法を示します。

Golangのサンプルプログラム

ソースコードはgistに置きました。ここ

func mmapRegs32(addr uint32, n int) []uint32 {
    file := "/dev/uio0"

    f, err := os.Open(file)
    if err != nil {
        log.Fatal(err)
    }

    offset := int64(addr) &^ 0xfff
    data, err := syscall.Mmap(int(f.Fd()), offset, (n+0xfff)&^0xfff, syscall.PROT_READ, syscall.MAP_SHARED)
    if err != nil {
        log.Fatalf("mmap %s: %v", f.Name(), err)
    }
    f.Close()

    map_array := (*[math.MaxInt32 / 4]uint32)(unsafe.Pointer(&data[0]))
    return map_array[(addr&0xfff)/4 : ((int(addr)&0xfff)+n)/4]
}

Cのプログラムと同様のパラメータでSyscall.Mmap()を使用します。このメソッドは戻り値が[]byte です。
バイト単位でアクセスしたい場合はこれをこのまま使用すればよいです。
今回は4バイト単位でアクセスしたいので、[]uintの型で欲しいところです。
そのためには、一度大きなサイズのuint32の配列のポインタに変換してから、それをベースにする[]int のスライスを作成すればよいです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away