2017-04-14 3 views
3

Ich habe C für 2-3 Jahre geschrieben und vor kurzem Assembly abgeholt, aber da ich Windows benutze, musste ich noch nie make-Dateien verwenden, da ich Visual Studio gerade benutzt habe. Ich versuche Cygwin und einen i686 Cross-Compiler zu verwenden, um c- und Assemblydateien zu kompilieren und sie dann zu einer binären Datei zu verbinden, die mein Betriebssystem darstellt. Ich bin neu, um Dateien zu machen, also weiß ich nicht, wie ich das richtig machen soll. Dies ist, was ich bisher für die Makefile bekam:Kompilieren von x86 und c mit Makefile

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] $< 

Ich erhalte eine Fehlermeldung besagt, dass der Linker nicht den Eintrag Symbol finden _start so offensichtlich ist nichts zu kompilieren. Wie würde ich das beheben?

Meine src/linker.ld-Datei, die _start als Einstiegspunkt definiert ist:

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) 
     } 
} 

Die src/boot.asm Datei ich bin mit meiner definiert _start Label:

# 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

Der Fehler, den Sie erhalten, ist ein Linker-Fehler. Sie zeigen uns nicht Ihre 'linker.ld', aber es klingt, als würden Sie einen Einstiegspunkt von' _start' verwenden, aber Sie haben keine '_start'-Bezeichnung in Ihrem Code. –

+0

_start ist in boot.asm definiert und hier ist linker.ld https://pastebin.com/MuJxLQW8 –

+0

Können Sie uns Ihre 'boot.asm' zeigen. Das Problem ist, dass dies kein minimales vollständiges überprüfbares Beispiel ist. Wenn Sie Ihr gesamtes Projekt zur Verfügung stellen, wäre es sogar besser. –

Antwort

1

Sie ändern müssen, um Ihre Makefile zu etwas wie diesem:

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] $< 

Diese Makefile unterscheidet sich darin, dass wir eine Liste von ASM-Dateien und C Dateien erstellen. Ich habe auch die LD_FLAGS ein bisschen aufgeräumt und eine zusätzliche Regel hinzugefügt, um myos.bin und clean die Objekt- und Bin-Dateien zu erstellen.

In Ihrem aktuellen Code würden Sie die Makefile-Variablen mit dieser in ihnen nach der Expansion:

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 wurde aus verketten beide Dateilisten zusammen abgeleitet und das Ersetzen der .c und .asm Erweiterungen mit .o. Dies ist die Liste aller Objekte, die aus ihren Quelldateien generiert werden müssen.

Mit GNU Assembler ist es üblich, Dateien zu verwenden, mit .s Erweiterungen statt .asm


Der Grund für die _start Etikett nicht war (oder .S, wenn Sie die C Präprozessor verwenden möchten) Der Grund dafür ist, dass die Assembly-Dateien nicht verarbeitet wurden. Das bedeutet, dass boot.asm nicht boot.o wurde und daher überhaupt nicht verknüpft wurde.

Verwandte Themen