Makefile in OS Development

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
hshihab
Posts: 1
Joined: Sun Apr 21, 2013 5:47 pm

Makefile in OS Development

Post by hshihab »

I'm currently working on bulding a simple OS from scratch and i'm follwoing a tutorial guide.

as the tutorial advances to the point where you combine the boot_sector code with the kernel code to boot the OS , the amount of terminal commands to compile and execute the OS-image was fairly high.

So the tutorial (fortunately) included a full section about Automating builds with Make

So i decided to break up all of the OS related codes into three directories : boot, drivers, kernel

--Code(here will be the makefile)
--boot:
--some necessary .asm files
--kernel:
--all kernel related files are here (such as kernel.c)
--drivers:
--all driver related files are here

and here is my Makefile so far :

Code: Select all

# Automatically generate lists of sources using wildcards.
VPATH=./boot:./kernel:./drivers
C_SOURCES = $( wildcard kernel/*.c drivers/*.c )
HEADERS = $( wildcard kernel/*.h drivers/*.h )
# TODO : Make sources dep on all header files.


# Convert the *. c filenames to *. o to give a list of object files to build
OBJ = ${C_SOURCES:.c =.o}

# Defaul build target
all: os-image


# Run bochs to simulate booting of our code.
run: all
	bochs

# This is the actual disk image that the computer loads
# which is the combination of our compiled bootsector and kernel
os-image : boot/boot_sect_c.bin kernel.bin
	cat $^ > os-image

# This builds the binary of our kernel from two object files :
# - the kernel_entry , which jumps to main () in our kernel
# - the compiled C kernel
kernel.bin : kernel/kernel_entry.o ${OBJ}
	ld -o $@ -Ttext 0x1000 $^ --oformat binary

# Generic rule for compiling C code to an object file
# For simplicity , we C files depend on all header files .
%.o : %.c ${HEADERS}
	gcc -ffreestanding -c $< -o $@

# Assemble the kernel_entry.
%.o : %.asm
	nasm $< -f elf -o $@
%.bin : %.asm
	nasm $< -f bin -I 'boot/' -o $@
clean:
	rm -fr *.bin *.dis *.o os-image
	rm -fr kernel/*.o boot/*.bin drivers/*.o
now , when i try to make use of the makefile and run :

Code: Select all

make run
this is what i get

Code: Select all

nasm boot/boot_sect_c.asm -f bin -I 'boot/' -o boot/boot_sect_c.bin
nasm kernel/kernel_entry.asm -f elf -o kernel/kernel_entry.o
ld -o kernel.bin -Ttext 0x1000 kernel/kernel_entry.o --oformat binary
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
[color=#FF0000]kernel/kernel_entry.o:(.text+0x1): undefined reference to `main'
make: *** [kernel.bin] Error 1[/color]
i tried replacing every source file that could be related to this error into different directories , but i still get the same error



Any help would be greatly appreciated , Thanks
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Makefile in OS Development

Post by xenos »

Do you get the same error when you run the commands manually? (I would say: probably yes. So the problem is not related to the makefile.) The most widely accepted solution to this is to use a cross compiler.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Makefile in OS Development

Post by bluemoon »

hshihab wrote:as the tutorial advances to the point where you combine the boot_sector code with the kernel code to boot the OS ,
This is where things getting seriously wrong.
As very simple tutorial it may be useful to combine boot with kernel for illusive purpose, to get you started.
But once you add more stuff on top of it, it will goes nowhere as you waste effort dealing with size limitations, different boot mechanic, etc.

I advice you to isolate boot loader from kernel for cleaner design.

For your question:
ld -o kernel.bin -Ttext 0x1000 kernel/kernel_entry.o --oformat binary
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
kernel/kernel_entry.o:(.text+0x1): undefined reference to `main'
You call ld with host's default, which expect main and probably going to build an application.
Add -nostdinc -nostdlib etc, or better, build a cross compiler.
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Makefile in OS Development

Post by sortie »

Do not pass -nostdinc. It's a mistake. Use a cross-compiler.. Use the GNU assembler rather than nasm and link with your compiler. Be sure to actually provide a _start entry point. Tell us the commands in future instead of giving us the makefile, it's not relevant unless you want me to criticize it.

[Sorry, in a hurry]
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Makefile in OS Development

Post by Combuster »

sortie wrote:Use the GNU assembler rather than nasm
Nonsense.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Makefile in OS Development

Post by sortie »

Combuster wrote:
sortie wrote:Use the GNU assembler rather than nasm
Nonsense.
Sorry - I don't intend to derail this discussion. I recommend the GNU assembler over nasm because it integrates much better with the rest of the GNU toolchain (this is my main reason). You get a fully-fledged cross GAS with your cross-binutils, it uses the same syntax as objdump and inline gcc assembly. Your cross GCC uses it as the backend. You don't have to specify options to tell it the target platform, it remembers your --host option and defaults to that. [Which is good, because it makes your build scripts simpler.] When you make an OS-specific toolchain or otherwise adapt binutils, these changes automatically help you port GAS. [And probably a few other reasons I forgot, such as that GAS supports more platforms.] These are the reasons why I recommend newbies GAS over nasm. (And of course, I don't mind experienced users using nasm, I did in the start, but the fact that GAS integrates better should be important to everyone.)

Oh, and if you are just starting out? I recommend you don't do a bootloader and rather use GRUB and multiboot and do a real ELF kernel. It's much nicer and I can assure you there is plenty of interesting "Not-Invented-Here" to enjoy in kernel mode.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Makefile in OS Development

Post by bluemoon »

I don't see how nasm, yasm or whateverasm not integrate nicely with gcc, and it its either integrate, or does not integrate, there is nothing in between - so how does one better than other?
And no, no assembler war, please. Use the one you are familiar with, they should all work.
sortie wrote:Do not pass -nostdinc. It's a mistake
Proof wanted.
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Makefile in OS Development

Post by sortie »

The -nostdinc option surpressed all standard incude directories. You do want these. For instance, you want to use the <stdarg.h> header that comes with your cross-compiler, and all the other nice headers that come with your cross-compiler. People tend to pass -nostdinc when not using a real cross-compiler to surpress these headers, but that is a mistake as well, because you ought use a cross-compiler in the first place.

[Sorry, didn't intend to start a discussion on assemblers. It it merely my opinion that GAS is better for newbies as it comes with binutils and uses the same syntax as the rest of the toolchain. Please carry on. :-)]
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Makefile in OS Development

Post by bluemoon »

sortie wrote:People tend to pass -nostdinc when not using a real cross-compiler to surpress these headers, but that is a mistake as well,
It is totally work I would not consider it a mistake.
sortie wrote:because you ought use a cross-compiler in the first place.
I totally agree, I also strongly advice to use cross-compiler, but I acknowledge some people like to use host toolchain, and it can be done with special cares.
Post Reply