リンカー スクリプト

アプリケーション実行ファイルのビルド プロセスは、コンパイルとリンクの 2 つの段階に分けることができます。リンクは、リンカー スクリプトと呼ばれるリンカー コマンド言語ファイルを使用してリンカーで実行します。リンカー スクリプトの主な目的は、ターゲット マシンのメモリ レイアウトを記述し、プログラムの各セクションを配置するメモリでの位置を指定することです。

Vitis ソフトウェア プラットフォームにはリンカー スクリプト ジェネレーターが含まれており、GCC 用のリンカー スクリプトを簡単に生成できます。リンカー スクリプト ジェネレーター GUI によりターゲット ハードウェア プラットフォームが調べられ、使用可能なメモリ セクションが判断されます。ユーザーの作業は、ELF ファイルの異なるコードおよびデータ セクションを異なるメモリ領域に割り当てることだけです。

注記:
  • マルチプロセッサ システムでは、各プロセッサが異なる ELF ファイルを実行するので、各 ELF ファイルにそれぞれリンカー スクリプトが必要です。2 つの ELF ファイルがメモリ内でオーバーラップしていないことを確認してください。
  • デフォルト リンカーでは、メモリで使用可能な DDR アドレスが指定されます。特定のハードウェア/ドメイン プロジェクトでアプリケーションを作成している場合は、そのアプリケーションのメモリはオーバーラップします。

アプリケーションのリンカー スクリプトの生成

アプリケーションのリンカー スクリプトを生成するには、次の手順を実行します。

  1. Project Navigator ビューでアプリケーション プロジェクトを選択します。
  2. Generate Linker Script を右クリックします。または、Xilinx > Generate Linker Script をクリックします。ダイアログ ボックスの左側は、Modify project build settings as follows フィールドの [Output Script] 名とプロジェクト ビルド設定は例外は読み出し専用です。この領域には、デザインに使用可能なメモリ エリアがすべて表示されます。メモリの割り当てには、[Basic] タブを使用する方法と [Advanced] タブを使用する方法があります。どちらも同じタスクを実行しますが、[Basic] タブの方が大まかで、すべてのデータ タイプを「データ」、すべての命令タイプを「コード」として処理します。ほとんどのタスクはこれで達成できます。Advanced タブは、ソフトウェア ブロックをさまざまなタイプのメモリに正確に割り当てる場合に使用します。
  3. OK をクリックします。

    エラーがあった場合は、その新しいリンカー スクリプトでアプリケーションをビルドする前に修正しておく必要があります。

    注記: リンカー スクリプトが既にある場合は、そのファイルを上書きするかどうかを尋ねるメッセージ ウィンドウが表示されます。OK をクリックするとファイルが上書きされ、Cancel をクリックすると上書きがキャンセルされます。

    Managed Make プロジェクトの場合、Modify project build settings で選択したオプションに基づいて、Vitis ソフトウェア プラットフォームでリンカー設定にリンカー スクリプトが自動的に追加されます。

[Basic] タブ

[Generate a linker script] ダイアログ ボックスの [Basic] タブの次のセクションを設定します。これらの主要なセクションを適切なメモリ領域に割り当てると、パフォーマンスを向上できます。コード、データ、およびヒープまたはスタック セクションの横にあるドロップダウン リストを使用して、ブロックを配置する領域とメモリのタイプを選択します。

Code Sections
実行コード (命令) を格納します。このタスクには、通常 DDR メモリが使用されます。割り込みハンドラーまたはよく使用される関数を個別のセクションにビルドし、BRAM または OCM などのレイテンシの短いメモリにマップできます。
Data Sections
初期化されたデータおよび初期化されていないデータを配置します。DDR メモリがよく使用されますが、データ サイズ要件が小さい場合は、パフォーマンスを向上するため OCM または BRAM を使用できます。
Heap and Stack
ヒープへのアクセスには、malloc() などのダイナミック メモリ割り当て呼び出しを使用します。これらのセクションは通常 DDR に配置したままにしますが、小さいことがわかっている場合は OCM または BRAM に配置できます。スタックがそれほど使用されない場合は、DDR に配置したままにしておいてもパフォーマンスの大幅な低下はありません。
Heap Size
ヒープ サイズを指定します。ダイナミック メモリ割り当てを明示的に使用しない場合でも、printf() などのヒープを使用する関数があります。それらの関数用に数 KB 割り当てておくことをお勧めします。
Stack Size
スタック サイズを指定します。スタックはメモリの下方に増加し、警告なしでヒープに侵食する可能性があります。再起関数や深い階層を使用する場合は特に、十分なメモリを割り当てるようにしてください。


[Advanced] タブ

メモリ セクションの定義およびメモリ セクションへの割り当てに関してより詳細な制御が必要な場合は、[Generate a linker script] ダイアログ ボックスの [Advanced] タブを使用します。

Code Section Assignments
ほかのセクションを作成していない場合、通常は .text コード セクションのみが含まれます。すべてのコード セクションは、この領域に表示されます。
Data Sections Assignments
コンパイラにより、読み出し専用データ (.rodata)、初期化されたデータ (.data)、および初期化されていないデータ (.bss) を含むさまざまなデータ セクション タイプが自動的に生成されます。
Heap and Stack Section Assignments
ヒープおよびスタックをメモリにマップし、そのサイズを定義します。
Heap Size
ヒープ サイズを指定します。ダイナミック メモリ割り当てを明示的に使用しない場合でも、printf() などのヒープを使用する関数があります。それらの関数用に数 KB 割り当てておくことをお勧めします。
Stack Size
スタック サイズを指定します。スタックはメモリの下方に増加し、警告なしでヒープに侵食する可能性があります。再起関数や深い階層を使用する場合は特に、十分なメモリを割り当てるようにしてください。


リンカー スクリプトの手動追加

Managed Make フロー用にリンカー スクリプトを手動で追加する手順は、次のとおりです。

  1. Managed Make プロジェクトを右クリックし、C/C++ Build Settings をクリックします。
  2. たとえば、ARM v8 gcc linker.のように、ターゲット プロセッサに該当するリンカーをクリックします。
  3. Linker Script をクリックして、リンカー スクリプトを追加します。
  4. Standard Make プロジェクトの場合は、リンカー スクリプトを手動でユーザーの makefile リンカー オプションに追加します。

リンカー スクリプトの変更

リンカー スクリプトを生成する場合、アップデートする方法が複数あります。
  1. テキスト エディターを使用してリンカー スクリプトを開いて、リンカー スクリプトを直接編集します。リンカー スクリプトを右クリックして Open With > Text Editor をクリックします。
  2. リンカー スクリプト ジェネレーターを使用してさまざまな設定のリンカー スクリプトを再生成します。
  3. リンカー スクリプト エディターを使用して変更をします。これには、リンカー スクリプトをダブルクリックします。カスタムのリンカー スクリプト エディターに、そのリンカー スクリプトの関連するセクションが表示されます。

リンカー スクリプト エディターには、次のような機能があります。

表 1. リンカー スクリプト エディターの機能

名前

機能

Available Memory Regions このセクションには、リンカー スクリプトで指定するメモリ領域がリストされます。領域は、右側の [Add] ボタンをクリックすると追加できます。定義済みの各メモリ領域の名前、ベース アドレス、サイズを変更できます。
Stack and Heap Sizes このセクションには、スタックおよびヒープ セクションのサイズが表示されます。単にテキスト ボックスの値を変更すると、これらのセクションのサイズをアップデートできます。
Section to Memory Region Mapping このセクションでは、リンカー スクリプトで定義されるセクションに割り当てられるメモリ領域を変更できます。割り当てられたメモリ領域を変更するには、そのメモリ領域を単にクリックして、ドロップダウン リストから変更するメモリ領域を選択します。