Impossible OS Docs

Kernel Debugger (KD Protocol)

What is it?

The kernel debugger (KD) is a planned WinDbg-compatible debug stub that would let a second machine attach over serial and control a live kernel: set breakpoints, read and write memory and registers, single-step, and inspect a crash without a reboot-and-guess cycle. The stub itself does not exist yet. What does exist is the serial driver it would talk through and an exception-dispatch hook shaped for it; this page describes both and links the open roadmap sections.

How does it work?

serial.c is a polling COM driver: serial_putchar()/serial_write() transmit, serial_trygetchar() reads one byte without blocking, and an abort-safe emergency write path underneath them serves panic-time output. There is no receive interrupt, no receive ring buffer and no packet framing. serial_init() programs the UART with divisor 0, which keeps whatever baud rate the firmware already set rather than forcing one, and serial_adopt_boot_info() later adopts the bootloader-reported I/O port but deliberately not a reported baud rate, leaving the line-rate decision to the roadmap's serial-line section.

The exception path already has the debugger slot NT puts there. except.h declares KI_DEBUG_ROUTINE, a callback called first-chance and second-chance for kernel-mode exceptions, and ki_set_debug_routine(), which publishes or detaches it with an atomic release store. In except.c the kernel-mode order is: debugger first chance, then the kernel __try/__except walk in ki_raise_kernel_exception(), then debugger second chance, then KeBugCheckExFrame(), the frame-carrying bugcheck that skips the Registry write. The callback defaults to NULL and only the exception unit tests register one, so today the notification is skipped and an unhandled kernel fault goes straight on to the bugcheck. #DB (vector 1) and #BP (vector 3) are already routed: except_init() installs except_common_handler on them through idt_register_handler() (idt.c), mapping them to STATUS_SINGLE_STEP and STATUS_BREAKPOINT, so a kernel INT3 enters exception dispatch and can be caught by kernel SEH. What is missing is a debugger behind them: with no callback registered, an unhandled breakpoint goes on to the bugcheck.

There is no src/kernel/kd/ directory, no KD packet type, no connection state and no breakpoint table anywhere in the tree.

What are its interfaces?

Interface Purpose
serial_putchar(), serial_write(), serial_trygetchar() COM transmit and single-byte poll receive (serial.h)
serial_init(), serial_adopt_boot_info() Early UART bring-up and post-handoff port (not baud) adoption
idt_register_handler(), idt_register_handler_quiet() Generic IDT vector hook installation (idt.h)
KI_DEBUG_ROUTINE, ki_set_debug_routine() The first-chance and second-chance kernel debugger callback slot, NULL by default (except.h)
ki_dispatch_exception(), ki_raise_kernel_exception() The fault dispatcher that consults the slot, and the kernel SEH walk it falls through to

How do I use it?

There is nothing to attach to yet: no kddebug= boot argument, no HKLM\SYSTEM\KernelDebugger key and no kd_init() exist, so neither WinDbg nor any other debugger can connect. Debugging today means the serial log and the panic screen described in Panic Screen and Crash Experience, plus unit tests of the dispatch path:

bash scripts/test.sh SUITE=except   # exception dispatch and kernel SEH suites

What is not implemented yet?

How does it compare with Windows 11 and Linux?

Windows ships WinDbg over KD on serial, network (KDNET) and USB, with breakpoints, register and memory access and a module list; Linux offers the same through kgdb (a GDB remote stub) and the kdb shell. Impossible OS has neither today. It has already matched one structural piece of Windows: the kernel exception dispatcher gives a debugger first-chance and second-chance notification exactly where NT's KiDebugRoutine sits, so the stub has a defined place to plug in. The roadmap targets WinDbg's wire protocol rather than GDB's.

See also

Impossible OS is free software under the GPL-3.0-only license. Last updated Edit this page on GitHub