Issue with compiling "Hello World" OS setup

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Issue with compiling "Hello World" OS setup

Post by SimonHA »

Hi all!

It's my first time here at the forum and I have a beginner issue with compiling my simple OS for an Raspberry Pi Zero.
Here is my MakeFile:

Code: Select all

# Target definitions.
ARCH 			= arch/arm
TARGET_BOARD	= pi-zero
TARGET_CPU		= arm1176jzf-s

# Compiler setup.
COMPILER = /home/simonha/opt/cross/bin/arm-none-eabi
AS = $(COMPILER)-as
CC = $(COMPILER)-g++
LD = $(COMPILER)-ld
CP = $(COMPILER)-objcopy
OD = $(COMPILER)-objdump

ASFLAGS	= -mcpu=$(TARGET_CPU)
CFLAGS 	= -mcpu=$(TARGET_CPU) -ffreestanding -Wall -Wextra -fpic -std=c++11 \
	-nodefaultlibs -lgcc
LDFLAGS = 

# Directory setup.
BUILD = build/
SOURCE = src/

# The name of the output file to generate.
KERNEL_TARGET = kernel.img

# The name of the assembler listing file to generate.
LIST = kernel.list

# The name of the map file to generate.
MAP = kernel.map

# The name of the linker script to use.
LINKER = $(ARCH)/$(TARGET_BOARD)/kernel.ld

# Header includes
HEADER_INCLUDES = \
	-I$(SOURCE) \
	-I$(SOURCE)/lib/libc/include \
	-I$(ARCH) \
	-I$(ARCH)/$(TARGET_BOARD)

# Assembly files.
KERNEL_AS = \
	$(wildcard $(ARCH)/kernel/*.s) \
	$(wildcard $(ARCH)/$(TARGET_BOARD)/lib/*.s)
	
# Source files.
KERNEL_SRC = \
	$(wildcard $(ARCH)/kernel/*.cpp) \
	$(wildcard $(ARCH)/$(TARGET_BOARD)/driver/*.cpp) \
	$(wildcard $(SOURCE)/kernel/*.cpp)

# Kernel C-library files.
KERNEL_C_LIB = \
	$(wildcard $(SOURCE)/lib/libc/string/*.c)

KERNEL_AS_OBJ =  $(patsubst %.s, %.o, $(KERNEL_AS))
KERNEL_SRC_OBJ = $(patsubst %.cpp, %.o, $(KERNEL_SRC))
KERNEL_C_LIB_OBJ = $(patsubst %.c, %.o, $(KERNEL_C_LIB))

# Rule to make everything.
all: build_kernel_c_lib build_kernel build_binary build_list

# Rule to make kernel C library.
build_kernel_c_lib: $(KERNEL_C_LIB_OBJ)
%.o : %.c
	mkdir -p $(dir $(BUILD)$@)
	$(CC) $(CFLAGS) $(HEADER_INCLUDES) -c $< -o $(BUILD)$@

# Rule to make the object files.
build_kernel: $(KERNEL_AS_OBJ) $(KERNEL_SRC_OBJ)
%.o : %.s
	mkdir -p $(dir $(BUILD)$@)
	$(AS) $(ASFLAGS) $< -o $(BUILD)$@ 
%.o : %.cpp
	mkdir -p $(dir $(BUILD)$@)
	$(CC) $(CFLAGS) $(HEADER_INCLUDES) -c $< -o $(BUILD)$@

# Rule to make the kernel image file.
build_binary: $(KERNEL_AS_OBJ) $(KERNEL_SRC_OBJ) $(KERNEL_C_LIB_OBJ))
	$(CC) $(CFLAGS) \
	$(addprefix $(BUILD), $(KERNEL_C_LIB_OBJ)) \
	$(addprefix $(BUILD), $(KERNEL_AS_OBJ)) \
	$(addprefix $(BUILD), $(KERNEL_SRC_OBJ)) \
	-T $(LINKER)  -o $(BUILD)MinOS.elf
	$(LD) $(LDFLAGS) -Map $(BUILD)$(MAP)
	$(CP) $(BUILD)MinOS.elf -O binary $(BUILD)$(KERNEL_TARGET)

# Rule to make the listing file.
build_list: $(BUILD)MinOS.elf
	$(OD) -D $(BUILD)MinOS.elf > $(BUILD)$(LIST)

# Rule to clean the project.
clean:
	rm -f $(addprefix $(BUILD), $(KERNEL_C_LIB_OBJ))
	rm -f $(addprefix $(BUILD), $(KERNEL_AS_OBJ))
	rm -f $(addprefix $(BUILD), $(KERNEL_SRC_OBJ))
	rm -f $(BUILD)MinOS.elf
	rm -f $(BUILD)$(MAP)
	rm -f $(BUILD)$(KERNEL_TARGET)
	rm -f $(BUILD)$(LIST)
	find $(BUILD) -type d -empty -delete
Which unfortunately gives me an annoying error I cannot seem to understand why it is there:

Code: Select all

mkdir -p build/src//lib/libc/string/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -nodefaultlibs -lgcc -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c src//lib/libc/string/strlen.c -o build/src//lib/libc/string/strlen.o
mkdir -p build/arch/arm/kernel/
/home/simonha/opt/cross/bin/arm-none-eabi-as -mcpu=arm1176jzf-s arch/arm/kernel/boot.s -o build/arch/arm/kernel/boot.o 
mkdir -p build/arch/arm/pi-zero/lib/
/home/simonha/opt/cross/bin/arm-none-eabi-as -mcpu=arm1176jzf-s arch/arm/pi-zero/lib/ok_led.s -o build/arch/arm/pi-zero/lib/ok_led.o 
mkdir -p build/arch/arm/pi-zero/driver/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -nodefaultlibs -lgcc -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c arch/arm/pi-zero/driver/uart.cpp -o build/arch/arm/pi-zero/driver/uart.o
mkdir -p build/src//kernel/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -nodefaultlibs -lgcc -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c src//kernel/kernel.cpp -o build/src//kernel/kernel.o
make: *** No rule to make target 'src//lib/libc/string/strlen.o)', needed by 'build_binary'.  Stop.
[Finished in 0.5s with exit code 2]
[shell_cmd: make]
[dir: /media/sf_MinOS]
[path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games]
Any ideas about the issue? Furthermore, should I compile my kernel C-library externally and link it with the kernel makefile afterwards? I appreciate your help.

Best regards,
Simon
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Issue with compiling "Hello World" OS setup

Post by iansjack »

There appears to be a rogue ")" at the end of the line:

build_binary: $(KERNEL_AS_OBJ) $(KERNEL_SRC_OBJ) $(KERNEL_C_LIB_OBJ))
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Re: Issue with compiling "Hello World" OS setup

Post by SimonHA »

Okay, that is a bit embarrassing :shock:
It does not complain about this anymore. However, how do I deal with this new error?

Code: Select all

/home/simonha/opt/cross/lib/gcc/arm-none-eabi/6.2.0/../../../../arm-none-eabi/bin/ld: cannot find crt0.o: No such file or directory
I know that crt0 is the startup routine, which I already have in my boot.s file, where I clean up the BSS etc. before
jumping to my kernel main entry. The boot.s contain a global _start routine so the linker should find this, yet it still complains?
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Issue with compiling "Hello World" OS setup

Post by iansjack »

I would move your startup routines into your own version of crt0.o. There are other solutions, but this is probably the easiest.

Bear in mind that any userspace programs that you want to compile for your system will also need some sort of startup routine. Normally, at the very least, it creates argv[] and argc, and calls main().
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Re: Issue with compiling "Hello World" OS setup

Post by SimonHA »

Okay, thank you for your help. How do I tell my cross compiler where this crt0.o is?
Icee
Member
Member
Posts: 100
Joined: Wed Jan 08, 2014 8:41 am
Location: Moscow, Russia

Re: Issue with compiling "Hello World" OS setup

Post by Icee »

Your LDFLAGS should include a -nostdlib flag which implies -nostartfiles which will stop the linker from trying to locate crt0.o. You'll also need -lgcc when linking.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Issue with compiling "Hello World" OS setup

Post by iansjack »

I think that Icee's advice is better than mine, so I'd recommend that you try that first.
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Re: Issue with compiling "Hello World" OS setup

Post by SimonHA »

So far so good. Here is the updated Makefile:

Code: Select all

# Target definitions.
ARCH 			= arch/arm
TARGET_BOARD	= pi-zero
TARGET_CPU		= arm1176jzf-s

# Compiler setup.
COMPILER = /home/simonha/opt/cross/bin/arm-none-eabi
AS = $(COMPILER)-as
CC = $(COMPILER)-g++
LD = $(COMPILER)-g++
CP = $(COMPILER)-objcopy
OD = $(COMPILER)-objdump

ASFLAGS	= -mcpu=$(TARGET_CPU)
CFLAGS 	= -mcpu=$(TARGET_CPU) -ffreestanding -Wall -Wextra -fpic -std=c++11
LDFLAGS = -nostdlib -lgcc

# Directory setup.
BUILD = build/
SOURCE = src/

# The name of the output file to generate.
KERNEL_TARGET = kernel.img

# The name of the assembler listing file to generate.
LIST = kernel.list

# The name of the map file to generate.
MAP = kernel.map

# The name of the linker script to use.
LINKER = $(ARCH)/$(TARGET_BOARD)/kernel.ld

# Header includes
HEADER_INCLUDES = \
	-I$(SOURCE) \
	-I$(SOURCE)/lib/libc/include \
	-I$(ARCH) \
	-I$(ARCH)/$(TARGET_BOARD)

# Assembly files.
KERNEL_AS = \
	$(wildcard $(ARCH)/kernel/*.s) \
	$(wildcard $(ARCH)/$(TARGET_BOARD)/lib/*.s)
	
# Source files.
KERNEL_SRC = \
	$(wildcard $(ARCH)/kernel/*.cpp) \
	$(wildcard $(ARCH)/$(TARGET_BOARD)/driver/*.cpp) \
	$(wildcard $(SOURCE)/kernel/*.cpp)

# Kernel C-library files.
KERNEL_C_LIB = \
	$(wildcard $(SOURCE)/lib/libc/string/*.c)

KERNEL_AS_OBJ =  $(patsubst %.s, %.o, $(KERNEL_AS))
KERNEL_SRC_OBJ = $(patsubst %.cpp, %.o, $(KERNEL_SRC))
KERNEL_C_LIB_OBJ = $(patsubst %.c, %.o, $(KERNEL_C_LIB))

# Rule to make everything.
all: build_kernel_c_lib build_kernel build_binary build_list

# Rule to make kernel C library.
build_kernel_c_lib: $(KERNEL_C_LIB_OBJ)
%.o : %.c
	mkdir -p $(dir $(BUILD)$@)
	$(CC) $(CFLAGS) $(HEADER_INCLUDES) -c $< -o $(BUILD)$@

# Rule to make the object files.
build_kernel: $(KERNEL_AS_OBJ) $(KERNEL_SRC_OBJ)
%.o : %.s
	mkdir -p $(dir $(BUILD)$@)
	$(AS) $(ASFLAGS) $< -o $(BUILD)$@ 
%.o : %.cpp
	mkdir -p $(dir $(BUILD)$@)
	$(CC) $(CFLAGS) $(HEADER_INCLUDES) -c $< -o $(BUILD)$@

# Rule to make the kernel image file.
build_binary: $(KERNEL_AS_OBJ) $(KERNEL_SRC_OBJ) $(KERNEL_C_LIB_OBJ)
	$(LD) $(LDFLAGS) \
	$(addprefix $(BUILD), $(KERNEL_C_LIB_OBJ)) \
	$(addprefix $(BUILD), $(KERNEL_AS_OBJ)) \
	$(addprefix $(BUILD), $(KERNEL_SRC_OBJ)) \
	-T $(LINKER)  -o $(BUILD)MinOS.elf
	$(LD) $(LDFLAGS) -Map $(BUILD)$(MAP)
	$(CP) $(BUILD)MinOS.elf -O binary $(BUILD)$(KERNEL_TARGET)

# Rule to make the listing file.
build_list: $(BUILD)MinOS.elf
	$(OD) -D $(BUILD)MinOS.elf > $(BUILD)$(LIST)

# Rule to clean the project.
clean:
	rm -f $(addprefix $(BUILD), $(KERNEL_C_LIB_OBJ))
	rm -f $(addprefix $(BUILD), $(KERNEL_AS_OBJ))
	rm -f $(addprefix $(BUILD), $(KERNEL_SRC_OBJ))
	rm -f $(BUILD)MinOS.elf
	rm -f $(BUILD)$(MAP)
	rm -f $(BUILD)$(KERNEL_TARGET)
	rm -f $(BUILD)$(LIST)
	find $(BUILD) -type d -empty -delete
The linker finds the libgcc but does not seem to find the required functions such as '__aeabi_uidiv'?

Code: Select all

mkdir -p build/src//lib/libc/string/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c src//lib/libc/string/strlen.c -o build/src//lib/libc/string/strlen.o
mkdir -p build/arch/arm/kernel/
/home/simonha/opt/cross/bin/arm-none-eabi-as -mcpu=arm1176jzf-s arch/arm/kernel/start.s -o build/arch/arm/kernel/start.o 
mkdir -p build/arch/arm/pi-zero/lib/
/home/simonha/opt/cross/bin/arm-none-eabi-as -mcpu=arm1176jzf-s arch/arm/pi-zero/lib/ok_led.s -o build/arch/arm/pi-zero/lib/ok_led.o 
mkdir -p build/arch/arm/pi-zero/driver/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c arch/arm/pi-zero/driver/uart.cpp -o build/arch/arm/pi-zero/driver/uart.o
mkdir -p build/src//kernel/
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -mcpu=arm1176jzf-s -ffreestanding -Wall -Wextra -fpic -std=c++11 -Isrc/ -Isrc//lib/libc/include -Iarch/arm -Iarch/arm/pi-zero -c src//kernel/kernel.cpp -o build/src//kernel/kernel.o
/home/simonha/opt/cross/bin/arm-none-eabi-g++ -nostdlib -lgcc \
build/src//lib/libc/string/strlen.o \
build/arch/arm/kernel/start.o build/arch/arm/pi-zero/lib/ok_led.o \
build/arch/arm/pi-zero/driver/uart.o build/src//kernel/kernel.o \
-T arch/arm/pi-zero/kernel.ld  -o build/MinOS.elf
build/arch/arm/pi-zero/driver/uart.o: In function `uart::init(unsigned long)':
uart.cpp:(.text+0x64): undefined reference to `__aeabi_uidiv'
uart.cpp:(.text+0x8c): undefined reference to `__aeabi_uidiv'
build/arch/arm/pi-zero/driver/uart.o:(.ARM.exidx+0x10): undefined reference to `__aeabi_unwind_cpp_pr1'
build/src//kernel/kernel.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1'
collect2: error: ld returned 1 exit status
Makefile:80: recipe for target 'build_binary' failed
make: *** [build_binary] Error 1
[Finished in 0.7s with exit code 2]
[shell_cmd: make]
[dir: /media/sf_MinOS]
[path: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games]
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Issue with compiling "Hello World" OS setup

Post by xenos »

This might sound trivial, but did you actually compile libgcc (with "make all-target-libgcc; make install-targel-libgcc" IIRC) when building your cross compiler? If you did, you can check whether it contains these functions.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Re: Issue with compiling "Hello World" OS setup

Post by SimonHA »

Yes I followed the instructions from the tutorial thoroughly and from a dump (objdump libgcc.a -t) of the file
"/home/simonha/opt/cross/lib/gcc/arm-none-eabi/6.2.0/libgcc.a", which I got from the linker I can find it:

Code: Select all

_udivsi3.o:     file format elf32-little

SYMBOL TABLE:
00000000 l    d  .text	00000000 .text
00000000 l    d  .data	00000000 .data
00000000 l    d  .bss	00000000 .bss
00000000 l       .text	00000000 $a
00000000 l       .text	00000000 .udivsi3_skip_div0_test
00000000 l    d  .debug_frame	00000000 .debug_frame
00000010 l       .debug_frame	00000000 $d
00000000 l    d  .debug_info	00000000 .debug_info
00000000 l    d  .debug_abbrev	00000000 .debug_abbrev
00000000 l    d  .debug_line	00000000 .debug_line
00000000 l    d  .debug_aranges	00000000 .debug_aranges
00000000 l    d  .ARM.attributes	00000000 .ARM.attributes
00000000 g     F .text	000000f4 .hidden __udivsi3
00000000 g     F .text	00000000 .hidden __aeabi_uidiv
000000f4 g     F .text	00000020 .hidden __aeabi_uidivmod
00000000         *UND*	00000000 __aeabi_idiv0
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issue with compiling "Hello World" OS setup

Post by Octocontrabass »

SimonHA wrote:The linker finds the libgcc but does not seem to find the required functions such as '__aeabi_uidiv'?
You need to put -lgcc after your object files instead of before.
SimonHA
Posts: 12
Joined: Thu Nov 10, 2016 4:00 pm

Re: Issue with compiling "Hello World" OS setup

Post by SimonHA »

Thank you. That did the trick! I also needed to add -fno-exceptions to the G++ compiler. Now it builds :)
Post Reply