diff --git a/boards/qemu-i386/Makefile.include b/boards/qemu-i386/Makefile.include index 85db0b12a200c380268f86c044efeb5fd14c4d0a..1413f9b392b486295a63bb06194e4c677dcca3c4 100644 --- a/boards/qemu-i386/Makefile.include +++ b/boards/qemu-i386/Makefile.include @@ -3,5 +3,24 @@ include $(RIOTBOARD)/x86-multiboot-common/Makefile.include CFLAGS += -march=i686 -mtune=i686 CFLAGS += -I$(RIOTBOARD)/qemu-i386/include -TERMPROG = qemu-system-i386 -m 512m -serial stdio -nographic -monitor /dev/null -kernel $(BINDIR)/$(APPLICATION).hex +TERMPROG = exec $(RIOTBOARD)/qemu-i386/dist/term.py "qemu-system-i386 -m 512m" $(BINDIRBASE) $(HEXFILE) + FLASHER = true + +DEBUGGER = $(TERMPROG) + +all: + +debug-kdbg: DEBUGGER_FLAGS="kdbg -r :1234 -- $(ELFFILE)" +debug-kdbg: debug + +debug-ddd: DEBUGGER_FLAGS="ddd --eval-command='target remote :1234' $(ELFFILE)" +debug-ddd: debug + +debug-tui: DEBUGGER_FLAGS="x-terminal-emulator -e gdb -ex 'target remote :1234' -tui --args $(ELFFILE)" +debug-tui: debug + +debug-gdb: debug +DEBUGGER_FLAGS = "x-terminal-emulator -e gdb -ex 'target remote :1234' --args $(ELFFILE)" + +debug: diff --git a/boards/qemu-i386/dist/term.py b/boards/qemu-i386/dist/term.py new file mode 100755 index 0000000000000000000000000000000000000000..b5c3404bd162856377dbc43b50c424c2a042a064 --- /dev/null +++ b/boards/qemu-i386/dist/term.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import readline +import socket +import signal +import subprocess +import sys +import threading + +from datetime import datetime +from distutils.util import split_quoted +from time import time + + +def get_timestamp(): + return datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S.%f') + +def popen(args, **kw): + null = open(os.devnull, 'wb', 0) + return subprocess.Popen(args, stdin=null, stdout=null, stderr=null, **kw) + +def main(QEMU, BINDIRBASE, HEXFILE, DEBUGGER=None): + def run_shell(): + nonlocal result + while 1: + try: + line = input() + if line == 'quit': + result = 0 + raise EOFError() + except EOFError: + qemu.kill() + return + client_file.write((line + '\r\n').encode('UTF-8')) + + def read_terminal(): + for line in client_file: + print('{}: {}'.format(get_timestamp(), line.decode('UTF-8', 'replace').rstrip("\r\n"))) + + if isinstance(QEMU, str): + QEMU = split_quoted(QEMU) + if DEBUGGER and isinstance(DEBUGGER, str): + DEBUGGER = split_quoted(DEBUGGER) + + histfile = os.path.join(BINDIRBASE, '.qemu-term.hist') + try: + readline.read_history_file(histfile) + except IOError: + pass + + result = 1 + try: + sock = socket.socket() + sock.settimeout(5) + sock.bind(('', 0)) + sock.listen(1) + host, port = sock.getsockname() + + args = QEMU + [ + '-serial', 'tcp:{}:{}'.format(host, port), + '-nographic', + '-monitor', '/dev/null', + '-kernel', HEXFILE, + ] + if DEBUGGER: + args += ['-s', '-S'] + + try: + qemu = popen(args) + + if DEBUGGER: + ignore_sig_int = lambda: signal.signal(signal.SIGINT, signal.SIG_IGN) + popen(DEBUGGER, preexec_fn=ignore_sig_int) + + client_sock, _ = sock.accept() + client_file = client_sock.makefile('rwb', 1) + sock.close() + + threading.Thread(target=run_shell, daemon=True).start() + threading.Thread(target=read_terminal, daemon=True).start() + + try: + result = qemu.wait() and result + except KeyboardInterrupt: + print('Interrupted ...') + result = 0 + finally: + try: + qemu.kill() + except: + pass + finally: + try: + readline.write_history_file(histfile) + except: + pass + + try: + client_sock.close() + except: + pass + return result + + +if __name__ == '__main__': + print("Type 'exit' to exit.") + sys.exit(main(*sys.argv[1:])) diff --git a/boards/x86-multiboot-common/Makefile.include b/boards/x86-multiboot-common/Makefile.include index 87937b1c4dcf68fe9ed7908962480daf994b1e67..f868a6bb95d4fb74c3fa8624b12d6b6dfebb9e5c 100644 --- a/boards/x86-multiboot-common/Makefile.include +++ b/boards/x86-multiboot-common/Makefile.include @@ -55,12 +55,18 @@ export OFLAGS = -O binary LINKFLAGS += -m32 -nostdlib -nostdinc -nostartfiles -nodefaultlibs \ --prefix=$(NEWLIB_BASE) \ -Wl,-rpath,$(NEWLIB_BASE)/lib \ - -T $(RIOTBASE)/boards/x86-multiboot-common/linker.ld + -T$(RIOTBASE)/boards/x86-multiboot-common/linker.ld UNDEF += $(BINDIR)x86-multiboot-common_base/startup.o -#CFLAGS += -ffunction-sections -fdata-sections -#LINKFLAGS += -Wl,--gc-sections -#CFLAGS += -Wall -Wextra -Werror -pedantic -pedantic-errors \ - BASELIBS += $(NEWLIB_BASE)/lib/libc.a \ $(NEWLIB_BASE)/lib/libm.a + +all: + +all-debug: export CFLAGS += -ggdb3 -O0 +all-debug: all + +ifeq (, $(filter all-debug, $(MAKECMDGOALS))) + CFLAGS += -Os -ffunction-sections -fdata-sections + LINKFLAGS += -Wl,--gc-sections +endif diff --git a/boards/x86-multiboot-common/linker.ld b/boards/x86-multiboot-common/linker.ld index 2a9f0a2a8523bdcb980b3764c31771cb79a057d4..e6e1fb08b9105b1045ac91e128f17976369d9408 100644 --- a/boards/x86-multiboot-common/linker.ld +++ b/boards/x86-multiboot-common/linker.ld @@ -34,7 +34,7 @@ SECTIONS Next we'll put the .text section. */ ._multiboot_header : { - *(._multiboot_header) + KEEP(*(._multiboot_header)) } .note.gnu.build-id :