2009年6月15日月曜日

setup.ld

今日からLinuxカーネルを読み始めてみます。
バージョン2.6.xが対象です。

まず最初に読んでみる対象は
「arch/x86/boot/setup.ld」
というリンカスクリプトです。

リンク時に参照されるものであって、カーネルではありません。
でもこのファイルでエントリポイント(最初に実行する箇所)を指定しているので
最初に読んでみるファイルとしては相応しいと考えました。
/*~*/がワタクシのコメントです。

===
/* 出力形式の指定 i386を指定している */
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)

/* エントリポイント。最初に実行するのは「_start」が指すアドレス */
ENTRY(_start)

/* 以下、セクションの定義 */
SECTIONS
{
/* アドレス0からbstext,bsdataセクション */
. = 0;
.bstext : { *(.bstext) }
.bsdata : { *(.bsdata) }

/* アドレス497からはheader, inittext, initdata, textセクション */
. = 497;
.header : { *(.header) }
.inittext : { *(.inittext) }
.initdata : { *(.initdata) }
.text : { *(.text*) }

/* 16byteアラインして、rodate, videocards,セクション */
. = ALIGN(16);
.rodata : { *(.rodata*) }

.videocards : {
video_cards = .;
*(.videocards)
video_cards_end = .;
}

/* 16byteアラインして、data, signatureセクション */
. = ALIGN(16);
.data : { *(.data*) }

.signature : {
setup_sig = .;
LONG(0x5a5aaa55)
}

/* 16byteアラインして、bssセクション */
. = ALIGN(16);
.bss :
{
__bss_start = .;
*(.bss)
__bss_end = .;
}
. = ALIGN(16);
_end = .;

/DISCARD/ : { *(.note*) }

. = ASSERT(_end <= 0x8000, "Setup too big!"); . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!"); }

===
エントリポイントには「_start」を指定しているので、プログラム実行時に
最初に実行するのが「_start」が指すアドレスになります。
「_start」については次回見てみましょう。

アセンブラソースを見ていると
.section ".bsdata", "a"
こんな記述を見かけますが、これらの定義が上記リンカスクリプトにあります。
上述の例だと、bsdataセクションを指定しているので、アドレス0からの位置に
配置されるのだと分かります。
===
リンカスクリプトについては下記サイトを参考にしています。
初めてのC言語-第9回 リンカスクリプト
GNU リンカ LD の使い方


0 件のコメント:

コメントを投稿