組込み開発再入門(3) – リンカスクリプト(2)

組込み開発再入門(2) のリンカスクリプトの続き。

スポンサーリンク

info を読む

Linux とか Unix を使っていて 「man嫁」と言われたことのある人は多いと思う。でも man だと限られた情報しかない。そこで info ですよ。リンカスクリプトに関して言えば 「info嫁」なのである。おもむろに
$info ld
とか打つと ld の info が表示されるので Scripts という章を読むと一通りリンカスクリプトについて知ることができる。

MEMORY ブロックを書いてみる

今まで SECTIONS しかないリンカスクリプトだったので MEMORY も書いてみる。MEMORY ブロックではメモリ空間の定義と空間の属性定義を行うことができる。つまり、

  • メモリ空間の開始アドレス
  • メモリ空間のサイズ
  • Read Only なのか書き込みもできるのか (ROMかRAMか)
  • Executable かどうか (プログラムを格納する空間なのか)
  • 初期化する必要があるか

といったことが定義できる。

書式はこんな感じ。

MEMORY {
    領域名1(属性):ORIGIN=開始アドレス,LENGTH=長さ
    領域名2(属性):ORIGIN=開始アドレス,LENGTH=長さ
}

ORIGIN と LENGTH は o や l と書くこともできる。

属性は省略もできる。詳しくは info を読むこと。

ATTR string 意味
R Read-only セクション (ROMとか)
W Read/write セクション (RAMとか)
X 実行可能セクション
A Allocatable セクション(実際にターゲット上に確保される)
I 初期化対象になるセクション。L でも可。
! 前述の属性を反転させる (←これがよくわからない)

で、定義したメモリ領域名はセクション定義で使うことができる。

SECTIONS {
    セクション名:{} > メモリ領域名
}

ということで、ここまで調べたことをまとめてリンカスクリプトをちょっと手直し。

OUTPUT_FORMAT("elf32-h8300")
OUTPUT_ARCH(h8300h)
ENTRY("_start")
 
MEMORY
{
    romall(rx)          : ORIGIN = 0x000000, LENGTH = 0x020000  /* 128kb */
    vectors(r)          : ORIGIN = 0x000000, LENGTH = 0x000100
    rom(rx)             : ORIGIN = 0x000100, LENGTH = 0x01ff00
 
    ramall(rwx)         : ORIGIN = 0x0fef10, LENGTH = 0x001000 /* 4kb */
    stack(rw)           : ORIGIN = 0x0FFF00, LENGTH = 0x000000 /* end of ram */
}
 
SECTIONS
{
    . = 0x0;
 
    .vectors : {
        LONG(ABSOLUTE(_start))
    } > vectors
 
    .text : {
        _text_start = . ;
        *(.text)
        _etext = . ;
    } > rom
}

なんとなく雰囲気は掴めた気がする。本当はもっといろいろ書かなければならないけどとりあえずこんな感じにしておく。ram とか stack とか定義だけしてみたけどきちんと使うのはもうちょっと後。

スポンサーリンク

フォローする