Handout
This commit is contained in:
146
tools/build.mk
Normal file
146
tools/build.mk
Normal file
@@ -0,0 +1,146 @@
|
||||
# Build the kernel
|
||||
|
||||
# Top Level Folder all generated files will be placed in.
|
||||
ROOTBUILDDIR = build
|
||||
# Folder the generated files will be placed in.
|
||||
BUILDDIR ?= $(ROOTBUILDDIR)
|
||||
# Build folder suffixes
|
||||
OPTTAG = opt
|
||||
NOOPTTAG = noopt
|
||||
DBGTAG = dbg
|
||||
VERBOSETAG = verbose
|
||||
|
||||
# C++
|
||||
CXX ?= $(PREFIX)clang++
|
||||
# on macos the default compiler is called c++, switch to clang++
|
||||
ifeq ($(shell uname),Darwin)
|
||||
ifeq ($(CXX),c++)
|
||||
CXX := clang++
|
||||
endif
|
||||
endif
|
||||
|
||||
CXXFLAGS_ARCH = -m64
|
||||
CXXFLAGS_DEFAULT = -std=c++23 -ffreestanding -fno-pic -nodefaultlibs -nostdlib -nostdinc -I. -fno-rtti -fno-exceptions -Wno-write-strings -fno-stack-protector -mno-red-zone -g -gdwarf-2 -fno-use-cxa-atexit -no-pie -nostartfiles
|
||||
# Enable 16-byte compare-and-exchange instruction for debugging purposes (stack alignment)
|
||||
CXXFLAGS_DEFAULT += -mcx16
|
||||
CXXFLAGS_OPT = -O3 -fomit-frame-pointer
|
||||
CXXFLAGS_WARNING = -Wall -Wextra -Werror -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-non-virtual-dtor
|
||||
CXXFLAGS_CLANG = -Wno-error=unused-private-field -Wno-implicit-exception-spec-mismatch -Wno-error=unused-const-variable -Wno-unused-command-line-argument -Wno-unused-const-variable -fno-strict-aliasing
|
||||
ifeq ($(shell uname),Darwin)
|
||||
CXXFLAGS_CLANG += -target x86_64-pc-linux-gnu -fuse-ld=lld
|
||||
endif
|
||||
CXXFLAGS_GCC = -fno-tree-loop-distribute-patterns -Wstack-usage=4096 -Wno-error=stack-usage=
|
||||
CXXFLAGS_NOFPU = -mno-mmx -mno-sse -mgeneral-regs-only
|
||||
CXXFLAGS = $(CXXFLAGS_ARCH) $(CXXFLAGS_DEFAULT) $(CXXFLAGS_OPT) $(CXXFLAGS_NOFPU) $(CXXFLAGS_WARNING)
|
||||
# Compiler specific flags
|
||||
ifneq (,$(findstring clang,$(CXX)))
|
||||
COMPILER := CLANG
|
||||
CXXFLAGS += $(CXXFLAGS_CLANG)
|
||||
else ifneq (,$(findstring g++,$(CXX)))
|
||||
COMPILER := GCC
|
||||
# g++ 6 does not support general-regs-only flag
|
||||
ifeq "$(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \<= 6)" "1"
|
||||
CXXFLAGS := $(filter-out -mgeneral-regs-only,$(CXXFLAGS))
|
||||
endif
|
||||
# Configures -Warray-bounds warning to allow accessing in the NULL page
|
||||
# Necessary to read the Extended BIOS Data Area at 0x40e
|
||||
ifeq "$(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 12)" "1"
|
||||
CXXFLAGS += --param=min-pagesize=0x40e
|
||||
endif
|
||||
CXXFLAGS += $(CXXFLAGS_GCC)
|
||||
else
|
||||
COMPILER :=
|
||||
endif
|
||||
|
||||
# Assembly
|
||||
ASM = nasm
|
||||
ASMFLAGS = -f elf64
|
||||
|
||||
# Additional build utilities
|
||||
# If llvm tools are available, use them
|
||||
ifneq (,$(shell which llvm-objcopy 2>/dev/null))
|
||||
PREFIX = llvm-
|
||||
endif
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
STRIP = $(PREFIX)strip
|
||||
AR = $(PREFIX)ar
|
||||
|
||||
# Subdirectories with sources
|
||||
VPATH = $(sort $(dir $(CC_SOURCES) $(ASM_SOURCES)))
|
||||
|
||||
# Lists of object files that are generated by compilation:
|
||||
# Note that the variables containing the input files are to be defined by
|
||||
# the Makefiles prior to including this common.mk.
|
||||
CC_OBJECTS = $(addprefix $(BUILDDIR)/,$(CC_SOURCES:.cc=.o))
|
||||
DEP_FILES = $(addprefix $(BUILDDIR)/,$(CC_SOURCES:.cc=.d) $(addsuffix .d,$(ASM_SOURCES)))
|
||||
ASM_OBJECTS = $(addprefix $(BUILDDIR)/,$(addsuffix .o,$(ASM_SOURCES)))
|
||||
|
||||
# Dependency files
|
||||
$(BUILDDIR)/%.d : %.cc $(MAKEFILE_LIST)
|
||||
@echo "DEP $<"
|
||||
@mkdir -p $(@D)
|
||||
$(VERBOSE) $(CXX) $(CXXFLAGS) -MM -MT $(BUILDDIR)/$*.o -MF $@ $<
|
||||
|
||||
$(BUILDDIR)/%.asm.d : %.asm $(MAKEFILE_LIST)
|
||||
@echo "DEP $<"
|
||||
@mkdir -p $(@D)
|
||||
$(VERBOSE) $(ASM) $(ASMFLAGS) -M -MT $(BUILDDIR)/$*.asm.o -MF $@ $<
|
||||
|
||||
# Object files
|
||||
$(BUILDDIR)/%.o : %.cc $(MAKEFILE_LIST)
|
||||
@echo "CXX $<"
|
||||
@mkdir -p $(@D)
|
||||
$(VERBOSE) $(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||
|
||||
$(BUILDDIR)/%.asm.o : %.asm $(MAKEFILE_LIST)
|
||||
@echo "ASM $<"
|
||||
@mkdir -p $(@D)
|
||||
$(VERBOSE) $(ASM) $(ASMFLAGS) -o $@ $<
|
||||
|
||||
# The standard target 'clean' removes the whole generated system, the object files, and the dependency files.
|
||||
clean::
|
||||
rm -rf "$(BUILDDIR)"
|
||||
|
||||
# Target issuing a nested call to make generating a fully optimized systems without assertions.
|
||||
%-$(OPTTAG):
|
||||
$(VERBOSE) $(MAKE) BUILDDIR="$(BUILDDIR)/$(OPTTAG)" ISODIR="$(ISODIR)/$(OPTTAG)" CXXFLAGS_OPT="-Ofast -fomit-frame-pointer -flto -march=westmere -DNDEBUG" $*
|
||||
|
||||
# Target issuing a nested call to make generating a non-optimized system.
|
||||
%-$(NOOPTTAG):
|
||||
$(VERBOSE) $(MAKE) BUILDDIR="$(BUILDDIR)/$(NOOPTTAG)" ISODIR="$(ISODIR)/$(NOOPTTAG)" CXXFLAGS_OPT="-O0" $*
|
||||
|
||||
# Target issuing a nested call to make generating a system optimized for debugging.
|
||||
%-$(DBGTAG):
|
||||
$(VERBOSE) $(MAKE) BUILDDIR="$(BUILDDIR)/$(DBGTAG)" ISODIR="$(ISODIR)/$(DBGTAG)" CXXFLAGS_OPT="-Og -fno-omit-frame-pointer" $*
|
||||
|
||||
# Target issuing a nested call to make generating a system with verbose output.
|
||||
%-$(VERBOSETAG):
|
||||
$(VERBOSE) $(MAKE) BUILDDIR="$(BUILDDIR)/$(VERBOSETAG)" ISODIR="$(ISODIR)/$(VERBOSETAG)" CXXFLAGS_OPT="-DVERBOSE" $*
|
||||
|
||||
# Documentation
|
||||
help::
|
||||
@$(echo) "" \
|
||||
"All targets exist in different flavours in addition to \e[2;3m<name>\e[0m:\n" \
|
||||
"\e[2;3m<name>\e[0;3m-noopt\e[0m, \e[2;3m<name>\e[0;3m-opt\e[0m, \e[2;3m<name>\e[0;3m-dbg\e[0m, and \e[2;3m<name>\e[0;3m-verbose\e[0m.\n" \
|
||||
"Targets suffixed with \e[3m-noopt\e[0m are compiled without optimizations,\n" \
|
||||
"\e[3m-opt\e[0m targets produce a highly optimized binary, while\n" \
|
||||
"\e[3m-dbg\e[0m targets only use optimizations not hindering debugging.\n" \
|
||||
"Targets suffixed with \e[3m-verbose\e[0m generate binaries including\n" \
|
||||
"verbose output (via \e[3mDBG_VERBOSE\e[0m), making such targets useful for debugging.\n" \
|
||||
"To get a verbose make output, clear VERBOSE, e.g. \e[3mmake VERBOSE=\e[0m.\n" \
|
||||
"The following targets are available (each target can be suffixed by \e[3m-noopt\e[0m\n" \
|
||||
"and \e[3m-verbose\e[0m):\n\n" \
|
||||
" \e[3mall\e[0m Builds $(PROJECT), generating an ELF binary\n\n"
|
||||
|
||||
# Print warnings, if appropriate
|
||||
ifeq (,$(COMPILER))
|
||||
$(warning Unknown (and potentially unsupported) compiler "$(CXX)"!)
|
||||
endif
|
||||
|
||||
# Include dependency files (generated via gcc flag -MM)
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(DEP_FILES)
|
||||
endif
|
||||
|
||||
# Phony targets
|
||||
.PHONY: clean help
|
||||
33
tools/common.mk
Normal file
33
tools/common.mk
Normal file
@@ -0,0 +1,33 @@
|
||||
# Common include Makefile
|
||||
|
||||
# Hide commands
|
||||
VERBOSE = @
|
||||
# Prefix for toolchain binaries
|
||||
PREFIX ?=
|
||||
# Project name
|
||||
PROJECT ?= "MPStuBS"
|
||||
|
||||
help::
|
||||
@$(echo) "\n" \
|
||||
"\e[1mMAKEFILE for the teaching operating system $(PROJECT)\e[0m\n" \
|
||||
"--------------------------------------------------\n\n" \
|
||||
"Executing '\e[4mmake\e[0m' will compile the operating system from source.\n"
|
||||
|
||||
# Get current directory path
|
||||
CURRENT_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
|
||||
# Include Makefile scripts
|
||||
include $(CURRENT_DIR)/build.mk
|
||||
include $(CURRENT_DIR)/qemu.mk
|
||||
include $(CURRENT_DIR)/image.mk
|
||||
include $(CURRENT_DIR)/linter.mk
|
||||
include $(CURRENT_DIR)/remote.mk
|
||||
|
||||
# Disable buitlin rules
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
||||
# Disable buitlin rules
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
# Disable buitlin suffixes
|
||||
.SUFFIXES:
|
||||
6771
tools/cpplint.py
vendored
Normal file
6771
tools/cpplint.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
96
tools/image.mk
Normal file
96
tools/image.mk
Normal file
@@ -0,0 +1,96 @@
|
||||
# Generates a bootable ISO image that can be transferred to external media, such as CDs or USB sticks.
|
||||
# This will install, in addition to your kernel, the bootloader GRUB (https://www.gnu.org/software/grub/).
|
||||
#
|
||||
# The target 'gemu-iso' is used to test the image generated with 'iso'.
|
||||
#
|
||||
# Assuming that a USB mass-storage devices is connected as, for instance /dev/sdc, the target 'usb-sdc'
|
||||
# can be used to make your device bootable (requires root access, substitute sdc with the matching device).
|
||||
# Alternatively, you can burn the .iso file directly to CD.
|
||||
|
||||
DD = dd
|
||||
XORRISO = xorriso
|
||||
MKISO = grub-mkrescue
|
||||
|
||||
ISODIR = $(BUILDDIR)-iso
|
||||
ISOGRUBCFG = boot/grub/grub.cfg
|
||||
ISOKERNEL = boot/kernel
|
||||
ISOINITRD = initrd
|
||||
GRUBTITLE = $(shell id -un)s $(PROJECT)
|
||||
GRUBTIMEOUT = 2
|
||||
GRUBBIN = /usr/lib/grub/i386-pc
|
||||
|
||||
# Default ISO target
|
||||
iso: $(ISOFILE)
|
||||
|
||||
# Create Grub config
|
||||
$(ISODIR)/$(ISOGRUBCFG):
|
||||
@echo "GEN $@"
|
||||
@mkdir -p $(dir $@)
|
||||
@$(echo) "set timeout=$(GRUBTIMEOUT)\nset default=0\n\nmenuentry \"$(GRUBTITLE)\" {\n\tmultiboot /$(ISOKERNEL)\n\tmodule /$(ISOINITRD)\n\tboot\n}" > $@
|
||||
|
||||
# Strip debug symbols from kernel binary
|
||||
$(ISODIR)/$(ISOKERNEL): all
|
||||
@echo "STRIP $@"
|
||||
@mkdir -p $(dir $@)
|
||||
$(VERBOSE) $(STRIP) --strip-debug --strip-unneeded -p -o $@ $(KERNEL)
|
||||
|
||||
# copy inital ramdisk
|
||||
$(ISODIR)/$(ISOINITRD): all
|
||||
@echo "CPY $@"
|
||||
@mkdir -p $(dir $@)
|
||||
@if [ -s $(INITRD) ] ; then cp -a $(INITRD) $@ ; else touch $@ ; fi
|
||||
|
||||
# Pack to ISO
|
||||
$(ISOFILE): $(ISODIR)/$(ISOKERNEL) $(ISODIR)/$(ISOINITRD) $(ISODIR)/$(ISOGRUBCFG)
|
||||
@echo "ISO $@"
|
||||
@which $(XORRISO) >/dev/null || echo "Xorriso cannot be found - if building the ISO fails, this may be the reason!" >&2
|
||||
$(VERBOSE) $(MKISO) -d $(GRUBBIN) -o $@ $(ISODIR)
|
||||
|
||||
# Run ISO in QEMU/KVM
|
||||
%-iso: $(ISOFILE)
|
||||
@${MAKE} -s QEMUKERNEL="-cdrom $<" $*
|
||||
|
||||
# Copy ISO to USB device
|
||||
usb: $(ISOFILE)
|
||||
ifeq (,$(USBDEV))
|
||||
@echo "The environment variable USBDEV must contain the path to the USB mass-storage device:" >&2
|
||||
@lsblk -o TYPE,KNAME,SIZE,MODEL -a -p | grep "^disk" | cut -b 6-
|
||||
@exit 1
|
||||
else
|
||||
$(VERBOSE) $(DD) if=$< of=$(USBDEV) bs=4M status=progress && sync
|
||||
endif
|
||||
|
||||
# Shorthand to copy ISO to a specific USB device
|
||||
usb-%:
|
||||
@$(MAKE) USBDEV=/dev/$* usb
|
||||
|
||||
# Burn ISO to CD
|
||||
cd: $(ISOFILE)
|
||||
ifeq (,$(CDRWDEV))
|
||||
@echo "The environment variable CDRWDEV must contain the path to the CD/DVD writer" >&2
|
||||
@exit 1
|
||||
else
|
||||
$(VERBOSE) $(XORRISO) -as cdrecord -v dev=$(CDRWDEV) -dao $<
|
||||
endif
|
||||
|
||||
# Shorthand to nurn ISO to specific CD device
|
||||
cd-%:
|
||||
@$(MAKE) CDRWDEV=/dev/$* cd
|
||||
|
||||
# The standard target 'clean' removes the whole generated system, the object files, and the dependency files.
|
||||
clean::
|
||||
@echo "RM $(ISODIR)"
|
||||
$(VERBOSE) rm -rf "$(ISODIR)" "$(ISODIR)$(OPTTAG)" "$(ISODIR)$(NOOPTTAG)" "$(ISODIR)$(DBGTAG)" "$(ISODIR)$(VERBOSETAG)"
|
||||
|
||||
# Documentation
|
||||
help::
|
||||
@$(echo) "Bootable Images\n" \
|
||||
" \e[3miso\e[0m Generates a bootable system image (File: $(ISOFILE))\n\n" \
|
||||
" \e[3m*-iso\e[0m Simulate the system by booting from the virtual CD drive. (e.g. qemu-iso)\n\n" \
|
||||
" \e[3musb\e[0m Generates a bootable USB mass-storage device; the environment\n" \
|
||||
" variable \e[4mUSBDEV\e[0m should point to the USB device\n\n" \
|
||||
" \e[3mcd\e[0m Generates a bootable CD; the environment variable \e[4mCDRWDEV\e[0m\n" \
|
||||
" should point to the CD writer\n\n"
|
||||
|
||||
# Phony targets
|
||||
.PHONY: iso cd usb help
|
||||
30
tools/linter.mk
Normal file
30
tools/linter.mk
Normal file
@@ -0,0 +1,30 @@
|
||||
# Perform static code checks
|
||||
|
||||
TIDY ?= clang-tidy
|
||||
CPPLINT ?= /usr/bin/env python "$(CURRENT_DIR)/cpplint.py"
|
||||
|
||||
# Check sources with Clang Tidy
|
||||
tidy::
|
||||
ifeq (,$(CC_SOURCES))
|
||||
@echo "(nothing to tidy)"
|
||||
else
|
||||
$(VERBOSE) $(TIDY) --format-style=google -header-filter=.* -warnings-as-errors="readability*" -checks="readability*,google-readability-casting,google-explicit-constructor,bugprone*,-bugprone-narrowing-conversions,-bugprone-reserved-identifier,-readability-else-after-return,-readability-magic-numbers" $(filter-out utils/png.cc,$(CC_SOURCES)) -- $(CXXFLAGS_ARCH) $(CXXFLAGS_DEFAULT) $(CXXFLAGS_OPT)
|
||||
endif
|
||||
|
||||
# Check sources with cpplint
|
||||
lint::
|
||||
@if $(CPPLINT) --quiet --recursive . ; then \
|
||||
echo "Congratuations, coding style obeyed!" ; \
|
||||
else \
|
||||
echo "Coding style violated -- see CPPLINT.cfg for details" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
|
||||
# Documentation
|
||||
help::
|
||||
@$(echo) "Static Analysis and Linter\n" \
|
||||
" \e[3mlint\e[0m Checks the coding style using \e[4mCPPLINT\e[0m\n\n" \
|
||||
" \e[3mtidy\e[0m Uses \e[4mClang Tidy\e[0m for a static code analysis\n\n"
|
||||
|
||||
# Phony targets
|
||||
.PHONY: tidy lint help
|
||||
111
tools/qemu.mk
Normal file
111
tools/qemu.mk
Normal file
@@ -0,0 +1,111 @@
|
||||
# Targets for running and debugging in Qemu/KVM
|
||||
|
||||
QEMUCPUS ?= 4
|
||||
INITRD ?= /dev/null
|
||||
|
||||
# Switch to curses if no graphical output is available
|
||||
ifeq ($(DISPLAY),)
|
||||
export QEMUDISPLAY ?= curses
|
||||
else
|
||||
# Macos display
|
||||
ifeq ($(shell uname),Darwin)
|
||||
export QEMUDISPLAY ?= cocoa
|
||||
else
|
||||
export QEMUDISPLAY ?= gtk
|
||||
endif
|
||||
endif
|
||||
|
||||
export QEMUEXTRAFLAGS ?=
|
||||
|
||||
# Architecture Specific flags
|
||||
QEMUFLAGS += -k en-us -machine pcspk-audiodev=pa -d guest_errors -m 2048
|
||||
# Macos sound
|
||||
ifeq ($(shell uname),Darwin)
|
||||
QEMUFLAGS += -audiodev coreaudio,id=pa
|
||||
else
|
||||
QEMUFLAGS += -audiodev pa,id=pa
|
||||
endif
|
||||
DBGKERNEL ?= $(KERNEL64)
|
||||
DBGARCH ?= i386:x86-64
|
||||
QEMU ?= qemu-system-x86_64
|
||||
QEMUKERNEL ?= -kernel $(KERNEL) -initrd $(INITRD)
|
||||
KVMFLAGS = -enable-kvm -cpu host
|
||||
QEMUDBGFLAGS = -no-shutdown -no-reboot
|
||||
|
||||
GDB = $(PREFIX)gdb
|
||||
ifneq ($(XDG_RUNTIME_DIR),)
|
||||
# We should prefer using domain sockets in a private directory
|
||||
GDBPORT ?= $(XDG_RUNTIME_DIR)/stubs-gdb.sock
|
||||
else
|
||||
# but fall back to PID + 1024, which should be an unprivileged unique port on single- and multiuser systems
|
||||
GDBPORT ?= :$(shell echo $$(($$(id -u) + 1024)))
|
||||
endif
|
||||
ifneq ($(findstring /,$(GDBPORT)),)
|
||||
QEMUGDB = -chardev socket,path=${GDBPORT},server=on,wait=off,id=gdb0 -gdb chardev:gdb0
|
||||
else
|
||||
QEMUGDB = -gdb tcp:${GDBPORT}
|
||||
endif
|
||||
# (gdb itself supports either :port or a path as target)
|
||||
|
||||
qemu: all
|
||||
@echo "QEMU ${KERNEL}"
|
||||
${VERBOSE} $(QEMU) $(QEMUKERNEL) $(QEMUGDB) -display ${QEMUDISPLAY} -smp $(QEMUCPUS) $(QEMUFLAGS) ${QEMUEXTRAFLAGS}
|
||||
|
||||
# Runs StuBS in Qemu with with hardware accelerations (KVM support) enabled
|
||||
# The started emulator provides several virtual CPUs that execute in parallel.
|
||||
kvm: all
|
||||
@echo "KVM ${KERNEL}"
|
||||
${VERBOSE} ${QEMU} $(QEMUKERNEL) $(QEMUGDB) -display ${QEMUDISPLAY} -smp $(QEMUCPUS) $(QEMUFLAGS) ${QEMUEXTRAFLAGS} $(KVMFLAGS)
|
||||
|
||||
# Execute Qemu with activated GDB stub and directly connect GDB to the spawned Qemu.
|
||||
gdb: all
|
||||
${VERBOSE} $(GDB) "$(DBGKERNEL)" \
|
||||
-ex "set arch $(DBGARCH)" \
|
||||
-ex "target remote | exec $(QEMU) -gdb stdio $(QEMUKERNEL) -smp $(QEMUCPUS) -S $(QEMUFLAGS) $(DBGFLAGS)"
|
||||
|
||||
################################################################
|
||||
# Rekursive Targets: Setzen einzelner QEMU Paramter
|
||||
################################################################
|
||||
|
||||
################################################################
|
||||
# Debugging mit GDB
|
||||
# Sinnvoll anwendbar mit den Targets: qemu, kvm, *-curses, *-serial
|
||||
%-gdb:
|
||||
${VERBOSE} ${MAKE} QEMUEXTRAFLAGS="${QEMUEXTRAFLAGS} -S" $*
|
||||
|
||||
# um sich mit GDB auf dem Standardport zu verbinden
|
||||
connect-gdb:
|
||||
${VERBOSE} gdb -ex "target remote ${GDBPORT}" $(DBGKERNEL)
|
||||
|
||||
################################################################
|
||||
# Eine -display Variante erzwingen
|
||||
%-curses:
|
||||
${VERBOSE} ${MAKE} QEMUDISPLAY="curses" QEMUSERIAL="vc:80Cx24C" $*
|
||||
|
||||
%-x11:
|
||||
${VERBOSE} ${MAKE} QEMUDISPLAY=gtk $*
|
||||
|
||||
################################################################
|
||||
# Serial-Ausgabe
|
||||
QEMUSERIAL ?= vc:80Cx24C
|
||||
QEMUFLAGS += -serial $(QEMUSERIAL)
|
||||
%-serial:
|
||||
@echo "HINT: C-a x: Terminate QEMU; C-a c: Open QEMU console"
|
||||
${VERBOSE} ${MAKE} QEMUSERIAL=mon:stdio $*
|
||||
|
||||
# Help for Qemu targets
|
||||
help::
|
||||
@$(echo) "System Emulation\n" \
|
||||
" \e[3mqemu\e[0m Starts $(PROJECT) in QEMU\n" \
|
||||
" Due to the internal design of QEMU, some things (especially\n" \
|
||||
" race conditions) might behave different compared to hardware!\n\n" \
|
||||
" \e[3mkvm\e[0m Starts $(PROJECT) in KVM, a hardware-accelerated virtual machine\n\n" \
|
||||
" \e[3m*-serial\e[0m Redirect the serial console to stdout (e.g., qemu-serial, kvm-serial)\n\n" \
|
||||
" \e[3m*-curses\e[0m Use QEMU's curses interface (e.g., qemu-curses).\n"\
|
||||
" \e[3m*-x11\e[0m Use QEMU's GTK interface (e.g., qemu-x11).\n\n"\
|
||||
" \e[3m*-gdb\e[0m Start Simulator with internal GDB stub and wait for a GDB\n" \
|
||||
" to attach. (e.g., qemu-gdb)\n" \
|
||||
" \e[3mconnect-gdb\e[0m Connect to waiting GDB. Execute in a second terminal!\n\n"\
|
||||
|
||||
# Phony targets
|
||||
.PHONY: qemu kvm help
|
||||
38
tools/remote.mk
Normal file
38
tools/remote.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
# Test your system on real hardware
|
||||
|
||||
NETBOOT_LOCAL="/ibr/adm/user-boot/"
|
||||
NETBOOT_HOST="x1.ibr.cs.tu-bs.de"
|
||||
|
||||
# The boot menu shows pairs of `vmlinuz-*` + `initrd-*.img` with owning user and timestamp.
|
||||
# We just need to choose a name that doesn't overlap with another user's.
|
||||
netboot: all
|
||||
$(VERBOSE) \
|
||||
if [ ! "$$DEPLOY_LOCAL" ] && [ -e "${NETBOOT_LOCAL}" ] ; then DEPLOY_LOCAL=1 ; fi ; \
|
||||
if [ "$$DEPLOY_LOCAL" = 1 ] ; then \
|
||||
user=$$USER ; \
|
||||
else \
|
||||
user=$$( ssh -G ${NETBOOT_HOST} | grep -oPe '^user \K.*' ) ; \
|
||||
fi ; \
|
||||
\
|
||||
mkdir -p $(BUILDDIR)/netboot ; \
|
||||
ln -fT ${KERNEL} $(BUILDDIR)/netboot/vmlinuz-$$user ; \
|
||||
initrd="$(INITRD)" ; if [ -s "$$initrd" ] ; then \
|
||||
ln -fT $$initrd $(BUILDDIR)/netboot/initrd-$$user.img ; \
|
||||
else \
|
||||
echo "(none)" > $(BUILDDIR)/netboot/initrd-$$user.img ; \
|
||||
fi ; \
|
||||
\
|
||||
if [ "$$DEPLOY_LOCAL" = 1 ] ; then \
|
||||
echo "CP to locally as $$user" ; \
|
||||
cp $(BUILDDIR)/netboot/vmlinuz-$$user $(BUILDDIR)/netboot/initrd-$$user.img ${NETBOOT_LOCAL} ; \
|
||||
else \
|
||||
echo "SCP to ${NETBOOT_HOST} as $$user" ; \
|
||||
scp $(BUILDDIR)/netboot/vmlinuz-$$user $(BUILDDIR)/netboot/initrd-$$user.img ${NETBOOT_HOST}:${NETBOOT_LOCAL} ; \
|
||||
fi
|
||||
|
||||
# Documentation
|
||||
help::
|
||||
@$(echo) "Netboot\n" \
|
||||
" \e[3mnetboot\e[0m Copies $(PROJECT) to the network share, allowing the test infrastructure\n" \
|
||||
" to boot your system"
|
||||
|
||||
Reference in New Issue
Block a user