17 |
RISC-Vの調査 (6) |
Bsimによるシミュレーション
QemuのシミュレーションからBsimのシミュレーションに切り替えます。ここで、Flute SoCではUARTのアドレスが異なっているため、テストプログラムのUARTアドレスを
<volatile char* UART0_ADDR = (char*)0x10000000;
>volatile char* UART0_ADDR = (char*)0xc0000000;
と変更した上でコンパイルします。
$ riscv32-unknown-elf-gcc -march=rv32i -mabi=ilp32 -nostartfiles -Tlink.lds -Wall -O2 hello.c -o hello.elf
ここで、リンカへの指示であるlink.ldsは以下のようにしています。
OUTPUT_ARCH("riscv")
ENTRY(main)
SECTIONS
{
. = 0x80000000;
.text.startup : { *(.text.startup) }
.text : {
_start = .;
*(.text);
_text_end = .;
exit = .;
}
.rodata : { *(.rodata) }
.sdata : { *(.sdata) }
.bss : { *.(.bss) }
/DISCARD/ : { *(.comment);
*(.riscv.attributes);
*(.strtab*);
*(.shstrtab);
}
. = ALIGN(8);
= . + 0x4000;
sp_top = .;
}
前稿で作成したelfを、Bsimによるシミュレーションが可能なhexファイルに変換します。これはFlute/Tests/elf_to_hex/elf_to_hexで行います。
$ ../Flute/Tests/elf_to_hex/elf_to_hex hello.elf Mem.hex
c_mem_load_elf: hello.elf is a 32-bit ELF file
Section .text.startup : addr 80000000 to addr 8000006c; size 0x 6c (= 108) bytes
Section .sdata : addr 80000068 to addr 80000070; size 0x 8 (= 8) bytes
Section .comment : Ignored
Section .riscv.attributes: Ignored
Section .symtab : Searching for addresses of '_start', 'exit' and 'tohost' symbols
Writing symbols to: symbol_table.txt
No 'exit' label found
No 'tohost' symbol found
Section .strtab : Ignored
Section .shstrtab : Ignored
Min addr: 80000000 (hex)
Max addr: 80000073 (hex)
Writing mem hex to file 'Mem.hex'
Subtracting 0x80000000 base from addresses
作成されたhello.hexの内容は以下のようになっています。逆アセンブルリストと比較して概ね良さそうです。
@0000000 // raw_mem addr; byte addr: 00000000
00c6802306c007130707a68300d7002306500613068006930707a703800007b7 // raw_mem addr 00000000; byte addr 00000000
0707a70300d7002306f006930707a70300e680230707a68300e680230707a683 // raw_mem addr 00000001; byte addr 00000020
000057b706c7a703800007b700e7802300a007130707a78300d7002302100693 // raw_mem addr 00000002; byte addr 00000040
00000000000000000000000010000000001000000000806700f7102355578793 // raw_mem addr 00000003; byte addr 00000060
@07fffff // last raw_mem addr; byte addr: 0fffffe0
000000000000000000000000000000000000000000000000000000000000000 // raw_mem addr 007fffff; byte addr 0fffffe0