RAM常駐イメージをチェックサム自体に取得しようとしていますが、これは言うは易く行うは難しです。
コードは最初にクロス開発プラットフォームでコンパイルされ、.elf 出力が生成されます。ユーティリティを使用してバイナリ イメージを削除し、そのイメージをイメージ サイズと共にターゲット プラットフォームに焼き付けてフラッシュします。ターゲットが開始されると、バイナリが RAM の正しい領域にコピーされ、そこにジャンプします。このユーティリティは、RAM に送信される elf 内のすべての単語のチェックサムも計算し、それもフラッシュに焼き付けます。したがって、私のイメージは、理論的には、事前の開始アドレスとフラッシュに保存されたサイズを使用して、独自の RAM 常駐イメージをチェックサムし、フラッシュに保存された合計と比較できます。
とにかくそれが理論です。問題は、イメージの実行が開始.data
されると、変数が変更されるとセクションが変更されることです。合計が完了するまでに、合計されたイメージは、ユーティリティが合計を計算したイメージではなくなります。
チェックサムルーチンをアプリ内の他のすべての初期化の前に移動することで、アプリケーションで定義された変数による変更を排除しました (整合性チェックが失敗した場合に実行する理由は理にかなっていますよね?)。キラーはCランタイムそのものです。malloc
ポインターのキャスティングなどに関連して、入力前に変更された項目がいくつかあるようmain()
です。
自己チェックサム C コードの全体的なアイデアは不十分ですか? アプリと CRT の .data を別のセクションに強制する方法があれば、CRT のスラッシュを回避できますが、(ほとんどの) イメージを実行する前にイメージの整合性をチェックすることが目標である場合、CRT データを初期化する必要があると主張する人もいるかもしれません。その一部になります。このようにコードチェックサム自体をRAMに作成する方法はありますか?
FWIW、私はこれの要件にこだわっているようです。個人的には、ram に転送する前に flashでバイナリをチェックサムし、ローダーと ram を信頼する方法だと思っていました。パラノイアはどこかで終わらなければなりませんよね?
その他の詳細: ツール チェーンは GNU であり、イメージには が含まれており.text
、1 つの連続して読み込まれたチャンクとして含まれています。OS はなく、これはベア メタルが組み込まれています。プライマリ ローダーは基本的に、バイナリを RAM の所定のアドレスに格納します。再配置は発生しません。VM は使用されません。チェックサムは、初期化時に一度だけテストする必要があります。.rodata
.data
memcpy
更新 これを行うことでそれが見つかりました..
__attribute__((constructor)) void sumItUp(void) {
// sum it up
// leave result where it can be found
}
malloc
.. CRT init による/sbrk
変数の初期化と、"impure.o" および "locale.o" が所有するいくつかの変数を除いて、ほぼすべての前に合計を取得できます。ここで、malloc
/のsbrk
値は、プロジェクト リンカー スクリプトから知っているものです。impure.o と locale.o を軽減できれば、ビジネスになる可能性があります。
更新 エントリ ポイントを制御できるので (プライマリ ローダーのフラッシュに記載されている内容により)、カスタム アセンブラ コードを使用してスタックと sdata ポインタを設定し、チェックサム ルーチンを呼び出すのが最善の方法のようです。次に、「通常の」_start コードに分岐します。