MMR宣言ファイルの独立化

かなり古い経緯になりますが、ある時期、TOPPERS/JSPのビルドファイルに、MMRの宣言ファイルを追加しました。

どういうものかというと、これがちょっと一言では言いにくいのですが、BlackfinのMemory Mapped Registerを、メモリ上に投影するものです。このファイルで宣言される変数は名前がmmrからはじまり、後半部分がBlackfin DPSのMMRと同じ名前になっています。何故こんなものが必要かというと、gdbで便利に使えるからです。当然ながらgdbはBlackfinのMMRのアドレスなど知りません。そのため、ペリフェラルのデバッグ時に難儀することになりました。毎回変数のアドレスを調べるなんてばかばかしいと考えたのがこのファイルを作るきっかけでした。

作成は一筋縄ではいきませんでした。そもそも膨大なMMRファイルを作るための情報集めからして純粋な肉体労働でした。加えて、頭を使う必要があります。MMRと同じ位置に配置する変数は、C言語の変数ですが、しかし、値がBlackfinにロードされてはなりません。そんな事をすればBlackfinがクラッシュしてしまいます。従って、一旦リンクして正しいアドレスにマップしたあと、objcopyを使って変数実体だけ削り取り、シンボルを残すという荒技が必要でした。

こうして作ったシンボルは期待通りの働きをしましたが、後になって重大な問題を引き起こしました。MMRを含んでいるために削除されたセクションには「最後のセクション」フラグが立っていました。ところが、objcopyによる削除によって、最後のセクションに立っていたこのフラグも消えます。これに引っかかったのがbfin-elf-ldrユーティリティです。このユーティリティはELFからBlackfinのローダーファイルであるLDRファイルを生成します。しかし、このツールはLDRに必要なロードの終了フラグを、ELFの最後のセクションのフラグから生成していたのでした。結局、objcopyが最後のセクションというフラグごとセクションを削ったため、LDRの中にロード終了フラグが生成されず、ロード時にクラッシュを引き起こすことになりました。

現在、この問題の対策を考えています。MMRファイルを削除すれば問題は解決であるため、JSPカーネルからはcore_mmr.cとchip_mmr.cを削除します。しかしこのままではgdbを使いにくくなるため、現在別アプリケーションとしてcore_mmr.cとchip_mmr.cだけをリンクしたファイルを試しているところです。結果から言えば、これはあっさり成功しました。シンボルだけこのファイルから読み出せば、多分通常のアプリケーションのデバッグが楽になるはずです。gdbでファイルからシンボルを読み込んで、現在のシンボルテーブルには、add-symbol コマンドを使います。

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください