2013-09-05 19 views
10

これまでどのように検索し、答えが出てこなかったのですか?リンカスクリプト - セクションをメモリ領域の最後に配置

Fake Address | Section 
    0  | text 
    7  | relocate 
    15  | bss 
    23  | stack 

を私はヒープを置くスタックの最後に次のように

私のメモリレイアウトです。私は使用しているARMチップの完全な降順スタックです。

ここでは、1つのセクションを配置して、それを.persistと呼びましょう。私はそれがRAMの最後に存在するようにしたいので、これを私のリンカースクリプトにプログラムしたいと思います。しかし、この.persistセクションのサイズは私によって定義されていませんが、コンパイラがそれに含まれるシンボルから計算されます。

これまでのところ、私はそれを行う良い方法を考え出していません。私はRAMの開始アドレスとSIZEを知っているので、セクションのサイズを知っていれば、セクションがどこに行く必要があるかを計算するのは簡単です。しかし、the GNU linker documentation (pg 74)によると、それはようです:そのセクションが割り当てられている場合

SIZEOF(セクション)は、名前の セクションのサイズをバイト単位で返します。 これが評価されたときにセクションが割り当てられていない場合、リンカーは にエラーを報告します。

私はリンカスクリプトのセクションのサイズを計算することができません。なぜなら、配置する前にサイズを計算したいからです。

これを行うには良い方法がありますか?

+0

それをやった同様の問題 がありました。これはあなたを助けますか? http://stackoverflow.com/a/19348569/911550 – parvus

+0

これは部分的な解決策ですが、私は何をしていません。それはまだ他の誰かが助けに来た最も近いです。ありがとう! – nonsensickle

答えて

0

私がしたいことは、単一のセクションを配置し、それを.persistと呼びましょう。私はそれがRAMの最後に存在するようにしたいので、これを私のリンカースクリプトにプログラムしたいと思います。

リンカスクリプトは、現在のアドレスを変更することができLocation Counterと呼ばれる特別な変数であり、そのようなサイズまたはセクションまたはシンボルのアドレスとして、アドレス空間内のギャップまたはホールを作成することによって。

+0

はい、私はこれを知っています。 'SIZEOF'演算子について、**あなたが*置くまでセクションのサイズを与えない**について、私が言ったことを忘れてしまった。 **私はこれを動作させる前に、セクションのサイズを取得する必要があります。 – nonsensickle

+0

唯一の回避策は、セクションを配置してサイズを取得し、配置して別の場所に移動できる場合です。 – nonsensickle

0

セクションを特定の場所に強制することができます。

このRed HatのGNUリンカのドキュメントpageでたとえば、アドレス0x8000000に開始する.dataセクションを定義することができます。

SECTIONS 
{ 
    . = 0x10000; 
    .text : { *(.text) } 
    . = 0x8000000; 
    .data : { *(.data) } 
    .bss : { *(.bss) } 
} 
+0

はい、これはわかっています。しかし、これは私が特定のアドレス*で終わるように私のセクションを保存することはできません。私は自分のセクションのサイズを取得し、それをアドレスから減算して結果のアドレスを与え、結果のアドレスに配置したいと思います。こうすることで、RAMメモリブロックの末尾に可変サイズのセクションを置くことができます**。私はこれが不可能であることを発見しました、そして、それは質問についてです。 – nonsensickle

5

私は、2段階のプロセスをリンクすることによって、類似した何かを達成することができました。 まず、問題のセクションを独自のオブジェクトファイルにコンパイルします。私の場合、アセンブリファイルから生成されたメタデータセクションがありました。 gcc -cはソースをオブジェクトファイルにコンパイルしますが、リンクはしません。

gcc -c metadata.s -o metadata.o 

また、プログラム全体を構築して、問題のセクションだけをobjcopyで抽出することもできます。

gcc -c main.cc -o main.o 
objcopy --only-section=.metadata main.o metadata.o 

ここでは、残りのプログラムをビルドしてリンクし、リンカーの入力にオブジェクトファイルを含めます。

gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld 

リンカは、オブジェクト・ファイルからセクション.metadataを読み取り、Iは​​リンカスクリプトにそのサイズを参照することができます。

+0

私はこのプロジェクトを最後に作業して以来、長い時を経てきましたが、あなたの答えはそれを可能にするのに最も近いようです。私は正しいとマークする前にそれを確認する必要がありますが、今は+1しています。 – nonsensickle

0

私は同じ問題を抱えて、私はこのよう

/* heap section */ 
.heap (NOLOAD): 
{ 
    . = ALIGN(8); 
    _sheap = .; 
    . = . + HEAP_SIZE; 
    . = ALIGN(8); 
    _eheap = .; 
} > ram 

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ; 
_stack_size = _ram_end_ - _eheap ; 

/* stack section */ 
.stack (NOLOAD): 
{ 
    . = ALIGN(8); 
    _sstack = .; 
    . = . + _stack_size; 
    . = ALIGN(8); 
    _estack = .; 
} > ram 

.LastSection (NOLOAD): /* for test in dump file */ 
{ 
    . = ALIGN(8); 
} > ram 
+0

私はこれを考慮しましたが、問題は、セクションの最後のバイトが '_ram_end'アドレスを占めるように、ラムの最後にセクションの配置を求めていることです。私が見ることができるのは、ラムの最後にスタックを置くことであり、スタックは単に残りのすべてのバイトを占有しています。私は、スタックとは違って、他のセクションのサイズに依存しない静的なサイズを持つセクションでこれを行うことを求めています。効果的に、この例では、スタックはRAM内の残りのすべてのメモリを占有します。 – nonsensickle

関連する問題