2016-03-21 10 views
2

私のARM MCUで、初期化されたデータ用に追加のRAMセクション(GNUリンカスクリプト内)を作成しようとしています。このセクションは、既知のアドレスに配置する必要があります。そのため、MPUの特定の属性を設定できます。 私はすべてのリンカの魔法にいくつか問題があります。次のようにGNUリンカスクリプトで余分なリロケータブルセクションを作成する

メモリが分割されています。

/* Memory Spaces Definitions */ 
MEMORY 
{ 
    rom (rx) :   ORIGIN = 0x00420200, LENGTH = 0x001DFE00 
    ram (rwx) :   ORIGIN = 0x20400000, LENGTH = 0x0005e000 
    ram_nocache_section (rwx) : ORIGIN = 0x2045e000, LENGTH = 0x00002000 
    sdram(rwx):   ORIGIN = 0x70000000, LENGTH = 0x00200000 
} 

それは私が対処しようとしている「ram_nocache_section」です。

次のように私は適切なセクションを定義することができる:

/* no cache section */ 
.ram_nocache : 
{ 
    . = ALIGN(8); 
    *(.ram_nocache) 
} > ram_nocache_section 

これは動作しますが、結果として得られるバイナリは巨大です。 0.5GB。これは、RAMアドレス空間がフラッシュアドレス空間から0.5GB離れているためです。これに対処する方法は、初期化されたラムデータを「再配置」することです。スクリプトはそうのようにこれを行う:

.text : 
{ 
    ... 
} > rom 

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

これは魔法の初期化データを割り当てる(および機能をRAM)、フラッシュ及びRAMに両方う。だから、コピーするのは簡単だろうね。同様に:

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

. = ALIGN(4); 
_eramdata = .; 

.relocate2 : AT (_eramdata) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

これはコンパイルされますが、結果のバイナリはまだ巨大です。これは、_eramdataシンボルが何らかの形でRAMに配置され、_etextのようにフラッシュに配置されないためです。

さて...このdocumentによると、私が代わりにこのような何かを行うことができるはず:

.relocate2 : AT (_etext + SIZEOF(.data) + SIZEOF(.ramfunc)) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

これは文句を言わないけれどもコンパイル。代わりに、次のように目的の結果を作成することができます。

.relocate2 : AT (_etext + 10k) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

しかし、これはかなり壊れやすい無駄な解決策です。

これを正しく行うにはどうすればよいですか?私は 'relocate2'セクションを通常の '再配置'セクションのすぐ隣に配置したいと思います。余分な無駄や事前定義されたコード制限なし。

+0

'NOINIT'属性について読んでください。 – Olaf

+0

私はNOINITがNOLOADに似ていると推測しています。変数の初期化を防止します。これで問題は解決します(私が調べました)が、プログラムを壊してしまいます。 (私は初期化されたデータを使用しています。) – Illishar

+0

あなたが望むものをクリアしていません。なぜ、標準の '.data'セクションを使用しないのですか?また、ロード・メモリーが指定されていません。 – Olaf

答えて

0

私は解決策を自分で発見した可能性があります

.relocate2 : AT (_etext + SIZEOF(.relocate)) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

私はすでにそのような何かをしようとしただろうと確信していました。しかし、これは私が望んでいたようだ。しかし、まだ最もエレガントな解決策ではありません。

+1

['AT> rom'](https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html)を使って、これらの初期化されたセクションのLMAを配置することができます。 init destinationへのLMAソースの 'memcpy()'を行うには、単純なアセンブラといくつかのLMAラベルが必要です(いずれにせよ)。リンカはあなたのためにこの追加を行います( '_etext'と同じです)。これを行う別の方法は、すべてを '_etext'に置くことですが、MMU/MPUのためのパディングを提供します。これによりバイナリに余分なパディングサイズが設定されます。 –

+0

私はAT> romを試しましたが、リンカーはセクションが重なっていると不平を言っていました。どうやら、 "AT> rom"と "section:AT(...)"の構成はお互いに矛盾しているようです。私はちょうど両方をAT> romに変更しようとしました。それはうまくいくようです。 (私は以下のコードを投稿します) – Illishar

+0

すべてを.textに入れるのは悪い考えではありません。 (これは一種の 'this is flash'セクションを作成します。) – Illishar

1

私は、これは、より良い構築好き:

. = ALIGN(4); 
_etext = .; 

.relocate : 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram AT>rom 

.relocate2 : 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section AT>rom 

はどちらのセクションでは、AT> ROMに変更する必要があります。 (混合しないでください)

関連する問題