Table of Contents
The kernel debugger is organized into a number of components:
The debug core
The debug core is found in kernel/debugger/debug_core.c. It contains:
A generic OS exception handler which includes sync'ing the processors into a stopped state on an multi-CPU system.
The API to talk to the kgdb I/O drivers
The API to make calls to the arch-specific kgdb implementation
The logic to perform safe memory reads and writes to memory while using the debugger
A full implementation for software breakpoints unless overridden by the arch
The API to invoke either the kdb or kgdb frontend to the debug core.
The structures and callback API for atomic kernel mode setting.
NOTE: kgdboc is where the kms callbacks are invoked.
kgdb arch-specific implementation
This implementation is generally found in arch/*/kernel/kgdb.c. As an example, arch/x86/kernel/kgdb.c contains the specifics to implement HW breakpoint as well as the initialization to dynamically register and unregister for the trap handlers on this architecture. The arch-specific portion implements:
contains an arch-specific trap catcher which invokes kgdb_handle_exception() to start kgdb about doing its work
translation to and from gdb specific packet format to pt_regs
Registration and unregistration of architecture specific trap hooks
Any special exception handling and cleanup
NMI exception handling and cleanup
(optional)HW breakpoints
gdbstub frontend (aka kgdb)
The gdbstub is located in kernel/debug/gdbstub.c. It contains:
All the logic to implement the gdb serial protocol
kdb frontend
The kdb debugger shell is broken down into a number of components. The kdb core is located in kernel/debug/kdb. There are a number of helper functions in some of the other kernel components to make it possible for kdb to examine and report information about the kernel without taking locks that could cause a kernel deadlock. The kdb core contains implements the following functionality.
A simple shell
The kdb core command set
A registration API to register additional kdb shell commands.
A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c
The implementation for kdb_printf() which emits messages directly to I/O drivers, bypassing the kernel log.
SW / HW breakpoint management for the kdb shell
kgdb I/O driver
Each kgdb I/O driver has to provide an implementation for the following:
configuration via built-in or module
dynamic configuration and kgdb hook registration calls
read and write character interface
A cleanup handler for unconfiguring from the kgdb core
(optional) Early debug methodology
Any given kgdb I/O driver has to operate very closely with the hardware and must do it in such a way that does not enable interrupts or change other parts of the system context without completely restoring them. The kgdb core will repeatedly "poll" a kgdb I/O driver for characters when it needs input. The I/O driver is expected to return immediately if there is no data available. Doing so allows for the future possibility to touch watch dog hardware in such a way as to have a target system not reset when these are enabled.
If you are intent on adding kgdb architecture specific support
for a new architecture, the architecture should define
HAVE_ARCH_KGDB
in the architecture specific
Kconfig file. This will enable kgdb for the architecture, and
at that point you must create an architecture specific kgdb
implementation.
There are a few flags which must be set on every architecture in their <asm/kgdb.h> file. These are:
NUMREGBYTES: The size in bytes of all of the registers, so that we can ensure they will all fit into a packet.
BUFMAX: The size in bytes of the buffer GDB will read into. This must be larger than NUMREGBYTES.
CACHE_FLUSH_IS_SAFE: Set to 1 if it is always safe to call flush_cache_range or flush_icache_range. On some architectures, these functions may not be safe to call on SMP since we keep other CPUs in a holding pattern.
There are also the following functions for the common backend, found in kernel/kgdb.c, that must be supplied by the architecture-specific backend unless marked as (optional), in which case a default function maybe used if the architecture does not need to provide a specific implementation.