カスタム リンカー スクリプトを使用する組み込みプログラムに取り組んでいます。プログラムは動作しますが、リンカがいくつかのセクションをメモリに配置する方法に問題がある可能性があることに気付きました。
リンカー スクリプトの関連部分は次のとおりです。
MEMORY {
ROM (rx) : ORIGIN = 0x00100000, LENGTH = 16k
RAM (rwx) : ORIGIN = 0x00200000, LENGTH = 4k
}
SECTIONS {
/* Other sections go here. */
.data : {
...
} >RAM AT>ROM
.bss : {
...
} >RAM
.stack : {
...
} >RAM
...
}
MAP ファイルの関連部分は次のとおりです。
.data 0x00200040 0x0 load address 0x001003d4
0x001003d4 __data_load = LOADADDR (.data)
0x00200040 __data_start = .
*(.data)
*(.data*)
0x00200040 . = ALIGN (0x4)
0x00200040 _edata = .
.igot.plt 0x00200040 0x0 load address 0x001003d4
.igot.plt 0x00000000 0x0 ./debug/sam7s_startup.o
.bss 0x00200040 0x0 load address 0x001003d4
0x00200040 __bss_start__ = .
*(.bss)
*(.bss*)
*(COMMON)
0x00200040 . = ALIGN (0x4)
0x00200040 _ebss = .
0x00200040 __bss_end__ = .
0x00200040 PROVIDE (end, _ebss)
0x00200040 PROVIDE (_end, _ebss)
0x00200040 PROVIDE (__end__, _ebss)
.stack 0x00200040 0x200 load address 0x001003d4
0x00200040 __stack_start__ = .
したがって、マップ ファイルから、.bss セクションと .stack セクションが ROM でロード アドレスを取得しているように見えます。これは、次の2行のせいだと思います。
.bss 0x00200040 0x0 load address 0x001003d4
.stack 0x00200040 0x200 load address 0x001003d4
ROMのスペースを占有する意味がないため、これは良くありません。.bss セクションは、現在は空ですが、コードでゼロに設定される初期化されていないグローバル変数が含まれます。スタックは、コードで初期化される RAM の一部でもあります。したがって、これらのセクションのいずれかが ROM のスペースを占有する必要はありません。
私の質問は、.bss と .stack が ROM に読み込まれないようにする正しい方法は何ですか? .bss および .stack セクションの末尾を から に変更する必要があり>RAM
ます>RAM AT>RAM
か? これは少し冗長に思えます。
いくつかのことをテストした後、次のことがわかりました。
(1)(NOLOAD)
属性を使用しても (たとえば、 に置き換え.stack :
て.stack (NOLOAD) :
)、.stack セクションと .bss セクションの ROM ロード アドレスを示すマップ ファイルが生成されます。
(2)RAM AT>RAM
上記のように を指定すると、.stack セクションと .bss セクションの ROM ロード アドレスがマップ出力に表示されなくなります。
(3) マップ ファイルに .bss および .stack セクションのロード アドレスが示されている場合、実際には ROM のスペースを占有していないように見えます。.stack セクションの長さは 0x200 バイトですが、実際には ROM 内のそのスペースを占有しているようには見えません。これにフィル値を指定し、リンカー スクリプト内でその後にセクションを配置したとしてもです。リンカー スクリプトでそれに続くセクションは、異なるスタック サイズで移動されません。
したがって、マップ ファイルの出力は、私が考えていることを意味していない可能性があります。.stack および .bss セクションには、実際には ROM 内のロード アドレスがまったく指定されていません。いくつかのことを試してみると、確かにこのように表示されます。特に(NOLOAD)
が使用されている場合に、セクションに ROM ロード アドレスが指定されているようにマップ出力が表示される理由を知ることは依然として興味深いでしょう。これは、LD がマップ出力ファイルを生成する方法の単なるバグでしょうか?