コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2019年10月6日 >>> 2019年9月23日
link もっと後

2019年10月6日

RISC-Vのバイナリダンプを逆アセンブルする

目次: RISC-V

相変わらず空き時間にRISC-Vのエミュレータを書いています。RV64IMACくらいが必要なのですが、意外と命令の種類が多くていっぺんにやるのは面倒なので、HiFive Unleashedのファームウェアを動かしてみて、足りない命令から実装していくスタイルで開発しています。

HiFive Unleashedの電源を入れたときに真っ先に起動してくるファームウェアというかブートローダはZSBL(Zeroth Stage Boot Loader), FSBL(First Stage Boot Loader)という名前です。

なんと親切なことにソースコードが公開されていますGitHub - Freedom U540-C000 Bootloader Codeのリンク)。素晴らしいですね……。

なぜかUnleashedから引っこ抜いてきたバイナリと、手元でコンパイルしたZSBL, FSBLのバイナリが一致しません。何か間違っているのかも?ちょっと気になります。しかしながら、ソースコードが公開されている意義は非常に大きいです。

メモリマップも公開されています。SiFive Freedom U540 SoCのサイトからダウンロードできます。

Unleashedリセット〜ZSBLを例に解説

U540のマニュアルによると、リセット直後のPCは0x1004で、その後はMSELの値を見て、適切な場所に飛ぶとあります。MSELというのは、Unleashedボード上のDIPスイッチのことです。購入後、変えていなければ状態だと全部ON、つまり0xfになっていると思います。

リセット直後に実行される領域の周辺バイナリをダンプしてみましょう。ダンプには拙作のmemaccess(GitHubへのリンク)を使っています。

Unleashed 0x1000〜0x1040領域のダンプ
# ma db 0x1000 0x40
00001000  0f 00 00 00 97 02 00 00  03 a3 c2 ff 13 13 33 00
00001010  b3 82 62 00 83 a2 c2 0f  67 80 02 00 00 00 00 00
00001020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
00001030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
00001040

何かが書いてあるようですが、RISC-Vのバイナリがスラスラ読めるほど達人ではないので、ファイルにダンプして逆アセンブルします。

Unleashed 0x1000〜0x1040領域の逆アセンブル
$ riscv64-unknown-elf-objdump -EL -D -b binary -m riscv:rv64 --adjust-vma=0x1000 reset.bin
reset.bin:     file format binary

Disassembly of section .data:

0000000000001000 <.data>:
    1000:       0000000f                fence   unknown,unknown
    1004:       00000297                auipc   t0,0x0
    1008:       ffc2a303                lw      t1,-4(t0) # 0x1000
    100c:       00331313                slli    t1,t1,0x3
    1010:       006282b3                add     t0,t0,t1
    1014:       0fc2a283                lw      t0,252(t0)
    1018:       00028067                jr      t0
        ...

先頭が変な命令に見えますが、これは命令ではなくMSELです。値は先程も言ったとおり0xfです。実行されるのは0x1004からです。大した量でもないし、1行毎に見ていきます。

0x1004: auipc t0, 0x0
PC + 0をt0にロードします。t0: 0x1004です。
0x1008: lw t1,-4(t0) # 0x1000
レジスタt1にアドレスt0 - 4 = 0x1004 - 4 = 0x1000つまりMSELをロードします。t1: 0xfです。
0x100c: slli t1,t1,0x3
レジスタt1を3ビット左シフト(= 8倍)します。t1: 0xf << 3 = 0x78です。
0x1010: add t0,t0,t1
レジスタt0とt1を足します。t0: です。t0: 0x1004 + 0x78 = 0x107cです。
0x1014: lw t0,252(t0)
レジスタt0にt0 + 252のアドレスからロードします。アドレスは0x107c + 252 = 0x1178です。後述のとおりt0: 0x10000です。
1018: jr t0
レジスタt0のアドレスにジャンプします。すなわち0x10000にジャンプします。

参考として、アドレス0x1178に何が書いてあるか示しておきます。付近の領域0x1100〜0x1180にはMSELの値に応じたジャンプ先のアドレスが書いてあります。MSELが他の値になったらどこにジャンプするか、眺めてみると面白いかと思います。

Unleashed 0x1000〜0x1040領域のダンプ
# ma dd 0x1100 0x80
00001100  00001004 00000000  20000000 00000000
00001110  30000000 00000000  40000000 00000000
00001120  60000000 00000000  00010000 00000000
00001130  00010000 00000000  00010000 00000000
00001140  00010000 00000000  00010000 00000000
00001150  00010000 00000000  00010000 00000000
00001160  00010000 00000000  00010000 00000000
00001170  00010000 00000000  00010000 00000000    ★0x1178には0x10000が書いてある
00001180

マニュアルの言うとおり、MSELが0xfの場合、リセット後ZSBLにジャンプ、アドレスで言うと0x10000にジャンプすることが確認できました。

以降も同様に0x10000付近をダンプし、逆アセンブルしたり、エミュレータに実行させてみたりして、開発を進めています。今はZSBLは通過して、FSBLの先頭の方まで実行できるようになりました。いうなれば、砂山にトンネルを掘っているような気分でしょうか、なかなか面白いです。

通常は逆アセンブルだけだと処理の意図を掴むことが難しいですけども、その点U540はソースコードが読めるため、当たりを付けることが比較的容易です。しばらくは素敵なおもちゃになりそうなボードです。

編集者:すずき(2021/06/28 15:26)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2019年10月6日 >>> 2019年9月23日
link もっと後

管理用メニュー

link 記事を新規作成

<2019>
<<<10>>>
--12345
6789101112
13141516171819
20212223242526
2728293031--

最近のコメント5件

  • link 25年10月6日
    すずきさん (10/10 13:14)
    「ですね。ccはもはやコンパイラというより...」
  • link 25年10月6日
    hdkさん (10/10 08:27)
    「ただのHello, worldでも試して...」
  • link 25年9月29日
    すずきさん (10/03 00:29)
    「なんと、メタパッケージ入れてなかったです...」
  • link 25年9月29日
    hdkさん (10/02 06:51)
    「あれ、dkmsは自動ビルドされるのが便利...」
  • link 20年8月24日
    すずきさん (08/30 22:06)
    「ですね、自分も今はPulseAudioを...」

最近の記事20件

  • link 25年10月15日
    すずき (10/19 16:54)
    「[PipeWireの音切れ問題 - サーバー側の設定確認と反映] 目次: ALSAPipeWireに変えてから音切れがなくなり...」
  • link 25年10月18日
    すずき (10/19 16:52)
    「[PipeWireの音切れ問題 - サーバー側PipeWireの設定] 目次: ALSAPipeWireに変えてから音切れがな...」
  • link 22年5月5日
    すずき (10/19 16:49)
    「[ALSA - まとめリンク] 目次: ALSAALSAの話。ALSAその1 - 使ってみようALSAその2 - カードとデバ...」
  • link 25年10月19日
    すずき (10/19 16:47)
    「[PipeWireの音切れ問題 - サーバー側pipewire-pulseの設定] 目次: ALSA未だにPipeWireの音...」
  • link 23年4月11日
    すずき (10/19 14:55)
    「[ブラウザー/メーラー - まとめリンク] 目次: ブラウザー/メーラー関係の深いまとめリンク。目次: Linuxブラウザー。...」
  • link 06年4月22日
    すずき (10/19 14:54)
    「[Seamonkey/Firefoxのメモリ使用量最小化] 目次: ブラウザー/メーラーGIGAZINE 2006年4月15日...」
  • link 25年10月17日
    すずき (10/19 14:53)
    「[Linux版Firefoxアドレスバーの黒線] 目次: ブラウザー/メーラーLinuxデスクトップマシンのFirefox(1...」
  • link 25年10月6日
    すずき (10/16 03:20)
    「[makeのデフォルトルールのリンクはLDを使わない] 目次: LinuxMakefileの達人には常識かもしれませんが、ma...」
  • link 25年10月13日
    すずき (10/16 03:19)
    「[PipeWireをPulseAudioサーバーの代わりにする、その2 - 音切れ多発] 目次: ALSA先日(2025年10...」
  • link 20年10月23日
    すずき (10/16 03:15)
    「[ARM - まとめリンク] 目次: ARMROCK64ブート周りの話のまとめ。ROCK64購入ROCK64とU-Bootのd...」
  • link 25年10月12日
    すずき (10/16 03:14)
    「[ROCK 5BのDebianをアップデート] 目次: ARMDebian StableがTrixieに変わったことをすっかり...」
  • link 20年8月29日
    すずき (10/16 02:36)
    「[ROCK64をRaspberry Pi 3のケースに無理やり格納] 目次: ARM先日KADHAS VIM2, VIM3を購...」
  • link 19年1月13日
    すずき (10/16 02:35)
    「[ROCK64とTinker BoardのU-Boot設定メモ] 目次: ARM完全に自分のためのメモですが、ROCK64とT...」
  • link 18年10月13日
    すずき (10/16 02:35)
    「[Welcome back ROCK64] 目次: ARMやっとROCK64を置けそうな場所を確保できて、Linuxカーネルで...」
  • link 18年9月3日
    すずき (10/16 02:35)
    「[ROCK64のカーネルだけ元に戻したい] 目次: ARMROCK64のカーネルを入れ替えていたら、動かないカーネルを書き込ん...」
  • link 18年8月20日
    すずき (10/16 02:35)
    「[ROCK64のU-Bootスクリプトを読む] 目次: ARM先日(2018年7月23日の日記参照)ROCK64のU-Boot...」
  • link 18年7月23日
    すずき (10/16 02:35)
    「[ROCK64とU-Bootのdistro boot] 目次: ARM昨日(2018年7月22日の日記参照)に引き続き、ROC...」
  • link 18年7月22日
    すずき (10/16 02:34)
    「[ROCK64購入] 目次: ARMRockchip RK3328搭載のシングルボードコンピュータ、ROCK64 4GB版を買...」
  • link 18年10月14日
    すずき (10/16 02:34)
    「[ROCK64のアナログオーディオ - その1 - I2Sとクロックレジスタ] 目次: ARMまた忘れてしまいそうなので、メモ...」
  • link 18年11月10日
    すずき (10/16 02:33)
    「[ROCK64のアナログオーディオ - その2 - I2SのDMA問題] 目次: ARM[ROCK64のI2Sが動かない] 先日(2...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 2025年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 10/19 16:54