# opencoreC - Root Unified Makefile # Target Architecture: x86_64 Long Mode (Microkernel OS) SHELL := /usr/bin/env bash # Toolchain definitions CC := gcc CXX := g++ LD := ld CARGO := cargo QEMU := qemu-system-x86_64 # Directory layout BUILD_DIR := build CONFIG_DIR := config INCLUDE_DIR := include LIB_DIR := lib HAL_DIR := hal SERVERS_DIR := servers KERNEL_DIR := kernel LIMINE_DIR := boot/limine # Common Freestanding Flags COMMON_FLAGS := -Wall -Wextra -O2 -ffreestanding -fno-stack-protector \ -fno-pie -no-pie -mno-red-zone -m64 \ -mno-sse -mno-sse2 -mno-avx \ -I$(INCLUDE_DIR) -I$(LIB_DIR)/libc/include CFLAGS := $(COMMON_FLAGS) -std=c11 CXXFLAGS := $(COMMON_FLAGS) -std=c++20 -fno-exceptions -fno-rtti -I$(LIB_DIR)/libipc_cpp/include # Outputs KERNEL_BIN := target/x86_64-unknown-none/release/opencore_kernel KERNEL_ELF := $(BUILD_DIR)/opencore_kernel.elf INIT_SERVER := $(BUILD_DIR)/init_server.elf UART_DRIVER := $(BUILD_DIR)/uart_driver.elf SH_SERVER := $(BUILD_DIR)/sh.elf PROCMGR := $(BUILD_DIR)/procmgr.elf DISK_IMG := $(BUILD_DIR)/opencoreC.img LIBC_OBJS := $(BUILD_DIR)/string.o $(BUILD_DIR)/syscalls.o $(BUILD_DIR)/stdlib.o .PHONY: all kernel libc hal servers image run clean help limine-setup all: kernel libc hal servers @mkdir -p $(BUILD_DIR) @cp $(KERNEL_BIN) $(KERNEL_ELF) @echo "=======================================================" @echo " [SUCCESS] opencoreC Build Complete!" @echo " Kernel: $(KERNEL_ELF)" @echo " Servers: $(INIT_SERVER), $(UART_DRIVER), $(SH_SERVER)" @echo " Run: make image && make run" @echo "=======================================================" kernel: @echo "[CARGO] Compiling Rust Microkernel (x86_64-unknown-none)..." @RUSTFLAGS="-C link-arg=-T$(CONFIG_DIR)/linker.ld -C code-model=kernel -C relocation-model=static" \ $(CARGO) build --package opencore_kernel --target x86_64-unknown-none --release libc: @mkdir -p $(BUILD_DIR) @echo "[CC] Compiling bare-metal freestanding libc..." @$(CC) $(CFLAGS) -c $(LIB_DIR)/libc/src/string.c -o $(BUILD_DIR)/string.o @$(CC) $(CFLAGS) -c $(LIB_DIR)/libc/src/syscalls.c -o $(BUILD_DIR)/syscalls.o @$(CC) $(CFLAGS) -c $(LIB_DIR)/libc/src/stdlib.c -o $(BUILD_DIR)/stdlib.o hal: libc @mkdir -p $(BUILD_DIR) @echo "[CC] Compiling HAL and Hardware Drivers..." @$(CC) $(CFLAGS) -I$(HAL_DIR)/include -c $(HAL_DIR)/src/uart.c -o $(BUILD_DIR)/uart.o @$(CC) $(CFLAGS) -I$(HAL_DIR)/include -c $(HAL_DIR)/src/pci.c -o $(BUILD_DIR)/pci.o @$(CC) $(CFLAGS) -I$(HAL_DIR)/include -c $(HAL_DIR)/src/apic.c -o $(BUILD_DIR)/apic.o servers: libc hal @mkdir -p $(BUILD_DIR) @echo "[CXX/CC] Linking Ring 3 User-space Servers..." @# C++ LibIPC @$(CXX) $(CXXFLAGS) -c $(LIB_DIR)/libipc_cpp/src/ipc.cpp -o $(BUILD_DIR)/ipc.o @# Init Root Server @$(CXX) $(CXXFLAGS) -c $(SERVERS_DIR)/init/main.cpp -o $(BUILD_DIR)/init_main.o @$(LD) -T $(CONFIG_DIR)/user.ld -nostdlib -static -o $(INIT_SERVER) \ $(BUILD_DIR)/init_main.o $(BUILD_DIR)/ipc.o $(LIBC_OBJS) @# Standalone UART Driver Server @$(CC) $(CFLAGS) -I$(HAL_DIR)/include -c $(SERVERS_DIR)/uart_driver/main.c -o $(BUILD_DIR)/uart_driver_main.o @$(LD) -T $(CONFIG_DIR)/user.ld -nostdlib -static -o $(UART_DRIVER) \ $(BUILD_DIR)/uart_driver_main.o $(BUILD_DIR)/uart.o $(LIBC_OBJS) @# Interactive Shell @$(CXX) $(CXXFLAGS) -c $(SERVERS_DIR)/sh/main.cpp -o $(BUILD_DIR)/sh_main.o @$(LD) -T $(CONFIG_DIR)/user.ld -nostdlib -static -o $(SH_SERVER) \ $(BUILD_DIR)/sh_main.o $(BUILD_DIR)/ipc.o $(LIBC_OBJS) @# Process Manager Daemon @$(CXX) $(CXXFLAGS) -c $(SERVERS_DIR)/procmgr/main.cpp -o $(BUILD_DIR)/procmgr_main.o @$(LD) -T $(CONFIG_DIR)/user.ld -nostdlib -static -o $(PROCMGR) \ $(BUILD_DIR)/procmgr_main.o $(BUILD_DIR)/ipc.o $(LIBC_OBJS) # Download and build the Limine bootloader host tool limine-setup: @if [ ! -d "$(LIMINE_DIR)" ]; then \ echo "[LIMINE] Cloning Limine v8 binary branch..."; \ git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 $(LIMINE_DIR); \ fi @echo "[LIMINE] Building host installer tool..." @$(MAKE) -C $(LIMINE_DIR) limine # Build a 64 MiB bootable FAT32 disk image with Limine BIOS/UEFI image: all limine-setup @echo "[IMAGE] Creating bootable disk image (64 MiB FAT32)..." @dd if=/dev/zero of=$(DISK_IMG) bs=1M count=64 2>/dev/null @parted -s $(DISK_IMG) mklabel msdos mkpart primary fat32 2048s 100% set 1 boot on 2>/dev/null @mformat -F -i $(DISK_IMG)@@1M :: @mmd -i $(DISK_IMG)@@1M ::/boot ::/EFI ::/EFI/BOOT @# Kernel and userspace servers @mcopy -i $(DISK_IMG)@@1M $(KERNEL_ELF) ::/boot/ @mcopy -i $(DISK_IMG)@@1M $(INIT_SERVER) ::/boot/ @mcopy -i $(DISK_IMG)@@1M $(UART_DRIVER) ::/boot/ @mcopy -i $(DISK_IMG)@@1M $(SH_SERVER) ::/boot/ @# Bootloader config @mcopy -i $(DISK_IMG)@@1M limine.conf ::/ @mcopy -i $(DISK_IMG)@@1M limine.cfg ::/ @mcopy -i $(DISK_IMG)@@1M limine.conf ::/boot/ @mcopy -i $(DISK_IMG)@@1M limine.cfg ::/boot/ @# Limine bootloader files @mcopy -i $(DISK_IMG)@@1M $(LIMINE_DIR)/limine-bios.sys ::/ @mcopy -i $(DISK_IMG)@@1M $(LIMINE_DIR)/limine-bios.sys ::/boot/ @mcopy -i $(DISK_IMG)@@1M $(LIMINE_DIR)/BOOTX64.EFI ::/EFI/BOOT/ @# Install Limine Stage 1 into MBR @$(LIMINE_DIR)/limine bios-install $(DISK_IMG) 2>&1 | grep -v "^Physical\|^Installing\|^Stage\|^Reminder" @echo "[IMAGE] Done: $(DISK_IMG) (BIOS + UEFI bootable)" # Launch QEMU with serial terminal (keyboard works via -serial stdio) run: image @echo "[QEMU] Launching opencoreC (SMP 4 cores, Serial terminal)..." @echo "[QEMU] Type 'help' for commands. Ctrl+A X to exit QEMU." @echo "-------------------------------------------------------" @$(QEMU) \ -M q35 \ -smp 4 \ -m 512M \ -serial mon:stdio \ -no-reboot \ -display none \ -drive file=$(DISK_IMG),format=raw # Run without rebuilding image (faster iteration) qemu: $(DISK_IMG) @echo "[QEMU] Quick launch from existing image..." @echo "[QEMU] Type 'help'. Ctrl+A X to exit." @$(QEMU) -M q35 -smp 4 -m 512M -serial mon:stdio -no-reboot -display none \ -drive file=$(DISK_IMG),format=raw clean: @echo "[CLEAN] Removing build directory and cargo target..." @rm -rf $(BUILD_DIR) target help: @echo "opencoreC Microkernel Build System" @echo "" @echo "Targets:" @echo " make all - Build kernel, HAL, libc, and all user servers" @echo " make image - Create bootable disk image (build/opencoreC.img)" @echo " make run - Build image and launch in QEMU (interactive serial)" @echo " make qemu - Quick relaunch without rebuild" @echo " make limine-setup - Download/build Limine bootloader" @echo " make clean - Remove all build artifacts" @echo "" @echo "QEMU Controls:" @echo " Type commands in the terminal (serial I/O)" @echo " Ctrl+A then X -> exit QEMU" @echo " Ctrl+A then C -> QEMU monitor"