NAME = metalsvm # For 64bit support, you have define BIT as 64 # Note: do not forget to 'make veryclean' after changing BIT!!! BIT=64 ARCH = x86 SMP=1 TOPDIR = $(shell pwd) LWIPDIRS = lwip/src/arch lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif DRIVERDIRS = drivers/net drivers/char KERNDIRS = libkern kernel mm fs apps arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) SUBDIRS = $(KERNDIRS) STACKPROT = -fno-stack-protector # Set your own cross compiler tool chain prefix here CROSSCOMPREFIX = # Uncomment both lines if compiling for the SCC! #CROSSCOMPREFIX = i386-unknown-linux-gnu- #STACKPROT = CC_FOR_TARGET = $(CROSSCOMPREFIX)gcc CXX_FOR_TARGET = $(CROSSCOMPREFIX)g++ GCC_FOR_TARGET = $(CROSSCOMPREFIX)gcc CPP_FOR_TARGET = $(CROSSCOMPREFIX)cpp AR_FOR_TARGET = $(CROSSCOMPREFIX)ar AS_FOR_TARGET = $(CROSSCOMPREFIX)as LD_FOR_TARGET = $(CROSSCOMPREFIX)ld NM_FOR_TARGET = $(CROSSCOMPREFIX)nm OBJDUMP_FOR_TARGET = $(CROSSCOMPREFIX)objdump OBJCOPY_FOR_TARGET = $(CROSSCOMPREFIX)objcopy RANLIB_FOR_TARGET = $(CROSSCOMPREFIX)ranlib STRIP_FOR_TARGET = $(CROSSCOMPREFIX)strip READELF_FOR_TARGET = $(CROSSCOMPREFIX)readelf # Tools MAKE = make RM = rm -rf NASM = nasm GDB = gdb ifeq ($(BIT), 32) QEMU = qemu-system-i386 else ifeq ($(BIT), 64) QEMU = qemu-system-x86_64 endif INCLUDE = -I$(TOPDIR)/include \ -I$(TOPDIR)/arch/$(ARCH)/include \ -I$(TOPDIR)/lwip/src/include \ -I$(TOPDIR)/lwip/src/include/ipv4 \ -I$(TOPDIR)/drivers # Compiler options for final code CFLAGS = -g -O2 -m$(BIT) -Wall -fomit-frame-pointer -ffreestanding -fstrength-reduce -finline-functions $(INCLUDE) $(STACKPROT) # Compiler options for debuging #CFLAGS = -g -O -m$(BIT) -Wall -fomit-frame-pointer -ffreestanding $(INCLUDE) $(STACKPROT) NASMFLAGS = -felf$(BIT) -g -i$(TOPDIR)/include/metalsvm/ ARFLAGS = rsv LDFLAGS = -T link$(BIT).ld -z max-page-size=4096 --defsym __BUILD_DATE=$(shell date +'%Y%m%d') --defsym __BUILD_TIME=$(shell date +'%H%M%S') STRIP_DEBUG = --strip-debug KEEP_DEBUG = --only-keep-debug # Do not change to elf64! # The Multiboot spec can only boot elf32 binaries OUTPUT_FORMAT = -O elf32-i386 CFLAGS_FOR_NEWLIB = -m$(BIT) -O2 $(STACKPROT) LDFLAGS_FOR_NEWLIB = -m$(BIT) CFLAGS_FOR_TOOLS = -m$(BIT) -O2 -Wall LDFLAGS_FOR_TOOLS = NASMFLAGS_FOR_NEWLIB = -felf$(BIT) ifeq ($(BIT), 32) CFLAGS += -march=i586 CFLAGS_FOR_NEWLIB += -march=i586 LDFLAGS_FOR_NEWLIB += -march=i586 else ifeq ($(BIT), 64) CFLAGS += -mno-red-zone endif # Prettify output V = 0 ifeq ($V,0) Q = @ P = > /dev/null endif default: all all: newlib tools $(NAME).elf newlib: $(MAKE) ARCH=$(ARCH) BIT=$(BIT) \ LDFLAGS="$(LDFLAGS_FOR_NEWLIB)" \ CFLAGS="$(CFLAGS_FOR_NEWLIB)" \ NASMFLAGS="$(NASMFLAGS_FOR_NEWLIB)" \ CC_FOR_TARGET=$(CC_FOR_TARGET) \ CXX_FOR_TARGET=$(CXX_FOR_TARGET) \ GCC_FOR_TARGET=$(GCC_FOR_TARGET) \ AR_FOR_TARGET=$(AR_FOR_TARGET) \ AS_FOR_TARGET=$(AS_FOR_TARGET) \ LD_FOR_TARGET=$(LD_FOR_TARGET) \ NM_FOR_TARGET=$(NM_FOR_TARGET) \ OBJDUMP_FOR_TARGET=$(OBJDUMP_FOR_TARGET) \ OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) \ RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET) \ STRIP_FOR_TARGET=$(STRIP_FOR_TARGET) \ READELF_FOR_TARGET=$(READELF_FOR_TARGET) -C newlib tools: $(MAKE) CFLAGS="$(CFLAGS_FOR_TOOLS)" LDFLAGS="$(LDFLAGS_FOR_TOOLS)" -C tools $(NAME).elf: $Q$(LD_FOR_TARGET) $(LDFLAGS) -o $(NAME).elf $^ @echo [OBJCOPY] $(NAME).sym $Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $(NAME).elf $(NAME).sym @echo [OBJCOPY] $(NAME).elf $Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $(OUTPUT_FORMAT) $(NAME).elf qemu: newlib tools $(NAME).elf $(QEMU) -monitor stdio -serial tcp::12346,server,nowait -smp $(SMP) -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:4711 -kernel metalsvm.elf -initrd tools/initrd.img qemudbg: newlib tools $(NAME).elf $(QEMU) -s -S -nographic -monitor stdio -serial tcp::12346,server -smp $(SMP) -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:4711 -kernel metalsvm.elf -initrd tools/initrd.img gdb: $(NAME).elf $(GDB) -q -x script.gdb debug: newlib tools $(NAME).elf killall $(QEMU) || true killall $(GDB) || true sleep 1 gnome-terminal --working-directory=$(TOPDIR) \ --tab --title=Shell --command="bash -c 'sleep 1 && telnet localhost 12345'" \ --tab --title=QEmu --command="make qemudbg" \ --tab --title=GDB --command="make gdb" \ --tab --title=Debug --command="bash -c 'sleep 1 && telnet localhost 12346'" clean: $Q$(RM) $(NAME).elf $(NAME).sym *~ $Q$(MAKE) -C tools clean @echo Cleaned. veryclean: clean $Q$(MAKE) -C newlib veryclean @echo Very cleaned. #depend: # for i in $(SUBDIRS); do $(MAKE) -k -C $$i depend; done %.o : %.c @echo [CC] $@ $Q$(CC_FOR_TARGET) -c -D__KERNEL__ $(CFLAGS) -o $@ $< @echo [DEP] $*.dep $Q$(CPP_FOR_TARGET) -MF $*.dep -MT $*.o -MM -D__KERNEL__ $(CFLAGS) $< include/metalsvm/config.inc: include/metalsvm/config.h @echo "; This file is generated automatically from the config.h file." > $@ @echo "; Before editing this, you should consider editing config.h." >> $@ @sed -nre 's/^[\t ]*#define[\t ]+([a-z_0-9]+)([\t ]+.*)*/%define \1/ip' $< >> $@ @sed -nre 's/^[\t ]*#define[\t ]+([a-z_0-9]+)[\t ]+([a-z_0-9.]+)([\t ]+.*)*/%define \1 \2/ip' $< >> $@ %.o : %.asm include/metalsvm/config.inc @echo [ASM] $@ $Q$(NASM) $(NASMFLAGS) -o $@ $< .PHONY: default all clean qemu qemudbg gdb debug newlib tools include $(addsuffix /Makefile,$(SUBDIRS))