質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1298閲覧

リンカスクリプトを用いたリンクに失敗する。undefined reference

kirimomi

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

1グッド

1クリップ

投稿2019/02/28 00:01

編集2019/02/28 18:11

前提・実現したいこと

リンカスクリプトを用いたリンクに失敗します。

表示されるエラー kernel.o: In function `_kernel_entry': KERNEL.c:(.text+0x5): undefined reference to `_BSS_START' KERNEL.c:(.text+0xa): undefined reference to `_BSS_END' KERNEL.c:(.text+0x13): undefined reference to `initBSS'

c

1KERNEL.c 2 3#include "include/section.h" 4#include "include/memory.h" 5 6int _kernel_entry( void ){ 7 initBSS( _BSS_START, _BSS_END - _BSS_START ); 8 for( ;; ) 9 { 10 } 11}
section.h extern unsigned int _TEXT_START; extern unsigned int _TEXT_END; extern unsigned int _BSS_START; extern unsigned int _BSS_END;

c

1section.c 2 3unsigned int _TEXT_START = ( unsigned int )&_text_start; 4unsigned int _TEXT_END = ( unsigned int )&_text_end; 5unsigned int _BSS_START = ( unsigned int )&_bss_start; 6unsigned int _BSS_END = ( unsigned int )&_bss_end;
memory.h void initBSS( unsigned int kernel_bss_start, int size );```

c

1memory.c 2 3#include "kstdlib.h" 4void initBSS( unsigned int kernel_bss_start, int size ){ 5 kmemset( ( void * )kernel_bss_start, 0x00, size ); 6}
kstdlib.h void kmemset(void *str,unsigned char c,int size);

c

1kstdlib.c 2 3void kmemset(void *str,unsigned char c,int size){ 4 unsigned char *ptr = (unsigned char*)str; 5 const unsigned char ch = (const unsigned char)c; 6 while(size--){ 7 *ptr++=ch; 8 } 9}
リンカスクリプト(linker.link) SECTIONS { . = 0x100000; .text : { _text_start = .; *(.text) _text_end = .; } .rodata : { _rodata_start = .; *(.rodata) _rodata_end = .; } .data : { _data_start = .; *(.data) _data_end = .; } .bss : { _bss_start = .; *(.bss) _bss_end = .; } }

試したこと

フォルダの構成は、現在のフォルダにKERNEL.cとリンカスクリプトとincludeフォルダがあり、includeフォルダの中にmemory.c,memory.h,section.c,section.h,kstdlib.c,kstdlib.hがある状態です。
現在のフォルダにいる状態で、
i386-elf-gcc -c -o kernel.o KERNEL.c -O2 -I /include -Wall
とコンパイルしました。その後、
i386-elf-ld -T linker.link -Map kernel.map -nostdlib -e _kernel_entry
--oformat binary -o KIMAGE kernel.o
とリンクしたところ最初に書いたエラーが出てしまいリンクできません。
memory.cをオブジェクトファイルにしなければならないのかなと思いましたが、
リンカスクリプトのシンボルを参照しているためそれも出来そうになく困っています。

補足情報(FW/ツールのバージョンなど)

macOS high sierra
gcc version 6.5.0 (GCC)
GNU ld (GNU Binutils) 2.28

追記

section.cをコンパイルしてオブジェクトファイルに出来ず、
error: '_text_start' undeclared here
というエラーを吐いてしまいます。
この_text_startですが、これはリンカスクリプト内で定義しているはずなのですが・・・。

kazuyakazuya👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/02/28 05:03

間違ってたらこめんなさい、なのですが・・・ “i386-elf-gcc -c -o kernel.o KERNEL.c -O2 -I /include -Wall”←これってコンパイルできてますか? “ -I /include” ルートディレクトリ見に行ってるような??;
kirimomi

2019/02/28 17:52

質問ありがとうございます。 i386-elf-gcc -c -o kernel.o KERNEL.c -O2 -I ./include -Wall このように直すとコンパイル通りました。ただ、このように修正する前のi386-elf-gcc -c -o kernel.o KERNEL.c -O2 -I /include -Wall でもコンパイル出来ました。ルートディレクトリにincludeというフォルダは無いにも関わらずです・・・ 謎です・・・。
pepperleaf

2019/03/01 14:41

#include "xxx" の場合、カレントディレクトリに xxx を探しに行くのが仕様では? <xxx> だと違ったと思うが。 -I オプションは、includeの探し先の追加では? (昔、使ったコンパイラ)と思った。(怪しい記憶ですが)
kirimomi

2019/03/02 00:11

-l オプションはその通りでした。 includeフォルダも見にいってくれていました。 ありがとうございます。
guest

回答1

0

ベストアンサー

i386-elf-gcc -c -o kernel.o KERNEL.c -O2 -I /include -Wall

i386-elf-ld -T linker.link -Map kernel.map -nostdlib -e _kernel_entry
--oformat binary -o KIMAGE kernel.o

これでは、KERNEL.c ファイルしかコンパイルしてませんし、kernel.o しかリンクしてませんね。

これでは、KERNEL.c 以外で定義されたものは見つかりません

投稿2019/02/28 00:09

編集2019/02/28 00:14
y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kirimomi

2019/02/28 17:57

お忙しい中、回答頂きありがとうございます。 section.cやmemory.cもオブジェクトファイルにしてから、それらのオブジェクトファイル全てをldコマンドに渡してリンクすれば良いという解釈で合っていますでしょうか?
episteme

2019/02/28 20:38

やってみたら数十秒でわかるぞ
y_waiwai

2019/02/28 22:14

リンクの前にすべてのソースファイルをコンパイルする必要があります コンパイルできない、というのはエラーがあるからできないので、そのエラーを修正しましょう
y_waiwai

2019/02/28 22:21 編集

ちなみに、 >error: '_text_start' undeclared here のエラーは、 sention.c の先頭で extern unsigned int _test_start; の定義を追加してみましょう(これだけじゃダメですぜ)
kirimomi

2019/03/02 00:09

いくつか定義を追加し無事コンパイルとリンクが出来ました。 今回は助言を頂きありがとうございました。 いつか私も誰かの質問に回答できるように精進していこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問