問題タブ [linker-scripts]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - コマンドライン引数を GNU LD に渡してセクションを作成し、サイズを定義して特定のメモリに配置することは可能ですか?
RAM にセクションを作成し、特定のサイズを割り当ててアドレスに配置したいですか? リンカー スクリプトの「ファイル」を渡さずに、または既存のリンカー スクリプトを変更せずに、これらすべての操作を実行することは可能ですか?
GNU LD/GCC を使用して、リンカー スクリプトによって実行されるすべての操作をコマンド ラインで実行することは可能ですか?
c - gcc: 関数ポインタを別のセクション (.data ではない) に配置できますか?
ホスト上で組み込みプロジェクトの単体テストを行うために、関数ポインターを使用して、実行時に関数の「実際の」実装とモックを変更できるようにしました。したがって、私の関数 'foo' は .c ファイルでは次のようになります。
関数ポインターが、コードではなくデータのみを運ぶことが許可されている内部 L1 データ メモリに存在するため、ターゲット プロセッサ (Blackfin) が例外を生成することが判明しました。
機能する解決策は、各関数ポインターに属性を割り当てて、L1 データ メモリに存在しない別のセクションに配置することです。次に例を示します。
ただし、これによりコードが少し読みにくくなり、エラーが発生しやすくなります (属性の割り当てを忘れた場合、単体テストは正常に実行されますが、関数がターゲットで呼び出されるとすぐにコードによって例外が生成されます)。
だから私の質問は、デフォルトですべての関数ポインタを別のセクションに置くようにgccに指示する方法があるかどうかです。
linker - CCSv5 でプロジェクト全体のアライメントを設定するにはどうすればよいですか?
TI Code Composer Studio 5.5 (TI ARM コンパイラ 5.1.1) でプロジェクト全体のリンカー アライメントを設定する必要があります。
これは私のリンカー .cmd ファイルです:
は.align 8
仕事をしませんでした。結果のマップ ファイルでは、アドレスが 4 または C で終わるシンボルが多数表示されます。すべてのシンボルが 8 の倍数に配置されている場合、アドレスは 0 または 8 で終わるはずです。
リンカーのアライメントを 64 ビットに設定する正しいコマンドはどれですか?
gcc - 特定のシンボルが参照されている場合、リンクが失敗する原因となる
コードがライブラリから特定のシンボルを参照している場合、リンクを失敗させる方法はありますか?
リンカスクリプト言語にそのようなディレクティブがあったことはうろ覚えのようですが、どうやらGNU LDではなかったようです(記憶違いかもしれません)。
サードパーティ ライブラリの一部が誤ってアプリケーションにリンクされるのを防ぐために必要です。リンクする場合、実行時に大混乱を引き起こす静的初期化子がいくつか追加されます (これは組み込みプロジェクトであるため、環境は少し風変わりです)。問題のサードパーティ ライブラリを変更できません。ビルド時にエラーを検出したいと思います。マップ ファイルを解析し、問題のある部分が見つかった場合にエラーを発行するビルド後のスクリプトを作成できると思いますが、上記の [false?] メモリにより、リンカーだけでは実行できないことを確認するよう求められます。
GNU GCC ツールチェーンを使用しています。
attributes - 一部のメモリ割り当てに __attribute__ (セクション) を使用するのはなぜですか?
私は持っているfoo[NUMBYTES] __attribute__((section(".bar")));
この属性 .bar セクションを使用する理由 foo[] はすでにいくらかのメモリ空間を提供しているためです。これは簡単なメモリ管理のためですか?
c - memcpy を別のコード セクションに移動する
ARM Cortex-M0+ マイクロコントローラーで実行するためのソフトウェアを構築しています。関数の呼び出し時にセカンダリ プログラムとして実行される種類の USB ブートローダーが含まれています。memcpy
コンパイル中の関数の挿入に問題があります。
バックグラウンド
リンカー スクリプトがすべての始まりです。そのほとんどは非常に簡単で標準的なものです。プログラムはそこに保存され.text
、そこからも実行されます。すべてが.text
チップのフラッシュセクションに保存されます。
奇妙なのは、ブートローダーが実行される部分です。ブートローダ コードを上書きせずにすべてのフラッシュを書き込めるようにするために、私のブートローダ エントリ ポイントは、マイクロコントローラの SRAM 部分へのブートローダ プログラムのコピーを開始し、そこから実行します。このようにして、ブートローダーは誤って自身を削除することなく、デバイス上のすべてのフラッシュを安全に消去できます。
これは、リンカー スクリプトで偽の「オーバーレイ」を実行することによって実装されます (実際OVERLAY
の使用例は、私の使用例とはまったく一致しませんでした)。
_end_flash
すべてのデータをフラッシュに保存した前のセクションの最後への参照です ( .text
、.rodata
、.init
...基本的に読み取り専用のものはすべてそこにスタックします)。
これにより、セクション.data
と.bss
セクションは通常 RAM に存在します。ただし、.bootloader
セクションは RAM の同じ場所にも存在します。両方のセクションは、コンパイル時に順番にフラッシュに保存されます。私のcrt0
ルーチンでは、.data
セクションはフラッシュから RAM 内の適切なアドレス ( で指定_start_data
) にコピーされ、.bss
セクションはゼロになります。.text
フラッシュから RAM にデータをコピーしてブートローダーを開始するセクションに追加のセクションを保存し、.data
とにあったものを上書きします.bss
。ブートローダからの唯一の終了はシステム リセットであるため、実行中のプログラムのデータが破壊されても問題ありません。ブートローダを RAM にコピーした後、それを実行します。
質問
明らかに、オーバーレイされたプログラムをコンパイルし、すべての参照が揃っていることを確認する際に、いくつかの問題が発生する可能性があります。.data
通常のプログラムからブートローダー コードにアクセスしたり、通常のプログラムやブートローダーからアクセスしたりする際に発生する問題を軽減するため.bss
に、リンカー スクリプトに次の 3 行を追加しました。
.text
ここで、(ブートローダーによって消去される可能性がある)、.data
(ブートローダーが上にある)、または.bss
(ブートローダーがその上にある) セクションとセクションの間にクロスがあるときはいつでも.bootloader
、コンパイラ エラーが発生します。発行済み。
実際にコードを書き始めるまで、これはうまくいきました。私のコードの一部には、いくつかの構造体のコピーなどが含まれています。どうやら、コンパイラはこれを行うことを決定しました(bootloader_
関数は.bootloader
セクションに存在します):
私のチップのアーキテクチャでは、アドレス0x20000000
まで0xE000000
は SRAM に配置されています (実際にはデバイス上に 4Kb しかありません)。以下のアドレスはすべて0x1fffffc00
フラッシュ セクションにあります。
.bootloader
問題はこれです: 私のセクション ( bootloader_usb_endp0_handler
) にある私の関数では、memcpy
( 2000039c
、20000562
、および2000056c
) への参照が挿入されました。これは、特に構造体のコピーを行っているためです。それが置かれた参照は、フラッシュに存在するmemcpy
アドレスにあります...消去される可能性があります。0x00000869
特定のコードは次のとおりです。
どこsetup_t
でbdt->addr
_ void*
_ setup_t
_ この行は への呼び出しを生成しますmemcpy
。
私の質問は、構造体のコピーを維持したいということです。それは便利です。memcpy をデフォルト以外の特定のセクションに配置するようにコンパイラに指定する方法はありますか? ブートローダーモジュールだけでそれが起こるようにしたい. 他のすべてのコードはそれを持つことができますmemcpy
...内部にあるブートローダーモジュールの特別なコピーが欲しいだけです.bootloader
。
これが単純に不可能な場合は、ブートローダ全体をアセンブリに書き込むか (面白くない)、ブートローダを個別にコンパイルして、かなり長い 16 進数の文字列としてエンド プログラムに含めて実行します。 RAMにコピーした後の文字列。文字列ルートは壊れやすく、実装が難しいため、私にはあまり魅力的ではありません...他の提案もいただければ幸いです。
このモジュールのコンパイル行は次のとおりです。
通常、最適化は になりますが-Os
、私はそれを取り除こうとしていましたmemcpy
... うまくいきませんでした。
また、私はこの質問を見てきましたが、問題は解決しませんでした。