# Note: Your cross-compilation toolchain must be in PATH for this # to work. Change these variables if it isn't (it should be, trust me) .SUFFIXES: CC := i386-elf-gcc GDB := i386-elf-gdb LD := i386-elf-ld AS := nasm IDIR := include SRCDIR := src BUILDDIR := build OBJDIR := obj DISTDIR := dist GDB := gdb CFLAGS := -o0 -ggdb -I $(IDIR) -Wall -pedantic -Wno-builtin-declaration-mismatch -ffreestanding KERNEL_SOURCES := $(shell find src/kernel -name '*.c' -type f) KERNEL_OBJS := $(KERNEL_SOURCES:.c=.o) KERNEL_OBJS := $(subst src/,$(OBJDIR)/,$(KERNEL_OBJS)) DRIVERS_SOURCES := $(shell find src/kernel/drivers -name '*.c' -type f) DRIVERS_OBJS := $(DRIVERS_SOURCES:.c=.o) DRIVERS_OBJS := $(subst src/,$(OBJDIR)/,$(DRIVERS_OBJS)) BOOTLOADER_SOURCES := $(shell find src/boot -name '*.s' -type f) BOOTLOADER_OBJS := $(BOOTLOADER_SOURCES:.s=.o) BOOTLOADER_OBJS := $(subst src/,$(OBJDIR)/,$(BOOTLOADER_OBJS)) BUILD_PATHS := $(subst src/,$(OBJDIR),$(dir $(KERNEL_OBJS))) BUILD_PATHS += $(subst src/,$(OBJDIR),$(dir $(DRIVERS_OBJS))) prepare: mkdir -p $(BUILD_PATHS) build obj dist clean: rm -rf obj/ rm -rf build/ rm -rf dist/ # Produce obj/path/to/file.o in the ELF format # if src/path/to/file.s exists $(OBJDIR)/%.o: prepare $(SRCDIR)/%.s $(AS) -f elf $(word 2,$^) -o $@ # Produce build/path/to/file.bin in the binary # format if src/path/to/file.s exists $(BUILDDIR)/%.bin: prepare $(SRCDIR)/%.s $(AS) -f bin $(word 2,$^) -o $@ # Special case for our master boot record $(BUILDDIR)/mbr.bin: prepare $(SRCDIR)/boot/mbr.s $(AS) -f bin $(word 2,$^) -o $(BUILDDIR)/mbr.bin # Produce obj/path/to/file.o using gcc if # src/path/to/file.c exists $(OBJDIR)/%.o: prepare $(SRCDIR)/%.c $(CC) $(CFLAGS) -c $(word 2,$^) -o $@ # Compile kernel drivers drivers: $(DRIVERS_OBJS) # Compile and link the kernel $(BUILDDIR)/kernel.bin: $(OBJDIR)/entrypoint.o $(KERNEL_OBJS) $(DRIVERS_OBJS) $(LD) -o $@ -Ttext 0x1000 $^ --oformat binary # Compile and link the kernel with debug symbols $(BUILDDIR)/kernel.elf: $(OBJDIR)/entrypoint.o $(KERNEL_OBJS) $(DRIVERS_OBJS) $(LD) -o $@ -Ttext 0x1000 $^ kernel: $(BUILDDIR)/kernel.bin # Compile the bootloader bootloader: $(BUILDDIR)/mbr.bin # Compile and link everything all: bootloader drivers kernel image: $(BUILDDIR)/mbr.bin $(BUILDDIR)/kernel.bin mkdir -p $(DISTDIR)/ cat $^ > $(DISTDIR)/os.img run: image qemu-system-i386 -drive format=raw,file=$(DISTDIR)/os.img,index=0,media=disk debug: $(BUILDDIR)/kernel.elf image qemu-system-i386 -drive format=raw,file=$(DISTDIR)/os.img,index=0,media=disk -gdb tcp:localhost:8080 -S