Makefile
This commit is contained in:
314
Makefile
Normal file
314
Makefile
Normal file
@@ -0,0 +1,314 @@
|
||||
#
|
||||
# Kurzanleitung
|
||||
# =============
|
||||
#
|
||||
# +++ General Targets +++
|
||||
#
|
||||
# make -- siehe -> make all
|
||||
#
|
||||
# make all -- Baut kernel.elf und generiert einen dump
|
||||
#
|
||||
# make install -- Baut kernel.img und transferiert ihn auf den Server.
|
||||
# Das Board holt sich diesen Kernel beim nächsten Reset.
|
||||
#
|
||||
# make qemu -- Baut den Kernel und führt ihn unter QEMU aus
|
||||
#
|
||||
# make qemu_debug -- Baut den Kernel und führt ihn unter QEMU mit debug
|
||||
# Optionen aus. Zum debuggen in einem zweiten Terminal
|
||||
# folgendes ausführen:
|
||||
# $ arm-none-eabi-gdb build/kernel.elf
|
||||
# $ target remote localhost:1234
|
||||
# make qemu_trace -- Wie qemu, gibt aber zusätzlich bei bestimmten MMIO-Zugriffen
|
||||
# Meldungen aus
|
||||
# make qemu_trace_mmu -- Wie qemu_trace, gibt aber nur Meldungen zur MMU aus
|
||||
#
|
||||
# make gdb -- Startet gdb und verbindet sich mit qemu
|
||||
#
|
||||
# make gdb_window -- Führt `make gdb` in einem neuen terminal aus
|
||||
#
|
||||
# make debug -- Führt qemu_debug gdb_window aus
|
||||
#
|
||||
# make clean -- Löscht alle erzeugten Dateien.
|
||||
#
|
||||
# make format -- Formatiert alle .c und .h Dateien im Stil von kernel.org
|
||||
#
|
||||
# make submission -- Verpackt alle Dateien die von git getrackt sind
|
||||
# Hierbei wird immer der Branch genutzt, der unter
|
||||
# SUBMISSION_BRANCH eingetragen ist.
|
||||
#
|
||||
# make home -- kopiert das fertige image nach $TFTP_PATH, für die
|
||||
# Arbeit zuhause einfach den Pfad eintragen
|
||||
#
|
||||
# +++ Single File Targets +++
|
||||
#
|
||||
# make kernel -- Baut kernel.elf im build Ordner
|
||||
#
|
||||
# make kernel.bin -- Baut kernel.bin im build Ordner
|
||||
#
|
||||
# make kernel.img -- Baut kernel.img im build Ordner
|
||||
#
|
||||
# make kernel_only -- Baut den kernel aber nur mit den Dateien aus SRC
|
||||
# Zum testen, ob der Kernel unabhängig kompiliert
|
||||
#
|
||||
# make user_only -- Baut nur die User Dateien aus USRC
|
||||
# Zum testen, ob Userland unabhängig kompiliert
|
||||
#
|
||||
# +++ Sonstiges +++
|
||||
#
|
||||
# MODE=strict make TARGET -- Baut TARGET mit allen Warnings, die GCC
|
||||
# -- unterstütz, sowie undefined behaviour sanitzers.
|
||||
# -- Baut nicht alles neu, d.h. im Zweifel zuerst
|
||||
# -- make clean ausführen.
|
||||
#
|
||||
# make qemu_record -- Erstellt eine "Aufnahme" einer Ausführung des OS.
|
||||
# Diese kann mit qemu_replay, qemu_debug_replay,
|
||||
# und debug_replay zum debugging abgespielt werden.
|
||||
# Dabei ist es dann in GDB möglich mit reverse-stepi
|
||||
# und reverse-continue "rückwärts" zu debuggen.
|
||||
|
||||
# Binäre Lsg (falls verwendet, ansonsten leer lassen)
|
||||
BIN_LSG =
|
||||
|
||||
# Hier eure source files hinzufügen
|
||||
SRC = arch/cpu/entry.S kernel/start.c arch/bsp/yellow_led.c lib/ubsan.c lib/mem.c
|
||||
|
||||
# Hier separate user source files hinzufügen
|
||||
USRC = user/main.c
|
||||
|
||||
# Hier können eigene GCC flags mit angegeben werden.
|
||||
# Die vorgegebenen Flags können weiter unten gefunden werden unter
|
||||
# CFLAGS_ALL und dürfen nicht verändert werden
|
||||
# Bsp: CFLAGS = -Wpedantic -Werror -O2
|
||||
CFLAGS = -std=gnu23
|
||||
|
||||
# 'strict' Modus
|
||||
ifeq ($(MODE), strict)
|
||||
CFLAGS_AVAIL = $(shell $(CC) -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n') $(CFLAGS_LAX)
|
||||
IGNORED_CFLAGS = -Wabi -Wc90-c99-compat -Wc99-c11-compat -Wc++-compat -Wtraditional \
|
||||
-Wtraditional-conversion -Wold-style-declaration -Wold-style-definition \
|
||||
-Wlong-long -Wdeclaration-after-statement -Wmain -Wswitch-default -Wstrict-flex-arrays \
|
||||
-Wsystem-headers
|
||||
CFLAGS_STRICT = $(filter-out $(IGNORED_CFLAGS), $(CFLAGS_AVAIL))
|
||||
|
||||
CFLAGS += $(CFLAGS_STRICT) -Werror
|
||||
CFLAGS += -fsanitize=undefined
|
||||
endif
|
||||
|
||||
# Gleiches gilt für Linkerflags, solltet ihr bspw. die libgcc mitlinken müssen
|
||||
LDFLAGS =
|
||||
|
||||
# Hier den git branch angeben, der für die Abgabe benutzt werden soll
|
||||
SUBMISSION_BRANCH = main
|
||||
|
||||
# Wenn ihr zuhause auf der Hardware arbeitet, hier das TFTP-Verzeichnis eintragen
|
||||
TFTP_PATH = /srv/tftp
|
||||
|
||||
# Standardinstallationspunkt der Toolchain
|
||||
-include config.mk
|
||||
|
||||
# Default if not defined in config.mk
|
||||
PREFIX ?= $(HOME)/Nextcloud/UNI/25-26_TI/BSP/arm
|
||||
|
||||
all:
|
||||
echo $(PREFIX)
|
||||
|
||||
# +-----------------------------------------------------+
|
||||
# | |
|
||||
# | Ab hier nichts mehr anpassen! Änderungen unter- |
|
||||
# | halb dieses Banners führen zu Punktabzug! |
|
||||
# | |
|
||||
# +-----------------------------------------------------+
|
||||
|
||||
# Source files, die fürs Testen einkompiliert werden.
|
||||
TSRC =
|
||||
SRC += $(TSRC)
|
||||
|
||||
# build directory
|
||||
BUILD_DIR = build
|
||||
|
||||
# separate kernel files and add build prefix
|
||||
KSRC_C = $(filter %.c, $(SRC))
|
||||
KSRC_S = $(filter %.S, $(SRC))
|
||||
KOBJ_C = $(addprefix $(BUILD_DIR)/,$(KSRC_C:%.c=%.o))
|
||||
KOBJ_S = $(addprefix $(BUILD_DIR)/,$(KSRC_S:%.S=%.o))
|
||||
KOBJ = $(KOBJ_C) $(KOBJ_S)
|
||||
|
||||
# separate user files and add build prefix
|
||||
USRC_C = $(filter %.c, $(USRC))
|
||||
USRC_S = $(filter %.S, $(USRC))
|
||||
UOBJ_C = $(addprefix $(BUILD_DIR)/,$(USRC_C:%.c=%.o))
|
||||
UOBJ_S = $(addprefix $(BUILD_DIR)/,$(USRC_S:%.S=%.o))
|
||||
UOBJ = $(UOBJ_C) $(UOBJ_S)
|
||||
|
||||
# accumulate
|
||||
OBJ_C = $(KOBJ_C) $(UOBJ_C)
|
||||
OBJ_S = $(KOBJ_S) $(UOBJ_S)
|
||||
OBJ = $(KOBJ) $(UOBJ)
|
||||
|
||||
# all header files
|
||||
HEADER_FILES = $$(find . -name '*.h')
|
||||
|
||||
# auto generated dep files
|
||||
DEP = $(OBJ:.o=.d)
|
||||
|
||||
# linker script
|
||||
LSCRIPT = kernel.lds
|
||||
|
||||
# static lib location for binary solution
|
||||
BIN_LSG_DIR = ./
|
||||
|
||||
# toolchain
|
||||
CC = $(PREFIX)/bin/arm-none-eabi-gcc
|
||||
LD = $(PREFIX)/bin/arm-none-eabi-ld
|
||||
OBJCOPY = $(PREFIX)/bin/arm-none-eabi-objcopy
|
||||
OBJDUMP = $(PREFIX)/bin/arm-none-eabi-objdump
|
||||
IMG = $(PREFIX)/bin/mkimage
|
||||
QEMU = $(PREFIX)/bin/qemu-system-arm
|
||||
QEMU_IMG = $(PREFIX)/bin/qemu-img
|
||||
GDB = $(PREFIX)/bin/arm-none-eabi-gdb
|
||||
FORMAT = $(PREFIX)/bin/clang-format
|
||||
|
||||
# configuration
|
||||
CFLAGS_ALL = -Wall -Wextra -ggdb -ffreestanding -mcpu=cortex-a7 -mfloat-abi=soft -mno-unaligned-access $(CFLAGS)
|
||||
CPPFLAGS = -Iinclude
|
||||
LDFLAGS += -T$(LSCRIPT) -nostdlib --fatal-warnings
|
||||
ifneq ($(BIN_LSG), )
|
||||
LDFLAGS += -L$(BIN_LSG_DIR) $(addprefix -l,$(BIN_LSG))
|
||||
endif
|
||||
OBJCOPYFLAGS = -Obinary -S --set-section-flags .bss=contents,alloc,load,data
|
||||
OBJDUMPFLAGS = -dfzh
|
||||
IMGFLAGS = -A arm -T standalone -C none -a 0x8000
|
||||
QEMUFLAGS = -M raspi2b -nographic -icount shift=9
|
||||
QEMU_REPLAY_FLAGS = -icount rrfile=$(BUILD_DIR)/replay.bin
|
||||
|
||||
FORMATFLAGS = --style="file:.clang-format" -i
|
||||
|
||||
# Regeln
|
||||
.PHONY: all
|
||||
|
||||
# default target
|
||||
all: kernel dump
|
||||
|
||||
# include auto generated targets
|
||||
-include $(DEP)
|
||||
|
||||
# single file targets
|
||||
$(OBJ_S):$(BUILD_DIR)/%.o: %.S
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS_ALL) -MMD -MP -o $@ -c $<
|
||||
|
||||
$(OBJ_C):$(BUILD_DIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS_ALL) -MMD -MP -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/kernel.elf: $(OBJ) $(LSCRIPT)
|
||||
ifneq ($(words $(OBJ)), $(words $(SRC) $(USRC)))
|
||||
@echo The number of objects files given to the linker does not match the\
|
||||
number of kernel and user files specified. Check your file extensions.; exit 1
|
||||
else
|
||||
$(LD) -o $@ $(wordlist 2,$(words $^),x $^) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
$(BUILD_DIR)/kernel.bin: $(BUILD_DIR)/kernel.elf
|
||||
$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
|
||||
|
||||
$(BUILD_DIR)/kernel.img: $(BUILD_DIR)/kernel.bin
|
||||
$(IMG) $(IMGFLAGS) -d $< $@
|
||||
|
||||
$(BUILD_DIR)/kernel_only.elf: $(KOBJ) $(LSCRIPT)
|
||||
$(LD) -o $@ $(wordlist 2,$(words $^),x $^) $(LDFLAGS)
|
||||
|
||||
$(BUILD_DIR)/user_only.elf: $(UOBJ) $(LSCRIPT)
|
||||
$(LD) -o $@ $(wordlist 2,$(words $^),x $^) $(LDFLAGS) --entry=0
|
||||
|
||||
$(BUILD_DIR)/kernel_dump.s: $(BUILD_DIR)/kernel.elf
|
||||
$(OBJDUMP) $(OBJDUMPFLAGS) $< > $@
|
||||
|
||||
# aliases
|
||||
.PHONY: dump kernel kernel.bin kernel.img kernel_only user_only
|
||||
dump: $(BUILD_DIR)/kernel_dump.s
|
||||
kernel: $(BUILD_DIR)/kernel.elf
|
||||
kernel.bin: $(BUILD_DIR)/kernel.bin
|
||||
kernel.img: $(BUILD_DIR)/kernel.img
|
||||
kernel_only: $(BUILD_DIR)/kernel_only.elf
|
||||
user_only: $(BUILD_DIR)/user_only.elf
|
||||
|
||||
# general targets
|
||||
.PHONY: install home qemu qemu_debug clean submission
|
||||
install: $(BUILD_DIR)/kernel.img
|
||||
arm-install-image $(BUILD_DIR)/kernel.img
|
||||
|
||||
home: $(BUILD_DIR)/kernel.img
|
||||
cp -v $(BUILD_DIR)/kernel.img $(TFTP_PATH)
|
||||
|
||||
$(BUILD_DIR)/vmstate.qcow2: $(BUILD_DIR)/kernel.elf
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(QEMU_IMG) create -f qcow2 $@ 32M
|
||||
|
||||
qemu: $(BUILD_DIR)/kernel.elf
|
||||
$(QEMU) $(QEMUFLAGS) -kernel $(BUILD_DIR)/kernel.elf
|
||||
|
||||
qemu_record: $(BUILD_DIR)/kernel.elf
|
||||
$(QEMU) $(QEMUFLAGS) $(QEMU_REPLAY_FLAGS) -icount rr=record -kernel $(BUILD_DIR)/kernel.elf
|
||||
|
||||
qemu_replay: $(BUILD_DIR)/kernel.elf $(BUILD_DIR)/replay.bin
|
||||
$(QEMU) $(QEMUFLAGS) $(QEMU_REPLAY_FLAGS) -icount rr=replay -kernel $(BUILD_DIR)/kernel.elf
|
||||
|
||||
qemu_debug: $(BUILD_DIR)/kernel.elf
|
||||
$(QEMU) $(QEMUFLAGS) -s -S -kernel $(BUILD_DIR)/kernel.elf
|
||||
|
||||
qemu_debug_replay: $(BUILD_DIR)/kernel.elf $(BUILD_DIR)/vmstate.qcow2 $(BUILD_DIR)/replay.bin
|
||||
$(QEMU) $(QEMUFLAGS) $(QEMU_REPLAY_FLAGS) -drive file=$(BUILD_DIR)/vmstate.qcow2,if=none,snapshot=on,id=img-direct -icount rr=replay -s -S -kernel $(BUILD_DIR)/kernel.elf
|
||||
|
||||
qemu_trace: $(BUILD_DIR)/kernel.elf
|
||||
$(QEMU) $(QEMUFLAGS) -d "trace:bcm283*,trace:pl011*" -kernel $<
|
||||
|
||||
qemu_trace_mmu: $(BUILD_DIR)/kernel.elf
|
||||
$(QEMU) $(QEMUFLAGS) -d "mmu" -kernel $<
|
||||
|
||||
gdb: $(BUILD_DIR)/kernel.elf
|
||||
$(GDB) --ex="target remote localhost:1234" --ex "set scheduler-locking on" $<
|
||||
|
||||
gdb_window: $(BUILD_DIR)/kernel.elf
|
||||
ifeq (, $(shell which x-terminal-emulator 2>/dev/null))
|
||||
@which $(TERM) || { echo "TERM not set properly, please do so, e.g. with 'export TERM=xterm'"; exit 1; }
|
||||
$(TERM) -e "bash -c 'make gdb; killall $(QEMU)'" &
|
||||
else
|
||||
x-terminal-emulator -e "make gdb; killall $(QEMU)" &
|
||||
endif
|
||||
|
||||
debug: gdb_window qemu_debug
|
||||
|
||||
debug_replay: gdb_window qemu_debug_replay
|
||||
|
||||
format:
|
||||
@$(FORMAT) $(FORMATFLAGS) $$(find . -name '*.c' -o -name '*.h')
|
||||
@echo "Finished reformatting code."
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
CURR_BRANCH = $(shell git branch --show-current 2> /dev/null)
|
||||
STATUS_BRANCH = "$(shell git status --porcelain 2> /dev/null)"
|
||||
|
||||
submission:
|
||||
ifneq ($(CURR_BRANCH), $(SUBMISSION_BRANCH))
|
||||
@echo "Refusing to create submission!"
|
||||
@echo "Current branch does not match submission branch."
|
||||
@echo " > Currently on branch: '$(CURR_BRANCH)'"
|
||||
@echo " > But registered submission branch is: '$(SUBMISSION_BRANCH)'"
|
||||
@echo "Please change branch or fix submission branch."
|
||||
@exit 1
|
||||
endif
|
||||
ifneq ($(STATUS_BRANCH), "")
|
||||
@echo "Refusing to create submission!"
|
||||
@echo "Submission branch is dirty or contains untracked files."
|
||||
@echo ""
|
||||
@echo "Please commit changes and add non essential files to '.gitignore'."
|
||||
@echo "Use 'git status' for a detailed list."
|
||||
@echo ""
|
||||
@exit 1
|
||||
endif
|
||||
git archive --format=tar.gz -o submission.tar.gz $(SUBMISSION_BRANCH)
|
||||
@echo Successfully created submission.tar.gz
|
||||
@echo We recommend testing archive before submitting it.
|
||||
Reference in New Issue
Block a user