2017-04-14 6 views
3

私はC言語で2〜3年勉強していますが、最近アセンブリを取り上げましたが、私はWindowsを使っているので、以前はVisual Studioを使っていたので、 Cygwinとi686のクロスコンパイラを使ってCとアセンブリファイルをコンパイルし、それらをリンクして私のオペレーティングシステムを表すバイナリファイルにしています。私はファイルを作るために新しいので、私はこれを正しく行う方法を知らない。x86とcをメイクファイルでコンパイル

CC = i686-elf-gcc 
CC_FLAGS = -c -std=gnu99 -ffreestanding -O2 -Wall -Wextra -I./include 
AS = i686-elf-as 
LD = i686-elf-gcc -T linker.ld -o myos.bin 
LD_FLAGS = -ffreestanding -O2 -nostdlib -lgcc 
O_FILES = $(wildcard src/*.o) 

all: $(O_FILES) 
    $(LD) $(LD_FLAGS) $(O_FILES) 

src/%.o: src/%.c 
    $(CC) $(CC_FLAGS) -o [email protected] $< 

src/%.o: src/%.asm 
    $(AS) -o [email protected] $< 

私は、リンカはそう明らかに何もコンパイルされていないエントリのシンボル_startを見つけることができないというエラーを取得しています:これは私がこれまでにMakefileのための持っているものです。どうすればこの問題を解決できますか?エントリポイントとして_startを定義

マイsrc/linker.ldファイルは次のとおりです。

ENTRY(_start) 

SECTIONS 
{ 
     . = 1M; 

     .text BLOCK(4K) : ALIGN(4K) 
     { 
       *(.multiboot) 
       *(.text) 
     } 

     .rodata BLOCK(4K) : ALIGN(4K) 
     { 
       *(.rodata) 
     } 

     .data BLOCK(4K) : ALIGN(4K) 
     { 
       *(.data) 
     } 

     .bss BLOCK(4K) : ALIGN(4K) 
     { 
       *(COMMON) 
       *(.bss) 
     } 
} 

私はそれを使用していsrc/boot.asmファイルには、私の_startラベルは定義されています。

# Declare constants for the multiboot header. 
.set ALIGN, 1<<0    # align loaded modules on page boundaries 
.set MEMINFO, 1<<1    # provide memory map 
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field 
.set MAGIC, 0x1BADB002  # 'magic number' lets bootloader find the header 
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot 

.section .multiboot 
.align 4 
.long MAGIC 
.long FLAGS 
.long CHECKSUM 

.section .bss 
.align 16 
stack_bottom: 
.skip 16384 # 16 KiB 
stack_top: 

.section .text 
.global _start 
.type _start, @function 
_start: 
     mov $stack_top, %esp 

     call kernel_main 

     cli 
1:  hlt 
     jmp 1b 

.size _start, . - _start 
+0

エラーは、リンカーエラーです。 'linker.ld'を表示せず、' _start'のエントリポイントを使っているように聞こえますが、あなたのコードには '_start'というラベルはありません。 –

+0

_startはboot.asmで定義されており、ここではlinker.ldです。https://pastebin.com/MuJxLQW8 –

+0

あなたの 'boot.asm'を表示できますか?問題はこれが最小限の完全に検証可能な例ではないということです。あなたがプロジェクト全体を利用可能にしたならば、それはさらに良いでしょう。 –

答えて

1

あなたのを修正する必要がありますMakefileを次のように変更します。

CC = i686-elf-gcc 
AS = i686-elf-as 
LD = i686-elf-gcc 
AS_FLAGS = 
LD_FLAGS = -ffreestanding -nostdlib -lgcc -Tlinker.ld 
CC_FLAGS = -c -std=gnu99 -ffreestanding -O2 -Wall -Wextra -I./include 

C_FILES := $(wildcard src/*.c) 
ASM_FILES := $(wildcard src/*.asm) 
O_FILES := $(C_FILES:.c=.o) $(ASM_FILES:.asm=.o) 
KERNEL_BIN := myos.bin 

all: $(KERNEL_BIN) 

clean: 
     rm -f $(KERNEL_BIN) $(O_FILES) 

$(KERNEL_BIN): $(O_FILES) 
     $(LD) $(LD_FLAGS) -o [email protected] $^ 

%.o: %.c 
     $(CC) $(CC_FLAGS) -o [email protected] $< 

%.o: %.asm 
     $(AS) $(AS_FLAGS) -o [email protected] $< 

このMakefileは、ASMファイルとCファイルのリストを作成する点で異なります。 LD_FLAGSを少しきれいにして、myos.binを作成し、オブジェクトとbinファイルをcleanに追加するルールを追加しました。あなたの現在のコードで

あなたは拡張後にそれらの中に、これとMakefileの変数を持っていると思います:

C_FILES = src/string.c src/tty.c src/kernel.c 
ASM_FILES = src/boot.asm 
O_FILES = src/string.o src/tty.o src/kernel.o src/boot.o 

O_FILESは一緒に両方のファイルのリストを連結し、.o.c.asmの拡張機能を置き換えるに由来するものでした。これは、ソースファイルから生成する必要があるすべてのオブジェクトのリストです。むしろ.asm


_startラベルがありませんでした理由よりも、(あなたがCプリプロセッサを使用する場合や.S

GNUアセンブラで、.s拡張子を持つファイルを使用するのが通例でありますアセンブリファイルが処理されていないためです。これはboot.asmboot.oになっていないことを意味し、したがってリンクされていませんでした。

関連する問題