# Pactor64 Makefile — x86-64 kernel build system # Uses GRUB2 as bootloader with multiboot2 protocol ASM = nasm CC = gcc LD = ld # === Kernel flags === ASM_FLAGS = -f elf64 CC_FLAGS = -std=gnu11 -ffreestanding -fno-builtin -fno-stack-protector \ -fno-pic -fno-pie -O2 -Wall -Wextra -mcmodel=kernel \ -mno-red-zone -mno-sse -mno-sse2 -mgeneral-regs-only \ -nostdlib -nostdinc -Iinclude LD_FLAGS = -T linker.ld -nostdlib -z max-page-size=0x1000 # === Userspace flags === UCC_FLAGS = -std=gnu11 -ffreestanding -fno-builtin -fno-stack-protector \ -no-pie -O2 -Wall -Wextra -mcmodel=small \ -mno-sse -mno-sse2 -mgeneral-regs-only \ -nostdlib -nostdinc -Ilibc ULD_FLAGS = -T userspace.ld -nostdlib --allow-multiple-definition -z max-page-size=0x1000 BUILD_DIR = build ISO_DIR = $(BUILD_DIR)/iso KERNEL_ELF = $(BUILD_DIR)/pactor64.kernel ISO_IMAGE = $(BUILD_DIR)/pactor64.iso DISK_IMG = $(BUILD_DIR)/pactor64.disk # Kernel objects KERNEL_OBJS = $(BUILD_DIR)/entry.o \ $(BUILD_DIR)/isr.o \ $(BUILD_DIR)/main.o \ $(BUILD_DIR)/idt.o \ $(BUILD_DIR)/timer.o \ $(BUILD_DIR)/keyboard.o \ $(BUILD_DIR)/pmm.o \ $(BUILD_DIR)/heap.o \ $(BUILD_DIR)/vga.o \ $(BUILD_DIR)/shell.o \ $(BUILD_DIR)/ext2.o \ $(BUILD_DIR)/ata.o \ $(BUILD_DIR)/elf.o \ $(BUILD_DIR)/syscall.o \ $(BUILD_DIR)/syscall_entry.o # Userspace LIBC_OBJS = $(BUILD_DIR)/start_entry.o $(BUILD_DIR)/libc_start.o PROG_ELF = $(BUILD_DIR)/programs/hello.elf .PHONY: all clean run run-disk debug disk iso programs verify all: $(ISO_IMAGE) @echo "=========================================" @echo " Pactor64 ISO built: $(ISO_IMAGE)" @echo " Kernel: $(KERNEL_ELF)" @echo " Programs: $(PROG_ELF)" @echo "=========================================" $(ISO_IMAGE): $(KERNEL_ELF) $(PROG_ELF) boot/grub.cfg @mkdir -p $(ISO_DIR)/boot/grub $(ISO_DIR)/programs @cp $(KERNEL_ELF) $(ISO_DIR)/boot/pactor64.kernel @cp boot/grub.cfg $(ISO_DIR)/boot/grub/grub.cfg @cp $(PROG_ELF) $(ISO_DIR)/programs/hello.elf 2>/dev/null || true @grub-mkrescue -o $@ $(ISO_DIR) 2>/dev/null # === Kernel linking === $(KERNEL_ELF): $(KERNEL_OBJS) $(LD) $(LD_FLAGS) $^ -o $@ # === Kernel ASM objects === $(BUILD_DIR)/entry.o: kernel/entry.asm | $(BUILD_DIR) $(ASM) $(ASM_FLAGS) $< -o $@ $(BUILD_DIR)/isr.o: kernel/isr.asm | $(BUILD_DIR) $(ASM) $(ASM_FLAGS) $< -o $@ $(BUILD_DIR)/syscall_entry.o: kernel/syscall_entry.asm | $(BUILD_DIR) $(ASM) $(ASM_FLAGS) $< -o $@ # === Kernel C objects === $(BUILD_DIR)/main.o: kernel/main.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/idt.o: kernel/idt.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/timer.o: kernel/timer.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/keyboard.o: kernel/keyboard.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/pmm.o: kernel/pmm.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/heap.o: kernel/heap.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/vga.o: kernel/vga.c include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/shell.o: kernel/shell.c include/pactor64.h kernel/ata.h kernel/ext2.h kernel/elf.h kernel/hello_elf.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/ata.o: kernel/ata.c kernel/ata.h include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/ext2.o: kernel/ext2.c kernel/ext2.h kernel/ata.h include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/elf.o: kernel/elf.c kernel/elf.h include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ $(BUILD_DIR)/syscall.o: kernel/syscall.c kernel/syscall.h include/pactor64.h | $(BUILD_DIR) $(CC) $(CC_FLAGS) -c $< -o $@ # === Userspace libc === $(BUILD_DIR)/start_entry.o: /tmp/start_entry.asm | $(BUILD_DIR) $(ASM) $(ASM_FLAGS) $< -o $@ $(BUILD_DIR)/libc_start.o: libc/start.c libc/libc.h | $(BUILD_DIR) $(CC) $(UCC_FLAGS) -c $< -o $@ # === Userspace programs === programs: $(PROG_ELF) $(BUILD_DIR)/programs/hello.elf: $(BUILD_DIR)/programs/hello.o $(LIBC_OBJS) userspace.ld @mkdir -p $(BUILD_DIR)/programs $(LD) $(ULD_FLAGS) $(BUILD_DIR)/programs/hello.o $(LIBC_OBJS) -o $@ $(BUILD_DIR)/programs/hello.o: programs/hello.c libc/libc.h | $(BUILD_DIR)/programs $(CC) $(UCC_FLAGS) -c $< -o $@ $(BUILD_DIR)/programs: @mkdir -p $@ $(BUILD_DIR): @mkdir -p $@ clean: rm -rf $(BUILD_DIR) run: $(ISO_IMAGE) qemu-system-x86_64 -cdrom $(ISO_IMAGE) -m 512 \ -serial mon:stdio -display none -no-reboot debug: $(ISO_IMAGE) qemu-system-x86_64 -cdrom $(ISO_IMAGE) -m 512 \ -serial mon:stdio -display none -no-reboot -s -S # === Disk image === disk: $(KERNEL_ELF) $(PROG_ELF) @bash scripts/mkdisk.sh # === Boot from disk image === run-disk: disk qemu-system-x86_64 -drive file=$(DISK_IMG),format=raw,if=ide -m 512 \ -serial mon:stdio -display none -no-reboot run-disk-gui: disk qemu-system-x86_64 -drive file=$(DISK_IMG),format=raw,if=ide -m 512 \ -serial mon:stdio -no-reboot verify: $(KERNEL_ELF) @grub-file --is-x86-multiboot2 $(KERNEL_ELF) && echo "VALID multiboot2" || echo "INVALID"