# 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