分解して下調べをしていたDDR mini
既にファームウェアアップデート用のUSBを探しそうな画面が発見されていますが、
これは適当にUSBを挿せばいいものではなく、必要な条件のもとパッケージングしたものに対して発動するものだと思われます。
DDRmini 本体のStartボタンを左右同時押ししながら電源投入するとファームウェアアップデートモードに入るんだけど、コレってワンチャンあるのか!? #DDRmini pic.twitter.com/Z7P9Nc5ekK
— Иaoya@でんきや (@Smith708) September 13, 2024
その条件を調べることや、他にバックドアがないかどうかを調べるため、内部のソフトウェアを調べていきます。
で、どうやって?
まず、このAllwinnerのCPUは、FELモードというUSB経由であれやこれやするためのモードが備わっていますが、ここで行うことができるのはプログラムの転送ぐらいです。
まずFELモード上でu-bootなどのブートローダを転送して実行し、そのあとファームウェアを転送して書き込んだりすることができます。
過去にさんざん弄ったファミコンミニの系列はこの方法でカーネル書き換えが進められてきました。
しかし、今回採用されたA527というCPU、かなり新しいもので従来使われていたようなu-bootが対応できていないようで、まともにコンパイルできるツリーが見つかりませんでした。そのため、何か他の方法を使わなければなりません。
いろいろ探していたとこ、A527やその互換のT527というCPUを搭載したAvaotaSBCというオープンソース設計の組み込みボードがあるのを見つけました。
また、それに対応したベアメタルの開発環境、そしてブートローダとLinuxの入ったOSイメージがあります。これが使えそうだと踏んで調査を行いました。
Allwinner系のCPUの多くは、起動シーケンスとしてeMMC(8bit onboard SDC2)のほかに、SDカード(4bit SDC0)やSPI Flash、NAND等いろいろなストレージから起動できます。
A527は都合がいいことに、基板上のeMMCより先に、今回基板上からオミットされたSDカードスロットから起動することがデータシートに記載されていました。
そのため、まずSDカードスロットを復活させました。
しかし、SDカードソケットを付けてもそのままでは使えません。
きちんと使えないように、各信号線が基板上で分断されていますので、そこをすべてジャンパし、またCLK以外の線は10Kオームでプルアップする必要があります。
よしよしよし!謎が解けたぞ
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 12, 2024
この青色をジャンパ、赤色は10kでプルアップすればSD繋がるはず!
CLKとDET、ワザとシールドに隠したな! pic.twitter.com/aOTKnduWcf
この配線を行い、SDスロットの信号を見ながら電源を入れるとCLK信号が観測され、SDカードを探しに来ていることが確認できました。
よしよしよし 電源投入時にSD初期化CLK出てるぞ! pic.twitter.com/Jbkb4JSzF3
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 12, 2024
次はSDカードの中身の準備です。
先ほど見つけたベアメタルの環境をコンパイルし、テストコードをいくつか書いてみます。
一応動いているようですが、動いた結果が観測できません。
なぜなら、標準入出力であるシリアルポートが発見できていないからです。
今までのミニコンソールは、それっぽいところを当たりながら電源を入れればすぐにブートローダやLinuxのメッセージが表示されていました。が、今回は徹底的にその動作が潰されていて、全く信号が確認できません。
とはいえ、シリアルの配線は絶対に残っているはずです。
うーん.... pic.twitter.com/QG5utWIE0w
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 12, 2024
データシートとピンアサイン、そして基板上の配線を穴が開くほど見つめながらプログラムを調整したところ、見事にシリアルポートをの出力を確保できました。
うっしゃぁキタでこれぇ!
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 14, 2024
取り付けたSDスロットにA527用のベアメタルの開発環境で作ったバイナリ書いてシリアル出力できたで!
やっぱ元のDDR環境ではシリアル出力が完全に抑制されてるように見える
おかげで探すのに大変手間取ったUART0はPB9,10のマッピングになってたぞ#DDRmini https://t.co/M5TbXK1Ast pic.twitter.com/3WO3T1n9pQ
プログラムが動いたらこっちのもの。eMMCの中身を読み込み、SDカードに保存して解析すればいいのです。
というわけで、先ほどの環境からSDカードを使っているサンプルを改造し、実装してみましたが。。。。。動かん。っていうか、動きが変。
どうやら、SDカードとeMMC、どちらかしか使わないと仮定してあり、各パラメータを保存するメモリを一つ分しか確保しないコードになっていました。
これを修正し、カード二枚が同時に使えるようにしたところ、無事、eMMCとSDカードどちらからも読み込めるようになったんですが・・・・書き込めない!!!!
オンボードeMMCが認識できたので、これで中身が吸い出せるぞ。が、DRAMを初期化しようとするとおそらくパラメータがほかの基板用なので失敗してしまう。なので起動環境内のRAMでやらないといけないが・・・何キロかはあるといいな。マップどこだ。
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 14, 2024
最悪シリアルからhexdumpなんだけどw… pic.twitter.com/4Qo1VDX5xV
さんざん悩みつつ調べた結果、書き込み部分が実装されていませんでしたw
というのは一寸違ってて、実はSDカードの伝送、高速化のために普通はDMAによるメモリ転送を使い、まとめて転送するようになっています。
今回のベアメタル環境、DDRMiniの環境と完全に同じではないため、基板上のDDRメモリの初期化が行えず、大きなメモリ空間やDMAが使えない状態でした。
そのため、DMAではなくFIFOに1バイトずつ書き込む”CPU転送”モードを使う必要があったのです。サンプルソースのドライバでは、DMAの部分は読み書きどちらも実装されていましたが、CPU転送、レスポンスの読み込みにしか使わないので書き込む部分は省略されてたんですね。気づくのにしばらくかかりました。
Linuxのドライバのソースなどを参照し、この部分を実装すると、見事eMMCの内容をSDカードに書きこむことができるようになりました。
やったーeMMCの中身をSDカードにまるっと書きだすプログラムができたぞー… pic.twitter.com/Bute6RmR34
— ひろみつ@技術書典お07 カラオケハック本 (@bakueikozo) September 17, 2024
書き込めたらこっちのもの。中身を調べていきます。つづく。