FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-VのLinuxブート環境をbuildrootで構築する (4. ブート用HEXファイルの作り方)

RISC-VのLinuxブート環境を構築したので、次にこれをRTL環境で実行している。

ChipyardやSpikeの環境では、BootROMに、最初のブートシーケンス及びDevice Treeの情報がバイナリ形式で格納されている。 これをどのように作成するのかについてまとめておく。

  1. ブートシーケンスを用意する。今回はRV64用のみ。
.section .text
_init:
    .word       0x00000297 # auipc   t0,0x0
    .word       0x02028593 # addi    a1,t0,24 # 1018 <dtb>
    # la      a1, dtb
        csrr    a0, mhartid

        ld      t0, 24(t0)
        jr      t0
    .word   0
    .word   0x80000000  # start PC
    .word   0x00000000  # start PC
dtb:

ちなみに、AUIPCADDIアセンブリ命令ではなく機械語で挿入したのは、Spikeと完全動作を一致させるために中間変数で使用されるレジスタが変わることを防ぐため。

以下のコマンドでブートシーケンスを含んだbinaryファイルを用意する。

riscv64-unknown-elf-as bootrom.S -o bootrom.o
riscv64-unknown-elf-ld bootrom.o -o bootrom.elf -Tlink.ld
objcopy -I elf64-little  -O binary --only-section .text bootrom.elf bootrom.bin
  1. Device Treeファイルを作成する

テンプレートとなるDevice Tree Fileを用意しておく。

  • dts_skeleton.dts
/dts-v1/;

...
    #size-cells = <0>;
    timebase-frequency = <10000000>;
    CPU0: cpu@0 {
      device_type = "cpu";
      reg = <0>;
      status = "okay";
      compatible = "riscv";
      riscv,isa = "rv|XLEN||EXTENSION|";
      mmu-type = "riscv,|SVMODE|";
      riscv,pmpregions = <16>;

テンプレートの一部を置き換えて、コンフィグレーションにあったDevice Treeファイルを置き換える。

sed 's/|XLEN|/64/g' dts_skelenton.dts | \
        sed 's/|EXTENSION|/imc/g' | \
        sed 's/|SVMODE|/sv39/g' > dts_skelenton_tmp.dts
        dtc -@ -O dtb dts_skelenton_tmp.dts -o dts_rv$(XLEN)$(EXT).dtb
  1. ブート用バイナリの作成

最後に、これをつなぎ合わせてブート用のバイナリを作成する。ダミーファイルを入れているのは自分のRTLシミュレーション環境の問題で、本来は必要ないはず。

cat bootrom.bin dts_rv64imc.dtb dummy.txt > bootrom.img
objcopy -I binary -O verilog --verilog-data-width 16 bootrom.img bootrom.hex

こうして、ブート用のHEXファイルが作成されるので、$readmemhによりROMに格納するわけだ。