FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

BFDからバイナリデータを抽出してISSを動作させる(1)

いよいよ、libbfdの使い方が分かってきたので、ISSに組み込んでシミュレータに流し込む実験に入ろう。 ただ、仕事が忙しくて、家に帰ってからもなかなか時間がとれない。

github.com

とりあえずは、まずはダンプ機能をISSに入れてみるところまで。ISSでは、LoadSrec()という関数を作成しており、これを利用してsrecからデータをロードする仕組みを持っている。 これをLoadBfdFile()という関数に置き換えて、バイナリファイルから情報を読み込むようにしてみよう。

uint32_t EnvBase::LoadBfdSrec (std::string filename)
{
    try {
        // open binary
        bfd *abfd = bfd_openr (filename.c_str(), NULL);
        bfd_check_format (abfd, bfd_object);

        // disasemble
        bfd_map_over_sections (abfd, load_bitfile, static_cast<void *>(&m_memory_vec));

    } catch (std::string str) {
        std::cerr << str;
        exit (EXIT_FAILURE);
    }

}

前回も説明したとおり、bfd_map_over_sectionsは、セクション毎に関数を呼び出すものだ。ここではload_bitfileをstatic_cast(&m_memory_vec)の引数を付けて呼び出している。

msyksphinz.hatenablog.com

static void load_bitfile (bfd *b, asection *section, PTR data)
{
    std::vector <MemoryBlock *> *p_mem_vec = static_cast<std::vector <MemoryBlock *> *>(data);

    if (!section->flags & SEC_ALLOC) return;
    if (!section->flags & SEC_LOAD) return;
    if (section->flags & SEC_LINKER_CREATED) return;
    if (section->flags & SEC_CODE) {
        if (!strncmp (".plt", section->name, 4) ||
            !strncmp (".got", section->name, 4)) {
            return;
        }
        load_hex (b, section, p_mem_vec);
    } else if (section->flags & SEC_DATA ||
               section->flags & SEC_HAS_CONTENTS) {
        load_hex (b, section, p_mem_vec);
    }

    return;
}

まずは引数daatをstd::vector * 型に変換して、ベクタとして扱えるようにする。 ここから先は、前の記事と一緒だ。データを読み込んで、ベクタにロードする前にとりあえずダンプして、正常にデータを抽出できていることを確認する。

static void load_hex (bfd *b, asection *section, std::vector <MemoryBlock *> *p_mem_vec)
{
    int i, j, size;
    unsigned char *buf;
    size = bfd_section_size (b, section);
    buf = static_cast<unsigned char *>(calloc (size, 1));
    if (!bfd_get_section_contents (b, section, buf, 0, size))
        return;

    /* do hex dump of data */
    for (int i = 0; i < size; i+= 16) {
        printf ( "%08x:  ", section->vma + i);
        for (j = 0; j < 16 && j + 1 < size; j++) {
            printf ("%02x ", buf[i+j]);
        }
        for (; j < 16; j++) {
            printf ("    ");
        }
        printf ("  ");
        for (j = 0; j < 16 && j+i < size; j++) {
            printf ("%c", isprint (buf[i+j]) ? buf[i+j] : '.');
        }
        printf ("\n");
    }
    free (buf);
    return;
}

これでバイナリファイルを読ませて、実行してみる。

$ swimmer_riscv --hexfile ~/benchmarks/coremark_v1.0/coremark.bin --max 10
Swimmer-RISCV
  Version 20150817 Revision 3d8fac8
  developed by Masayuki Kimura <masayuki.kimura.1986@gmail.com>
00000100:  97 01 00 7f 93 81 01 f1 17 41 00 7f 13 01 01 f0   .........A......
00000110:  b3 00 00 00 33 02 00 00 b3 02 00 00 33 03 00 00   ....3.......3...
00000120:  b3 03 00 00 33 04 00 00 b3 04 00 00 33 05 00 00   ....3.......3...
00000130:  b3 05 00 00 33 06 00 00 b3 06 00 00 33 07 00 00   ....3.......3...
00000140:  b3 07 00 00 33 08 00 00 b3 08 00 00 33 09 00 00   ....3.......3...
00000150:  b3 09 00 00 33 0a 00 00 b3 0a 00 00 33 0b 00 00   ....3.......3...
00000160:  b3 0b 00 00 33 0c 00 00 b3 0c 00 00 33 0d 00 00   ....3.......3...
00000170:  b3 0d 00 00 33 0e 00 00 b3 0e 00 00 33 0f 00 00   ....3.......3...
00000180:  b3 0f 00 00 17 24 00 80 13 04 44 16 e7 00 04 00   .....$....D.....
00000190:  93 00 10 00 73 90 00 78 6f f0 9f ff 13 00 00 00   ....s..xo.......
7f000000:  d0 30 00 80 d8 30 00 80 e0 30 00                       .0...0...0..
7f00000c:  01 00 00 00 01 00 00 00 66 00 00                       ........f...
80000000:  63 0a 06 00 03 15 25 00 83 97 25 00 33 05 f5 40   c.....%...%.3..@
80000010:  67 80 00 00 03 17 05 00 93 17 07 01 93 d7 07 01   g...............
80000020:  13 77 07 f0 93 d7 87 00 b3 67 f7 00 23 10 f5 00   .w.......g..#...
80000030:  03 97 05 00 03 15 25 00 93 17 07 01 93 d7 07 01   ......%.........
80000040:  13 77 07 f0 93 d7 87 00 b3 67 f7 00 23 90 f5 00   .w.......g..#...
80000050:  83 97 25 00 33 05 f5 40 67 80 00 00 13 01 01 fe   ..%.3..@g.......
80000060:  23 2c 81 00 03 14 05 00 23 2e 11 00 23 2a 91 00   #,......#...#*..
...

やった、ちゃんとデータを取得できている!

さて、次はいよいよこのデータをISSのメモリに格納していこう (つづく)。