OpenOCDでU-Bootを更新する
tftpdなどを使うのが面倒なのと失敗してもやり直しができる安心感があるので、OpenOCDを使いJTAG経由でU-Bootを書き換えます。
Vine 4.2/5.0用RPMを作成しました。CentOSでも動くかも。なお、Fedora12ではパッケージが存在するようなのでyumでインストール可能だと思います。
SubversionリポジトリのtrunkをビルドするとOBSOLETEというエラーが出てビルドに失敗します(しかも最後の方に出る・・・)ので0.2.0Releaseを使うとよさそうです。多分リリースされたのでそれを使え、ってことだと思います。
- Windows版バイナリも存在します -- http://www.yagarto.de/howto/openocd/index.html
準備
以下の状態にします。
- SheevaPlug上でLinuxが起動していない(U-Bootのプロンプトあたりがいいでしょう)
- 母艦側PCからは/dev/ttyUSB0が見えている
そのための作業の例
まず母艦側PCからシリアル接続をします。
# modprobe ftdi_sio vendor=0x9e88 product=0x9e8f
これでシリアル接続が成功すれば/dev/ttyUSB0と/dev/ttyUSB1が作成されるはずです。そこからscreenで接続します。
# screen /dev/ttyUSB1 115200
接続できたらログインし、SheevaPlugを再起動します。再起動時のU-Bootが起動している最中で何かキーを押し、U-Bootプロンプトで待機します。なお、screenから抜けるにはCtrl-Aを押して、kを押すことで現在のスクリーンを終了することができます。
Marvell>>
これで書き換えの準備ができました。この状態で接続しておくと更新が完了したときのリブートがわかるのでちょうどいいかも。
書き換え
再び母艦PCから作業です。OpenOCDコマンドで書き換えます。カレントディレクトリにuboot.binを配置し以下のコマンドで書き換えられます。
[root@localhost root]# openocd -f /usr/share/openocd/scripts/board/sheevaplug.cfg -c init -c sheevaplug_reflash_uboot Open On-Chip Debugger 0.2.0 (2009-12-13-23:07) Release $URL: http://svn.berlios.de/svnroot/repos/openocd/tags/openocd-0.2.0/src/openocd.c $ For bug reports, read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS 2000 kHz jtag_nsrst_delay: 200 jtag_ntrst_delay: 200 dcc downloads are enabled Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2) Info : JTAG Tap/device matched target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x000000d3 pc: 0xffff0000 MMU: disabled, D-Cache: disabled, I-Cache: disabled 0 0 1 0: 00052078 NAND flash device 'NAND 512MiB 3,3V 8-bit' found successfully erased blocks 0 to 4 on NAND flash device 'NAND 512MiB 3,3V 8-bit' <-- ここで3-4分待つ wrote file uboot.bin to NAND flash 0 up to offset 0x00073000 in 207.011871s
wrote file...の行が出力されると書き込み完了です。環境にもよると思いますが3-4分程度だと思います。
無事に更新できた場合、U-Bootが自動的にリブートするようです。変なU-Bootを書き込み、起動しなくなっても同様の手順で書き換えれば復旧するのでいろいろいじりたい人でも安心です 。一度U-Bootのビルドオプションを間違い、気づかずそのまま書き込んでしまったところ動かなくなりましたが、適切なU-Bootを書き込んで復活可能でした。この場合もやはり自動でリブートするようです。
参考にさせていただいたサイト
OpenOCDで遊ぶ
OpenOCDはその名の通りデバッガなので、JTAG経由でコマンドを送り込んだりしていろいろ遊べるようです。
あまり詳しくは調べてないのですが、OpenOCDはサーバとして動作し、Telnet経由で接続することができます。
サーバの起動
この例ではSheevaPlugに接続します。
# openocd -f /usr/share/openocd/scripts/board/sheevaplug.cfg Open On-Chip Debugger 0.3.1 (2009-12-24-11:03) $URL$ For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html 2000 kHz trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain jtag_nsrst_delay: 200 jtag_ntrst_delay: 200 dcc downloads are enabled Warn : use 'feroceon.cpu' as target identifier, not '0' Info : clock speed 2000 kHz Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2) Info : Embedded ICE version 0
こんな感じ。サーバを停止する場合はCtrl-Cで停止します。
Telnetで接続
Telnetで先ほど起動したOpenOCDに接続します。デフォルトではポートは4444のようです。
% telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger >
こんな感じです。以降ではOpenOCDのプロンプトをOpenOCD>と記述します。
SheevaPlugの環境変数領域をダンプする
あまり使用することはないと思いますが、SheevaPlugのNANDの内容をファイルに出力する場合は以下のようにします。以下のアドレスをだと環境変数が格納されている領域になります。なお、読み出しの速度は相当遅いようで、4KB読み出すのに1分ほどかかりました。格納している環境変数の数にもよりますが、私の場合は4KBですべて収まりました。
OpenOCD> init <-- OpenOCDサーバ初期化 OpenOCD> sheevaplug_init <-- SheevaPlugをhalt target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x000000d3 pc: 0xffff0000 MMU: disabled, D-Cache: disabled, I-Cache: disabled 0 0 1 0: 00052078 OpenOCD> nand probe 0 <-- NANDを認識 NAND flash device 'NAND 512MiB 3,3V 8-bit' found OpenOCD> nand dump 0 sheeva-env.bin 0xa0000 0x1000 <-- 0xa0000から4KB(0x1000)読み取り dumped 4096 byte in 67.108826s OpenOCD> resume <-- 作業が終了したら再起動 OpenOCD> exit <-- 接続終了
こんな感じです。出力ファイル名を絶対パスで指定していない場合はOpenOCDサーバを起動したディレクトリからの相対パスになります。ここで出力したファイルを同じアドレスである0xa0000以降に書き込めば環境変数を復旧させることができます。
まあ、メモした方が早い気もしますが。
U-Bootの環境変数領域は先頭4バイトがデータ部のCRC32になっており、それ以降に変数名=値の形式で格納されていて、各変数は0x00で区切られています。
その他の応用は/usr/share/openocd/scripts/board/sheevaplug.cfgなどを参考にしてください