diff --git a/.gitignore b/.gitignore index a6d348f..7f417a6 100644 --- a/.gitignore +++ b/.gitignore @@ -169,3 +169,4 @@ $RECYCLE.BIN/ build .clang-format .ccls-cache +socks.log diff --git a/Makefile b/Makefile index 2c7b451..1be4f69 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,9 @@ KERNEL_OBJ := $(addprefix $(BUILDDIR)/,$(KERNEL_C_FILES:.c=.o)) BUILD_ID := $(shell tools/generate_build_id.py --arch $(ARCH)) -CFLAGS := -DBUILD_ID=\"$(BUILD_ID)\" -ASMFLAGS := -DBUILD_ID=\"$(BUILD_ID)\" +CFLAGS := $(CFLAGS) -DBUILD_ID=\"$(BUILD_ID)\" -g +ASMFLAGS := $(ASMFLAGS) -DBUILD_ID=\"$(BUILD_ID)\" +LDFLAGS := $(LDFLAGS) -g $(BUILDDIR)/$(KERNEL_EXEC): $(KERNEL_OBJ) $(ARCH_OBJ) @echo " \033[1;36mLINK\033[0m \033[1m$@\033[0m" diff --git a/arch/x86_64/extra.mk b/arch/x86_64/extra.mk index 96054af..0b298bf 100644 --- a/arch/x86_64/extra.mk +++ b/arch/x86_64/extra.mk @@ -1,4 +1,5 @@ QEMU := qemu-system-x86_64 +QEMU_FLAGS := -m 64M -smp 4 ARCH_TEMP_FILES := $(BUILDDIR)/$(KERNEL_EXEC).elf32 @@ -16,8 +17,13 @@ run: $(BUILDDIR)/$(KERNEL_EXEC) $(BUILDDIR)/$(KERNEL_EXEC).elf32 @$(QEMU) -kernel $(BUILDDIR)/$(KERNEL_EXEC).elf32 debug: $(BUILDDIR)/$(KERNEL_EXEC) $(BUILDDIR)/$(KERNEL_EXEC).elf32 - @echo " \033[1;93mBOOT\033[0m $<" + @echo " \033[1;93mDEBUG\033[0m $<" + + @./tools/kernel-debug/debug_session.sh \ + tools/kernel-debug/gdb_session_init \ + tools/kernel-debug/lldb_session_init \ + $(QEMU) \ + -kernel $(BUILDDIR)/$(KERNEL_EXEC).elf32 -S -s \ + -curses -serial file:socks.log $(QEMU_FLAGS) + - @$(QEMU) \ - -kernel $(BUILDDIR)/$(KERNEL_EXEC).elf32 -S -s \ - -monitor stdio diff --git a/arch/x86_64/start_32.S b/arch/x86_64/start_32.S index bf5c524..2958500 100644 --- a/arch/x86_64/start_32.S +++ b/arch/x86_64/start_32.S @@ -55,7 +55,7 @@ bootstrap_pdpt: # a single PDPT bootstrap_pdir_buf: # a buffer of page directories. each pdir entry can be used to map 2MB of virtual memory. .skip BOOTSTRAP_PDIR_SIZE bootstrap_stack_bottom: - .skip 0x1000 + .skip 0x4000 bootstrap_stack_top: /******* @@ -260,7 +260,8 @@ long_mode_switch: _start: mov $bootstrap_stack_top, %esp - push %ebx # store the pointer to the multiboot info block. + push %ebx # store the pointer to the multiboot info block as a 64-bit value. + push $0x00 # store the pointer to the multiboot info block as a 64-bit value. # check if long mode is supported movl $0x80000000, %eax # Extended-function 80000000h. diff --git a/arch/x86_64/start_64.S b/arch/x86_64/start_64.S index d0bd140..6870ad2 100644 --- a/arch/x86_64/start_64.S +++ b/arch/x86_64/start_64.S @@ -1,5 +1,7 @@ .code64 +.extern kernel_init # defined in core/main.c + .section .boot.rodata, "a", @progbits /******* @@ -63,7 +65,11 @@ print_kernel_identifier: .type start_64, @function start_64: call vga_clear + + pop %rax call print_kernel_identifier + call kernel_init + cli hlt diff --git a/core/main.c b/core/main.c index 599bbeb..9afbfe1 100644 --- a/core/main.c +++ b/core/main.c @@ -1,4 +1,8 @@ -void kernel_init() -{ +#include +void kernel_init(uint64_t arg) +{ + uint8_t *vga = (uint8_t *)0xb8000; + *vga = 'A'; + *(vga + 1) = 0x0F; } diff --git a/tools/kernel-debug/debug_session.py b/tools/kernel-debug/debug_session.py new file mode 100755 index 0000000..843e734 --- /dev/null +++ b/tools/kernel-debug/debug_session.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +import sys +import os +import subprocess +import time +import signal + + +qemu_args = [] +gdb_args = [] +cur_program = '' + + +def run_process(args): + p = subprocess.Popen(args, + bufsize=1, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + while True: + retcode = p.poll() + line = p.stdout.read(1) + yield line + if retcode is not None: + break + + +for arg in sys.argv[1:]: + if arg == '--qemu': + cur_program = 'qemu' + continue + elif arg == '--gdb': + cur_program = 'gdb' + continue + + if cur_program == 'qemu': + qemu_args += [arg] + elif cur_program == 'gdb': + gdb_args += [arg] + else: + print('No program specified') + exit(-1) + +env = os.environ.copy() +signal.signal(signal.SIGINT, signal.SIG_IGN) +qemu = subprocess.Popen(qemu_args, + env=env, + start_new_session=True, + restore_signals=False) +time.sleep(1) + +if qemu.poll() is not None: + print('Failed to start QEMU') + exit(-1) + +subprocess.run(gdb_args, + env=env, + stdout=sys.stdout, + stdin=sys.stdin, + stderr=sys.stderr) +qemu.kill() diff --git a/tools/kernel-debug/debug_session.sh b/tools/kernel-debug/debug_session.sh new file mode 100755 index 0000000..653213c --- /dev/null +++ b/tools/kernel-debug/debug_session.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +gdb_cfg=$1 +lldb_cfg=$2 +shift 2 + +if command -v gdb &> /dev/null; then + tmux \ + new-session -d -s hz-debug "sleep 0.3; gdb -tui -x $gdb_cfg" \; \ + split-window -h -l 80 \; \ + split-window -v -l 25 "$@"\; \ + select-pane -t 0 +elif command -v lldb &> /dev/null; then + tmux \ + new-session -d -s hz-debug "sleep 0.1; lldb --source $lldb_cfg" \; \ + split-window -h -l 80 \; \ + split-window -v -l 25 "$@"\; \ + select-pane -t 0 +else + echo "No debugger available" + exit -1 +fi + +tmux a -t hz-debug +tmux kill-session -t hz-debug + diff --git a/tools/kernel-debug/gdb_session_init b/tools/kernel-debug/gdb_session_init new file mode 100644 index 0000000..0481960 --- /dev/null +++ b/tools/kernel-debug/gdb_session_init @@ -0,0 +1,4 @@ +set confirm off +symbol-file build/socks_kernel +target remote localhost:1234 +set confirm on diff --git a/tools/kernel-debug/lldb_session_init b/tools/kernel-debug/lldb_session_init new file mode 100644 index 0000000..0a275e8 --- /dev/null +++ b/tools/kernel-debug/lldb_session_init @@ -0,0 +1,2 @@ +file build/socks_kernel +gdb-remote localhost:1234 diff --git a/tools/make/gcc-cross-compile.mk b/tools/make/gcc-cross-compile.mk index 164f733..9dc8b30 100644 --- a/tools/make/gcc-cross-compile.mk +++ b/tools/make/gcc-cross-compile.mk @@ -2,7 +2,7 @@ LD := $(ARCH)-elf-gcc CC := $(ARCH)-elf-gcc ASM := $(ARCH)-elf-gcc -CFLAGS := -nostdlib -nostdinc -ffreestanding -Wl,-nostdlib +CFLAGS := -ffreestanding -nostdlib ASMFLAGS := $(CFLAGS) LDFLAGS := -nostdlib