Techwiki:Kd

From ReactOS Wiki
Jump to: navigation, search

The Kernel Debugging Protocol

The Kernel Debugging (KD) protocol is a low-level interface used by the kernel and the kernel debugger for hardware independent communication. It hides the hardware specific implementation of port communication and presents a uniform API for all types of ports.

This API is implemented in a separate DLL and there is one DLL for each type of port. The KD DLLO is given full control of the debug port. No one else is allowed to use it.


Initialization

KD initialization takes place early during boot, meaning the kernel debugger can connect early and troubleshoot boot issues. The KD DLL is responsible for reading command line settings*1*, performing hardware-specific initialization, and everything else required to set up the debug port. All of this is specific to the type of port used.

If the port is successfully initialized, STATUS_SUCCESS is returned. If initialization failed, an appropriate error status is returned. The kernel responds to failure by disabling the debugger.

TODO Do we rely on the command line settings to be correct? If not, do we verify them and fail if they are invalid, and return appropriate error code? If we do assume the settings to be correct, then what to do if the settings are actually wrong?


NTSTATUS
NTAPI
KdDebuggerInitialize0(
    PLOADER_PARAMETER_BLOCK LoaderBlock
);

Performs early initialization in phase 0. This usually consists of reading command line parameters from the loader block and initializing the port itself. If no loader block is provided, or if no settings are specified, then default settings are used.


NTSTATUS
NTAPI
KdDebuggerInitialize1(
    PLOADER_PARAMETER_BLOCK LoaderBlock
);

Performs initialization which could not be done during phase 0. Again, if no loader block is provided then default settings are used.


State Saving and Restoring

TODO What does "saving" and "restoring" mean, really? Can this fail? If so, then what to return? How does kernel respond? If not fail, then do we actually return NTSTATUS?


NTSTATUS
NTAPI
KdSave(
    BOOLEAN SleepTransition
);


Saves the debug port state before undergoing a transition.

SleepTransition If TRUE, this is a sleep transition. If FALSE, this is a hibernation transition.


NTSTATUS
NTAPI
KdRestore(
    BOOLEAN SleepTransition
);

Restores the debug port state

SleepTransition If TRUE, this is a sleep transition. If FALSE, this is a hibernation transition.


Power State Control

As the KD DLL is fully responsible for the debug port it must take care of the port's power state by itself.

TODO Can this fail? If so, what to return? And how does kernel respond? If not, do we actually return NTSTATUS?

NTSTATUS
NTAPI
KdD0Transition(
    VOID
);

Causes the debug port to undergo a D0 (fully on) transition.


NTSTATUS
NTAPI
KdD3Transition(
    VOID
);

Causes the debug port to undergo a D3 (fully off) transition.


Packet Communication

  • The most interesting part! Much to do!*

A KD dll exports 2 functions for communication across the debug port. What each function does vary greatly depending on the type of packet.

VOID
NTAPI
KdSendPacket(
    ULONG PacketType,
    PSTRING MessageHeader,
    PSTRING MessageData,
    PKD_CONTEXT Context
);

Sends a packet through the debug port.

KDSTATUS
NTAPI
KdReceivePacket(
    ULONG PacketType,
    PSTRING MessageHeader,
    PSTRING MessageData,
    PULONG DataLength,
    PKD_CONTEXT Context
);

Receives a packet from the debug port.


typedef enum _KDSTATUS
{
    KdPacketReceived,
    KdPacketTimedOut,
    KdPacketNeedsResend
} KDSTATUS;
typedef struct _STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PCHAR Buffer;
} STRING, *PSTRING;

Buffer can be one of many types of structures, depending on the type of packet. These structures in turn contain nested unions and even more flags, making a large number of possible structures.

typedef struct _KD_CONTEXT
{
    ULONG KdpDefaultRetries;
    BOOLEAN KdpControlCPending;
} KD_CONTEXT, *PKD_CONTEXT;

References