From: Duje Mihanović Date: Tue, 28 Jun 2022 10:39:28 +0000 (+0200) Subject: Complete build system rehaul X-Git-Url: http://git.dujemihanovic.xyz/posts?a=commitdiff_plain;h=bdad753bd8125abc67a24b5d8030fa9cfb8706db;p=nameless-os.git Complete build system rehaul Inspired by Linux, the top Makefile is more recursive and practically every directory has its own sub-Makefile which builds or includes only code inside its directory. This new system works beautifully with -B and parallel jobs, while the previous one would in either case build the bootloader multiple times (and, in the case of parallel jobs, cause weird sporadic build errors). --- diff --git a/Makefile b/Makefile index 5d8c1eb..993a455 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,22 @@ export AS = yasm -ASFLAGS = -g dwarf2 -f elf export CC = i686-elf-gcc -QEMU = qemu-system-i386 -monitor stdio - +export QEMU = qemu-system-i386 -monitor stdio export GIT_REV = $(shell git describe --long HEAD) - -CFLAGS = -g -fgnu89-inline -Ikernel/include -Ikernel/include/arch/x86 -ffreestanding -DGIT_COMMIT=\"$(GIT_REV)\" - -KERNEL_OBJ = kernel/entry.o kernel/arch/x86/halt.o kernel/arch/x86/tty/tty.o kernel/drivers/irq/i8259a.o kernel/arch/x86/irq/idt.o kernel/arch/x86/irq/interrupt.o kernel/arch/x86/irq/stub.o kernel/kernel.o - -BOOTLOADER_OBJ = boot/x86/mbr boot/x86/vbr-fat32 boot/x86/stage3/LOADER.BIN boot/x86/stage3/loader.elf +MAKEFLAGS += -rR default: kernel/kernel.elf bootloader - all: default boot/x86/disk.img - -bootloader: $(BOOTLOADER_OBJ) - run: all $(QEMU) boot/x86/disk.img - debug: all $(QEMU) -s -S boot/x86/disk.img -boot/x86/mbr: boot/x86/mbr.s -boot/x86/vbr-fat32: boot/x86/vbr-fat32.s boot/x86/fat32/*.s -boot/x86/stage3/LOADER.BIN: boot/x86/stage3/*.s boot/x86/stage3/*.c boot/x86/fat32/*.s boot/x86/stage3/stage3.ld -boot/x86/stage3/loader.elf: boot/x86/stage3/*.s boot/x86/stage3/*.c boot/x86/fat32/*.s boot/x86/stage3/stage3.ld -$(BOOTLOADER_OBJ): +kernel/kernel.elf: + $(MAKE) -C kernel +bootloader: $(MAKE) -C boot/x86 -boot/x86/disk.img: boot/x86/mbr boot/x86/vbr-fat32 boot/x86/stage3/LOADER.BIN boot/x86/disk.dump kernel/kernel.elf +boot/x86/disk.img: bootloader boot/x86/disk.dump kernel/kernel.elf truncate -s1G boot/x86/disk.img sfdisk boot/x86/disk.img < boot/x86/disk.dump mkfs.fat -F 32 --offset 2048 boot/x86/disk.img @@ -39,14 +25,11 @@ boot/x86/disk.img: boot/x86/mbr boot/x86/vbr-fat32 boot/x86/stage3/LOADER.BIN bo mcopy -i boot/x86/disk.img@@1M boot/x86/stage3/LOADER.BIN ::. mcopy -i boot/x86/disk.img@@1M kernel/kernel.elf ::./KERNEL.ELF -kernel/kernel.elf: $(KERNEL_OBJ) - $(CC) -ffreestanding -nostdlib -o $@ -T kernel/linker.ld ${KERNEL_OBJ} -lgcc - i686-elf-objcopy --only-keep-debug kernel/kernel.elf kernel/kernel.dbg - i686-elf-objcopy --add-gnu-debuglink=kernel/kernel.dbg kernel/kernel.elf - i686-elf-strip --strip-unneeded kernel/kernel.elf - clean: - -rm kernel/kernel.{dbg,elf} ${KERNEL_OBJ} - cd boot/x86 && $(MAKE) clean + $(MAKE) -C boot/x86 clean + $(MAKE) -C kernel clean -.PHONY: default all clean run debug bootloader +# Even though kernel.elf is a real target, it's considered phony so that the +# kernel Makefile is always run. We don't check is the kernel binary up-to-date +# here because we want to be more recursive. +.PHONY: default all clean run debug bootloader kernel/kernel.elf diff --git a/boot/x86/Makefile b/boot/x86/Makefile index e75e8dc..3d12d12 100644 --- a/boot/x86/Makefile +++ b/boot/x86/Makefile @@ -1,27 +1,19 @@ -default: mbr vbr-fat32 stage3/LOADER.BIN stage3/loader.elf +BOOTLOADER_OBJ = mbr vbr-fat32 +ASFLAGS_BASE = -w-zeroing -CFLAGS=-g -ffreestanding -Istage3 -LD=i686-elf-gcc -LDFLAGS=-T stage3/stage3.ld -ffreestanding -nostdlib -g +default: $(BOOTLOADER_OBJ) stage3 -STAGE3_OBJ=stage3/loader.o stage3/paging.o stage3/elf.o stage3/prekernel.o - -mbr: mbr.s - $(AS) $(ASFLAGS) -w-zeroing -o $@ $< +stage3: + $(MAKE) -C stage3 vbr-fat32: vbr-fat32.s fat32/*.s - $(AS) $(ASFLAGS) -o $@ $< - -stage3/loader.elf: $(STAGE3_OBJ) - $(CC) $(LDFLAGS) -o $@ $^ -lgcc -Wl,--oformat=elf32-i386 - -stage3/LOADER.BIN: $(STAGE3_OBJ) - $(CC) $(LDFLAGS) -o $@ $^ -lgcc - -stage3/loader.o: stage3/loader.s stage3/*.s - $(AS) $(ASFLAGS) -f elf -g dwarf2 -DGIT_REVISION=\"$(GIT_REV)\" -o $@ $< clean: - -rm mbr vbr-fat32 stage3/LOADER.BIN stage3/loader.elf $(STAGE3_OBJ) disk.img + -rm mbr vbr-fat32 disk.img + $(MAKE) -C stage3 clean + +# Implicit rules +%: %.s + $(AS) $(ASFLAGS_BASE) -f bin $< -o $@ -.PHONY : default clean +.PHONY : default clean stage3 diff --git a/boot/x86/stage3/Makefile b/boot/x86/stage3/Makefile new file mode 100644 index 0000000..c9622b2 --- /dev/null +++ b/boot/x86/stage3/Makefile @@ -0,0 +1,25 @@ +STAGE3_OBJ = loader.o elf.o paging.o prekernel.o + +ASFLAGS_BASE = -f elf -g dwarf2 -DGIT_REVISION=\"$(GIT_REV)\" +CFLAGS_BASE = -ffreestanding -nostdlib -DGIT_REVISION=\"$(GIT_REV)\" -g +LDFLAGS_BASE = -ffreestanding -nostdlib -g -lgcc -T stage3.ld + +default: LOADER.BIN loader.elf + +loader.elf: $(STAGE3_OBJ) + $(CC) $(LDFLAGS_BASE) $(LDFLAGS) -Wl,--oformat=elf32-i386 $^ -o $@ + +LOADER.BIN: $(STAGE3_OBJ) + $(CC) $(LDFLAGS_BASE) $(LDFLAGS) $^ -o $@ + +# Implicit rules +%.o: %.c + $(CC) $(CFLAGS_BASE) $(CFLAGS) -c $< -o $@ + +%.o: %.s + $(AS) $(ASFLAGS_BASE) $(ASFLAGS) $< -o $@ + +clean: + -rm -f $(STAGE3_OBJ) LOADER.BIN loader.elf + +.PHONY: default clean diff --git a/boot/x86/stage3/elf.c b/boot/x86/stage3/elf.c index d3d215f..8621c39 100644 --- a/boot/x86/stage3/elf.c +++ b/boot/x86/stage3/elf.c @@ -1,7 +1,7 @@ /* Code for parsing ELF binaries (the kernel) */ -#include -#include +#include "elf.h" +#include "paging.h" #include int check_elf_header(struct elf_header *header) diff --git a/boot/x86/stage3/paging.c b/boot/x86/stage3/paging.c index 5a0e5f7..14afe85 100644 --- a/boot/x86/stage3/paging.c +++ b/boot/x86/stage3/paging.c @@ -1,7 +1,7 @@ /* Code for enabling paging */ #include -#include +#include "paging.h" /* Preallocated page tables. */ static uint32_t page_directory[1024] __attribute__((aligned(4096))) __attribute__((section(".data"))); diff --git a/boot/x86/stage3/prekernel.c b/boot/x86/stage3/prekernel.c index 280c350..07bd721 100644 --- a/boot/x86/stage3/prekernel.c +++ b/boot/x86/stage3/prekernel.c @@ -1,5 +1,5 @@ -#include -#include +#include "elf.h" +#include "paging.h" /* This bit of code will be run right after the segment registers have been set * up for protected mode. */ diff --git a/boot/x86/stage3/stage3.ld b/boot/x86/stage3/stage3.ld index 1accdc0..e8bb5e7 100644 --- a/boot/x86/stage3/stage3.ld +++ b/boot/x86/stage3/stage3.ld @@ -4,7 +4,7 @@ OUTPUT_FORMAT(binary) SECTIONS { . = 0x1800; .text : { - stage3/loader.o(.text) + loader.o(.text) *(.text) } .rodata : { *(.rodata) } diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..a872ca6 --- /dev/null +++ b/kernel/Makefile @@ -0,0 +1,26 @@ +KERNEL_OBJ = kernel.o entry.o + +include drivers/Makefile +include arch/x86/Makefile + +ASFLAGS_BASE = -f elf -g dwarf2 +CFLAGS_BASE = -fgnu89-inline -ffreestanding -nostdlib -Iinclude -Iinclude/arch/x86 -g -DGIT_COMMIT=\"$(GIT_REV)\" +LDFLAGS_BASE = -ffreestanding -nostdlib -lgcc -g + +kernel.elf kernel.dbg: $(KERNEL_OBJ) + $(CC) $(LDFLAGS_BASE) $(LDFLAGS) -T linker.ld $^ -o $@ + i686-elf-objcopy --only-keep-debug kernel.elf kernel.dbg + i686-elf-objcopy --add-gnu-debuglink=kernel.dbg kernel.elf + i686-elf-strip --strip-unneeded kernel.elf + +clean: + -rm $(KERNEL_OBJ) kernel.elf kernel.dbg + +# Implicit rules +%.o: %.c + $(CC) $(CFLAGS_BASE) $(CFLAGS) -c $< -o $@ + +%.o: %.s + $(AS) $(ASFLAGS_BASE) $(ASFLAGS) $< -o $@ + +.PHONY: clean diff --git a/kernel/arch/x86/Makefile b/kernel/arch/x86/Makefile new file mode 100644 index 0000000..52224a3 --- /dev/null +++ b/kernel/arch/x86/Makefile @@ -0,0 +1,4 @@ +include arch/x86/irq/Makefile +include arch/x86/tty/Makefile + +KERNEL_OBJ += arch/x86/halt.o diff --git a/kernel/arch/x86/irq/Makefile b/kernel/arch/x86/irq/Makefile new file mode 100644 index 0000000..3dc6f82 --- /dev/null +++ b/kernel/arch/x86/irq/Makefile @@ -0,0 +1 @@ +KERNEL_OBJ += $(addprefix arch/x86/irq/, idt.o interrupt.o stub.o) diff --git a/kernel/arch/x86/tty/Makefile b/kernel/arch/x86/tty/Makefile new file mode 100644 index 0000000..0498223 --- /dev/null +++ b/kernel/arch/x86/tty/Makefile @@ -0,0 +1 @@ +KERNEL_OBJ += arch/x86/tty/tty.o diff --git a/kernel/drivers/Makefile b/kernel/drivers/Makefile new file mode 100644 index 0000000..76d86aa --- /dev/null +++ b/kernel/drivers/Makefile @@ -0,0 +1 @@ +include drivers/irq/Makefile diff --git a/kernel/drivers/irq/Makefile b/kernel/drivers/irq/Makefile new file mode 100644 index 0000000..cd5b834 --- /dev/null +++ b/kernel/drivers/irq/Makefile @@ -0,0 +1 @@ +KERNEL_OBJ += drivers/irq/i8259a.o diff --git a/kernel/linker.ld b/kernel/linker.ld index a6fb8e4..40870da 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -7,7 +7,7 @@ SECTIONS .text : AT(ADDR(.text) - 0xbff00000) ALIGN(4K) { __TEXT_BASE__ = .; - kernel/entry.o (.text) + entry.o (.text) *(.text) __TEXT_END__ = .; }