GR-PEACHでu-bootが動かせない問題&そもそも新しいDAPLink動いてないんじゃ?問題

u-bootのconfig見る限りGR-PEACH対応してるはずなのに、何故かまったく動かせない問題が発端。

結論は、mbedのDAPLink使わずに直接SPIフラッシュ書き込めばOK。この記事は、それができない人向けの解説(?)。加えて、新しめのDAPLinkのファームウェア書き込んでしまった人はu-boot以外もまったく動かせてなかったのでは?という話。

GR-PEACHなどのボードは、USBでPCに接続するとMBEDというドライブが現れて、そこにmbed開発環境で作ったバイナリを入れると、フラッシュに書き込まれて実行が始まる。これがDAPLinkで、GR-PEACHではメインのSoC (RZ/A1H) とは別にあるLPC11U35(Cortex-M0のマイコン)がこの処理を行っている。

ここで、変なバイナリを突っ込むと弾かれる仕組みがある。

uint8_t validate_bin_nvic(const uint8_t *buf)
{
    if (g_target_family && g_target_family->validate_bin_nvic) {
        return g_target_family && g_target_family->validate_bin_nvic(buf);
    } else {
        return validate_bin_nvic_base(buf);
    }
}

https://github.com/ARMmbed/DAPLink/blob/v0258/source/daplink/validation.c#L33

要は、特定のtarget_family用の validate_bin_nvic があればそれを実行し、なければ汎用の validate_bin_nvic_base を実行する。

汎用の方は、先頭がinitial SP value, Reset_Handler, NMI_Handler, HardFault_Handlerとしておかしくないかを確認する。具体的には、SPが各ボードで定義しているRAMの範囲に、各Handlerがフラッシュの範囲に、それぞれ入っていれば良い。

しかし、GR-PEACHの場合は、先頭がそういうアドレスのテーブルではなく、いきなり命令から始まるようになっている。そこで、専用のvalidate_bin_nvic_rzaがある。

このへん。

これは、0xE59FF0XX(のリトルエンディアン)であることを確認していて、要は先頭がarmの ldr pc, [pc, #XX] 命令ならOKというもの。

mbed開発環境でGR-PEACH用に作ったバイナリは0xE59FF018(ldr pc, [pc, #24])になっていて(ARMだと命令実行時点でPCが8進んでいるので)0x18000000(バイナリの先頭=フラッシュの先頭)+ 8 + 0x18(オフセット)= 0x18000020。それで、0x18000020番地には0x18003000が書かれていて、そこにジャンプすることになる。そこから先は何か初期化ルーチンがあったりして、最後は自分で作ったプログラム(0x18004000)にジャンプする模様。

ところが、普通にu-bootをGR-PEACH用にビルドすると(mbedの環境とかではないのもあって)、先頭にブランチ命令(0xEA0000B8)が生成されてしまってこのチェックに引っかかる。

/*
 * A macro to allow insertion of an ARM exception vector either
 * for the non-boot0 case or by a boot0-header.
 */
        .macro ARM_VECTORS
#ifdef CONFIG_ARCH_K3
	ldr     pc, _reset
#else
	b	reset
#endif

https://github.com/u-boot/u-boot/blob/v2026.10/arch/arm/lib/vectors.S#L25

どうやら、ARCH_K3という(よく知らない)のだとお目当ての命令と同じになるようなので、このソースに2箇所ある #ifdef CONFIG_ARCH_K3 を #if defined(CONFIG_ARCH_K3) || defined(CONFIG_RZA1) とかしてやれば、先頭が0xE59FF0XXのu-boot.binができるはず。できた。完。

・・・

だったら良かったんだけど、それでも書き込めない。そのせいでずっと止まってたんだが、

Fix family_id for Renesas targets- #942
https://github.com/ARMmbed/DAPLink/pull/942

(このへんに宇宙猫画像)

Family IDが間違っているということは、そもそも0xE59FF0XXのチェックが行われてなくて、(違ってる方のIDは専用の validate_bin_nvic がないので)汎用の validate_bin_nvic_base が実行されている。つまり、0xE59FF0XXをRAMの範囲と比較して(そんなアドレスにRAMもフラッシュもないというか元々アドレスですらないので)弾かれていたというオチかな。専用開発環境で作ったバイナリも全滅だったのでは?

それで、エラーの時はMBEDドライブにFAIL.txtというファイルができていて、そこにエラーメッセージがあるんだけど、内容が timeout なんだよ。わからんって。

少なくとも0254から0257は全滅。古いのは調べてない。

0258にすれば解決なんだけど、May 10, 2023のPre-Releaseで止まっていて、ソースはあるけどバイナリがない。自分でコンパイルしたらリンク時に警告(エラー扱い)で止まってしまうので、records/tools/gcc_arm.yaml の -Wl,-fatal-warnings を取っ払って解決した(解決したとは言ってない)。

DAPLinkの古いバージョンに戻すのもありかもしれんけど、どこまで戻していいか(戻せばいいか)は不明。

あと、これもどこからか調べてないけれど、新しいバージョンは「ボタン押しながら起動」でメンテナンスモードに入らないバグ(?)があって、DAPLinkファームウェア入れ替えられないという罠もあった。裏のJP2(ジャンパ)使う方法でなんとか脱出。

そんなこんなあって、いまはDAPLink (0258) でドロップインしたu-boot.bin(上記のvectors.S修正)が動いています。