267 lines
10 KiB
Makefile
Executable File
267 lines
10 KiB
Makefile
Executable File
# -----------------------------------------------------------------------------
|
||
#
|
||
# M A K E F I L E
|
||
#
|
||
# zum HHUos der Lehrveranstaltung 'Betriebssystem-Entwicklung'.
|
||
# -----------------------------------------------------------------------------
|
||
#
|
||
# Compilieren: ‘make'
|
||
# Ausfuehren mit Qemu: ‘make qemu’
|
||
# GDB mit Qemu: ‘make qemu-gdb &’ und danach ‘make gdb’
|
||
# DDD mit Qemu: ‘make qemu-gdb &’ und danach ‘make ddd’
|
||
#
|
||
# Aufraeumen mit: ‘make clean’
|
||
#
|
||
# Achtung: Erzeugen von bootfaehigen Medien erfordert das Anpassen folgender
|
||
# Variablen: DRIVE_FD und DRIVE_HD. Aufpassen, ansonsten wir evt.
|
||
# die System-Disk zerstoert.
|
||
#
|
||
# Erzeugen einer bootfaehigen Diskette mit: ‘make bootdisk’
|
||
# Erzeugen eines bootfaehigen USB-Sticks mit: ‘make bootdisk-usb’
|
||
# Erzeugen eines bootfaehigen Festplatte mit: ‘make bootdisk-hd’
|
||
#
|
||
# -----------------------------------------------------------------------------
|
||
# Autor: Olaf Spinzcyk, TU Dortmund
|
||
#
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Liste der Quelltexte:
|
||
|
||
STARTUP_SOURCE = ./startup.asm
|
||
CC_SOURCES = $(shell find . -name "*.cc")
|
||
C_SOURCES = $(shell find . -name "*.c")
|
||
ASM_SOURCES = $(shell find ./kernel -name "*.asm")
|
||
|
||
# Einstellungen in Abhaengigkeit vom Generierungssystem:
|
||
#
|
||
# ASMOBJFORMAT: Ausgabeformat fuer den Assembler. Das Format muss dem
|
||
# jeweiligen Format des verwendeten C++ Compilers angepasst
|
||
# werde, damit gemischte Objektdateien gelinkt werden koennen.
|
||
# OBJDIR: Verzeichnis, in dem die Objektdateien abgelegt werden
|
||
# sollen.
|
||
# DEPDIR: Verzeichnis, in dem die Abhaengigkeitsdateien abgelegt werden
|
||
# sollen
|
||
# DRIVE_FD: Diskettenlaufwerk, auf das das System-Image geschrieben wird
|
||
# (Target: bootdisk)
|
||
# DRIVE_HD: Festplatten-/USB-Device, auf das das System-Image
|
||
# geschrieben wird (Target: bootdisk-hd)
|
||
# DELETE: Name des Kommandos zum Loeschen von Dateien
|
||
# ASM: Zu benutzender Assembler
|
||
# CC/CXX: Zu benutzender C/C++-Compiler
|
||
# CFLAGS: Flags fuer den C-Compileraufruf
|
||
# CXXFLAGS: Flags fuer den C++-Compileraufruf
|
||
# LD: Zu benutzender Linker
|
||
# LDFLAGS: Flags fuer den Linkeraufruf
|
||
# LDLIBS: Dazuzulinkende Bibliotheken
|
||
# LDHEAD: Am Anfang zu linkende Dateien
|
||
# LDTAIL: Am Ende zu linkende Dateien
|
||
# BOOT: Das Verzeichnis zu Bootsektor und Setup-Code
|
||
# TOOLS: Das Verzeichnis mit dem Build-Tool
|
||
|
||
VERBOSE = @
|
||
ASMOBJFORMAT = elf
|
||
OBJDIR = ./build
|
||
DEPDIR = ./dep
|
||
DRIVE_FD = /media/student/DATAUSB
|
||
# ACHTUNG: ein falsch angegebenes Laufwerk kann dazu fuehren, dass Daten auf dem
|
||
# spezifizierten Laufwerk verloren gehen! Nicht mit root-Rechten ausfuehren!
|
||
DRIVE_HD = /media/student/DATAUSB
|
||
DELETE = rm
|
||
ASM = nasm
|
||
CC ?= gcc
|
||
CXX ?= g++
|
||
GCCFLAGS ?= -mmanual-endbr -mpreferred-stack-boundary=2
|
||
|
||
# NOTE: Need -O0 to allow paging/bluescreen to work (We need the ebp on the stack)
|
||
# Fortify source needs -O2, at least O1
|
||
CFLAGS := $(CFLAGS) -O0 -m32 -march=i486 -Wall -fno-stack-protector -nostdlib -I. -g -ffreestanding -fno-pie -fno-pic -Wno-write-strings -mno-sse -mno-sse2 $(GCCFLAGS)
|
||
|
||
# NOTE: -std=c++17 for if constexpr and probably some other stuff
|
||
# -std=c++20 is needed for template concepts and optional references
|
||
CXXFLAGS := $(CFLAGS) -Wno-non-virtual-dtor -fno-threadsafe-statics -fno-use-cxa-atexit -fno-rtti -fno-exceptions -std=c++20
|
||
|
||
BOOT = ../boot
|
||
TOOLS = ../tools
|
||
# BIOS-dev.code:total-tracks:-heads:-sectors:start-track:-head:-sector
|
||
# Default-Werte fuer Boot von Floppy (USB/HD erkennt bootsect.asm selbst):
|
||
BOOTDEVICE = 0:80:2:18:0:0:1
|
||
|
||
# -------------------------------------------------------------------------
|
||
# Namen der Unterverzeichnisse mit den Quelltexten
|
||
|
||
VPATH = $(sort $(dir $(STARTUP_SOURCE) $(CC_SOURCES) $(C_SOURCES) $(ASM_SOURCES)))
|
||
|
||
# -------------------------------------------------------------------------
|
||
# Listen mit den Objektdateien, die beim Kompilieren entstehen:
|
||
|
||
FIRST_OBJECT = $(addprefix $(OBJDIR)/,$(patsubst %.asm,_%.o, $(notdir $(STARTUP_SOURCE))))
|
||
C_OBJECTS = $(notdir $(C_SOURCES:.c=.o))
|
||
CC_OBJECTS = $(notdir $(CC_SOURCES:.cc=.o))
|
||
|
||
DEP_FILES = $(patsubst %.o,$(DEPDIR)/%.d,$(C_OBJECTS))
|
||
DEP_FILES += $(patsubst %.o,$(DEPDIR)/%.d,$(CC_OBJECTS))
|
||
|
||
ASM_OBJECTS = $(patsubst %.asm,_%.o, $(notdir $(ASM_SOURCES)))
|
||
OBJPRE = $(addprefix $(OBJDIR)/,$(ASM_OBJECTS) $(C_OBJECTS) $(CC_OBJECTS))
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Default targets (einfaches Image, Image fuer USB Sticks, Image fuer VMWare
|
||
# und Boot CDs)
|
||
|
||
all: $(OBJDIR)/bootdisk.img $(OBJDIR)/bootdisk.vmi $(OBJDIR)/bootdisk-hd.vmi
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Regeln zur Erzeugung der Abhaengigkeitsdateien
|
||
|
||
$(DEPDIR)/%.d : %.c
|
||
@echo "DEP $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(CC) $(CFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
|
||
|
||
$(DEPDIR)/%.d : %.cc
|
||
@echo "DEP $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(CXX) $(CXXFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Regeln zur Erzeugung der Objektdateien
|
||
|
||
$(OBJDIR)/%.o : %.c
|
||
@echo "CC $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(CC) -c $(CFLAGS) -o $@ $<
|
||
|
||
$(OBJDIR)/%.o : %.cc
|
||
@echo "CXX $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(CXX) -c $(CXXFLAGS) -o $@ $<
|
||
|
||
$(OBJDIR)/_%.o : %.asm
|
||
@echo "ASM $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(ASM) -f $(ASMOBJFORMAT) -o $@ $<
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Gelinktes System
|
||
|
||
$(OBJDIR)/system: $(FIRST_OBJECT) $(OBJPRE)
|
||
@echo "LD $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(CXX) $(CXXFLAGS) -static -e startup -T sections -o $(OBJDIR)/system $(FIRST_OBJECT) $(OBJPRE)
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'system.img' enthaelt die zu ladenden Sections des eigentlichen Systems
|
||
|
||
$(OBJDIR)/system.img : $(OBJDIR)/system
|
||
@echo "OBJCOPY $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) objcopy -O binary $< $@
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'bootdisk.img' besteht aus dem 'system.img', das um den (parametrisierten)
|
||
# Bootblock und den Setup-Code erweitert wurde.
|
||
|
||
$(OBJDIR)/bootdisk.img : $(OBJDIR)/system.img $(TOOLS)/build $(BOOT)/bootsect $(BOOT)/setup
|
||
@echo "BUILD $@"
|
||
@if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
|
||
$(VERBOSE) $(TOOLS)/build $(BOOT)/bootsect $(BOOT)/setup $< $(BOOTDEVICE) $@
|
||
|
||
# 'bootdisk.vmi' ist eine bootdisk, die auf 1.44 MB mit 0 aufgefuellt ist,
|
||
# damit VMware damit klarkommt. Des weiteren wird dieses Image benoetigt, um
|
||
# bootfaehige CDs zu erstellen.
|
||
# bootdisk-hd.img wird auf etwa 1M mit 0 aufgefuellt, da qemu diese Groesse
|
||
# auf eine Festplatten-Laufwerkscharakteristik zurueckrechnen kann.
|
||
|
||
$(OBJDIR)/bootdisk.vmi: $(OBJDIR)/bootdisk.img
|
||
dd if=$< of=$@ bs=1474560 conv=sync
|
||
|
||
$(OBJDIR)/bootdisk-hd.vmi: $(OBJDIR)/bootdisk.img
|
||
dd if=$< of=$@ bs=$$((2016*512)) conv=sync
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'clean' loescht das generierte System, die Objektdateien und die
|
||
# Abhaengigkeitsdateien
|
||
|
||
clean:
|
||
@echo "RM $(OBJDIR)"
|
||
$(VERBOSE) rm -rf $(OBJDIR)
|
||
@echo "RM $(DEPDIR)"
|
||
$(VERBOSE) rm -rf $(DEPDIR)
|
||
$(MAKE) -C $(BOOT) clean
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'ast' erlaubt das betrachten des generierten template codes
|
||
ast:
|
||
clang++ -Xclang -ast-print -fsyntax-only $(f) | clang-format | bat -f -l cpp -P
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'bootdisk' erzeugt zunaechst das System, falls das noch nicht geschehen ist.
|
||
# Danach wird eine Bootdiskette mit dem System erzeugt.
|
||
|
||
bootdisk: $(OBJDIR)/bootdisk.img
|
||
@echo "CP $<"
|
||
$(VERBOSE) cp $< $(DRIVE_FD)
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'bootdisk-hd' erzeugt zunaechst das System, falls das noch nicht geschehen
|
||
# ist. Danach wird das System auf das spezifizierte Laufwerk geschrieben,
|
||
# welches sowohl eine Festplatte, als auch ein USB-Stick sein kann.
|
||
# ACHTUNG: ein falsch angegebenes Laufwerk kann dazu fuehren, dass Daten auf dem
|
||
# spezifizierten Laufwerk verloren gehen! Nicht mit root-Rechten ausfuehren!
|
||
|
||
bootdisk-usb: bootdisk-hd
|
||
bootdisk-hd: $(OBJDIR)/bootdisk.img
|
||
@echo "CP $<"
|
||
$(VERBOSE) cp $< $(DRIVE_HD)
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'qemu' ruft den qemu-Emulator mit dem System auf.
|
||
|
||
qemu: $(OBJDIR)/bootdisk.vmi
|
||
qemu-system-i386 -fda $(OBJDIR)/bootdisk.vmi -boot a -k en-us -soundhw pcspk -vga std -cpu 486 -serial stdio
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'qemu-gdb' ruft den qemu-Emulator mit aktiviertem GDB-Stub mit dem System
|
||
# auf, sodass es per GDB oder DDD inspiziert werden kann.
|
||
|
||
qemu-gdb: $(OBJDIR)/bootdisk.vmi
|
||
$(VERBOSE) echo "break main" > /tmp/gdbcommands.$(shell id -u)
|
||
$(VERBOSE) echo "target remote 127.0.0.1:1234" >> /tmp/gdbcommands.$(shell id -u)
|
||
$(VERBOSE) echo "continue" >> /tmp/gdbcommands.$(shell id -u)
|
||
qemu-system-i386 -fda $(OBJDIR)/bootdisk.vmi -boot a -k en-us -s -S -soundhw pcspk -vga std -cpu 486
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'gdb' startet den GDB-Debugger und verbindet sich mit dem GDB-Stub des vorher
|
||
# gestarteten Qemu.
|
||
|
||
gdb:
|
||
gdb -tui -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'ddd' startet den DDD-Debugger und verbindet sich mit dem GDB-Stub des vorher
|
||
# gestarteten Qemu.
|
||
|
||
ddd:
|
||
ddd --gdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
|
||
|
||
# --------------------------------------------------------------------------
|
||
# 'build'-Tool kompilieren.
|
||
|
||
$(TOOLS)/build: $(TOOLS)/build.c
|
||
cd $(TOOLS) && $(CC) -o $@ $<
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Bootsektor und Protected-Mode-Setup-Code kompilieren.
|
||
|
||
$(BOOT)/bootsect $(BOOT)/setup: $(BOOT)/bootsect.asm $(BOOT)/setup.asm
|
||
$(MAKE) -C $(BOOT)
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Einbindung der Abhaengigkeitsdateien
|
||
|
||
ifneq ($(MAKECMDGOALS),clean)
|
||
-include $(DEP_FILES)
|
||
endif
|
||
|
||
.PHONY: clean bootdisk bootdisk-hd bootdisk-usb gdb ddd
|