** WIP ** Ensure proper port parameter overriding retrieval in case the debugger gets enabled not at boot, but later at runtime

This commit is contained in:
Hermès Bélusca-Maïto 2024-12-10 22:20:42 +01:00
parent 4753dbe661
commit 47dd86037d
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
9 changed files with 356 additions and 228 deletions

View file

@ -148,6 +148,112 @@ KdpPortInitialize(IN ULONG ComPortNumber,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**
* @brief
* Loads port parameters from the Loader Parameter Block, if available.
**/
static NTSTATUS
KdpRetrieveParameters(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{
static BOOLEAN AreParamsRetrieved = FALSE;
PSTR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
KDDBGPRINT("%s(%p)\n", __FUNCTION__, LoaderBlock);
/* Load parameters only once if they haven't been already */
if (AreParamsRetrieved)
return STATUS_SUCCESS;
AreParamsRetrieved = TRUE;
/* Check if we have a loader block, and if not, attempt to use the
* system one. If it's unavailable (post phase-1 init), just return. */
if (!LoaderBlock)
LoaderBlock = KeLoaderBlock;
if (!LoaderBlock)
return STATUS_SUCCESS;
/* Check if we have a command line */
CommandLine = LoaderBlock->LoadOptions;
if (!CommandLine)
return STATUS_SUCCESS;
/* Upcase it */
_strupr(CommandLine);
/* Check if we got the /DEBUGPORT parameter */
PortString = strstr(CommandLine, "DEBUGPORT");
if (PortString)
{
/* Move past the actual string, to reach the port*/
PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*PortString == ' ') PortString++;
PortString++;
/* Do we have a serial port? */
if (strncmp(PortString, "COM", 3) != 0)
{
return STATUS_INVALID_PARAMETER;
}
/* Check for a valid Serial Port */
PortString += 3;
Value = atol(PortString);
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
{
return STATUS_INVALID_PARAMETER;
}
/* Set the port to use */
ComPortNumber = Value;
}
/* Check if we got a baud rate */
BaudString = strstr(CommandLine, "BAUDRATE");
if (BaudString)
{
/* Move past the actual string, to reach the rate */
BaudString += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudString == ' ') BaudString++;
/* And make sure we have a rate */
if (*BaudString)
{
/* Read and set it */
Value = atol(BaudString + 1);
if (Value) ComPortBaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
IrqString = strstr(CommandLine, "IRQ");
if (IrqString)
{
/* Move past the actual string, to reach the rate */
IrqString += strlen("IRQ");
/* Now get past any spaces */
while (*IrqString == ' ') IrqString++;
/* And make sure we have an IRQ */
if (*IrqString)
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) ComPortIrq = Value;
}
}
return STATUS_SUCCESS;
}
/** /**
* @brief * @brief
* Phase 0 initialization. Invoked by KdInitSystem() when the debugger * Phase 0 initialization. Invoked by KdInitSystem() when the debugger
@ -165,88 +271,18 @@ KdDebuggerInitialize0(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
NTSTATUS Status; NTSTATUS Status;
PCHAR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
/* Check if we have a LoaderBlock */ #ifdef KDDEBUG
if (LoaderBlock) CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[/*ComPort*/4]), /*DEFAULT_BAUD_RATE*/115200);
{ #endif
/* Get the Command Line */ KDDBGPRINT("KdDebuggerInitialize0\n");
CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */ /* Capture the parameters if this is the first invocation */
_strupr(CommandLine); Status = KdpRetrieveParameters(LoaderBlock);
if (!NT_SUCCESS(Status))
/* Get the port and baud rate */ return Status; // Or, keep using the default parameters?
PortString = strstr(CommandLine, "DEBUGPORT");
BaudString = strstr(CommandLine, "BAUDRATE");
IrqString = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */
if (PortString)
{
/* Move past the actual string, to reach the port*/
PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*PortString == ' ') PortString++;
PortString++;
/* Do we have a serial port? */
if (strncmp(PortString, "COM", 3) != 0)
{
return STATUS_INVALID_PARAMETER;
}
/* Check for a valid Serial Port */
PortString += 3;
Value = atol(PortString);
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
{
return STATUS_INVALID_PARAMETER;
}
/* Set the port to use */
ComPortNumber = Value;
}
/* Check if we got a baud rate */
if (BaudString)
{
/* Move past the actual string, to reach the rate */
BaudString += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudString == ' ') BaudString++;
/* And make sure we have a rate */
if (*BaudString)
{
/* Read and set it */
Value = atol(BaudString + 1);
if (Value) ComPortBaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (IrqString)
{
/* Move past the actual string, to reach the rate */
IrqString += strlen("IRQ");
/* Now get past any spaces */
while (*IrqString == ' ') IrqString++;
/* And make sure we have an IRQ */
if (*IrqString)
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) ComPortIrq = Value;
}
}
}
#if 0
#ifdef KDDEBUG #ifdef KDDEBUG
/* /*
* Try to find a free COM port and use it as the KD debugging port. * Try to find a free COM port and use it as the KD debugging port.
@ -269,9 +305,10 @@ KdDebuggerInitialize0(
if (ComPort != 0) if (ComPort != 0)
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE); CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
} }
#endif
#endif #endif
KDDBGPRINT("KdDebuggerInitialize0\n"); //KDDBGPRINT("KdDebuggerInitialize0\n");
/* Initialize the port */ /* Initialize the port */
Status = KdpPortInitialize(ComPortNumber, ComPortBaudRate); Status = KdpPortInitialize(ComPortNumber, ComPortBaudRate);
@ -299,6 +336,21 @@ NTAPI
KdDebuggerInitialize1( KdDebuggerInitialize1(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
NTSTATUS Status;
#ifdef KDDEBUG
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[/*ComPort*/4]), /*DEFAULT_BAUD_RATE*/115200);
#endif
KDDBGPRINT("KdDebuggerInitialize1\n");
/* Capture the parameters if KdDebuggerInitialize0() wasn't invoked already */
Status = KdpRetrieveParameters(LoaderBlock);
if (!NT_SUCCESS(Status))
return Status; // Or, keep using the default parameters?
// TODO: If we already have a MMIO COM port,
// map it in memory and update KdComPortInUse.
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -13,7 +13,7 @@
#include <ntifs.h> #include <ntifs.h>
#include <windbgkd.h> #include <windbgkd.h>
// #define KDDEBUG /* uncomment to enable debugging this dll */ #define KDDEBUG /* uncomment to enable debugging this dll */
#ifndef KDDEBUG #ifndef KDDEBUG
#define KDDBGPRINT(...) #define KDDBGPRINT(...)

View file

@ -141,6 +141,110 @@ KdpPortInitialize(IN ULONG ComPortNumber,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**
* @brief
* Loads port parameters from the Loader Parameter Block, if available.
**/
static NTSTATUS
KdpRetrieveParameters(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{
static BOOLEAN AreParamsRetrieved = FALSE;
PSTR CommandLine, PortString, BaudString, IrqString;
ULONG Value;
/* Load parameters only once if they haven't been already */
if (AreParamsRetrieved)
return STATUS_SUCCESS;
AreParamsRetrieved = TRUE;
/* Check if we have a loader block, and if not, attempt to use the
* system one. If it's unavailable (post phase-1 init), just return. */
if (!LoaderBlock)
LoaderBlock = KeLoaderBlock;
if (!LoaderBlock)
return STATUS_SUCCESS;
/* Check if we have a command line */
CommandLine = LoaderBlock->LoadOptions;
if (!CommandLine)
return STATUS_SUCCESS;
/* Upcase it */
_strupr(CommandLine);
/* Check if we got the /DEBUGPORT parameter */
PortString = strstr(CommandLine, "DEBUGPORT");
if (PortString)
{
/* Move past the actual string, to reach the port*/
PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*PortString == ' ') PortString++;
PortString++;
/* Do we have a serial port? */
if (strncmp(PortString, "COM", 3) != 0)
{
return STATUS_INVALID_PARAMETER;
}
/* Check for a valid Serial Port */
PortString += 3;
Value = atol(PortString);
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
{
return STATUS_INVALID_PARAMETER;
}
/* Set the port to use */
ComPortNumber = Value;
}
/* Check if we got a baud rate */
BaudString = strstr(CommandLine, "BAUDRATE");
if (BaudString)
{
/* Move past the actual string, to reach the rate */
BaudString += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudString == ' ') BaudString++;
/* And make sure we have a rate */
if (*BaudString)
{
/* Read and set it */
Value = atol(BaudString + 1);
if (Value) ComPortBaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
IrqString = strstr(CommandLine, "IRQ");
if (IrqString)
{
/* Move past the actual string, to reach the rate */
IrqString += strlen("IRQ");
/* Now get past any spaces */
while (*IrqString == ' ') IrqString++;
/* And make sure we have an IRQ */
if (*IrqString)
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) ComPortIrq = Value;
}
}
return STATUS_SUCCESS;
}
/** /**
* @brief * @brief
* Phase 0 initialization. Invoked by KdInitSystem() when the debugger * Phase 0 initialization. Invoked by KdInitSystem() when the debugger
@ -157,87 +261,12 @@ NTAPI
KdDebuggerInitialize0( KdDebuggerInitialize0(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PCHAR CommandLine, PortString, BaudString, IrqString; NTSTATUS Status;
ULONG Value;
/* Check if we have a LoaderBlock */ /* Capture the parameters if this is the first invocation */
if (LoaderBlock) Status = KdpRetrieveParameters(LoaderBlock);
{ if (!NT_SUCCESS(Status))
/* Get the Command Line */ return Status; // Or, keep using the default parameters?
CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */
_strupr(CommandLine);
/* Get the port and baud rate */
PortString = strstr(CommandLine, "DEBUGPORT");
BaudString = strstr(CommandLine, "BAUDRATE");
IrqString = strstr(CommandLine, "IRQ");
/* Check if we got the /DEBUGPORT parameter */
if (PortString)
{
/* Move past the actual string, to reach the port*/
PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*PortString == ' ') PortString++;
PortString++;
/* Do we have a serial port? */
if (strncmp(PortString, "COM", 3) != 0)
{
return STATUS_INVALID_PARAMETER;
}
/* Check for a valid Serial Port */
PortString += 3;
Value = atol(PortString);
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
{
return STATUS_INVALID_PARAMETER;
}
/* Set the port to use */
ComPortNumber = Value;
}
/* Check if we got a baud rate */
if (BaudString)
{
/* Move past the actual string, to reach the rate */
BaudString += strlen("BAUDRATE");
/* Now get past any spaces */
while (*BaudString == ' ') BaudString++;
/* And make sure we have a rate */
if (*BaudString)
{
/* Read and set it */
Value = atol(BaudString + 1);
if (Value) ComPortBaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (IrqString)
{
/* Move past the actual string, to reach the rate */
IrqString += strlen("IRQ");
/* Now get past any spaces */
while (*IrqString == ' ') IrqString++;
/* And make sure we have an IRQ */
if (*IrqString)
{
/* Read and set it */
Value = atol(IrqString + 1);
if (Value) ComPortIrq = Value;
}
}
}
#ifdef KDDEBUG #ifdef KDDEBUG
/* /*
@ -282,6 +311,16 @@ NTAPI
KdDebuggerInitialize1( KdDebuggerInitialize1(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
NTSTATUS Status;
/* Capture the parameters if KdDebuggerInitialize0() wasn't invoked already */
Status = KdpRetrieveParameters(LoaderBlock);
if (!NT_SUCCESS(Status))
return Status; // Or, keep using the default parameters?
// TODO: If we already have a MMIO COM port,
// map it in memory and update KdComPortInUse.
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -8,7 +8,7 @@ typedef
NTSTATUS NTSTATUS
(NTAPI *PKDP_INIT_ROUTINE)( (NTAPI *PKDP_INIT_ROUTINE)(
_In_ struct _KD_DISPATCH_TABLE *DispatchTable, _In_ struct _KD_DISPATCH_TABLE *DispatchTable,
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
typedef typedef
VOID VOID
@ -55,19 +55,19 @@ NTSTATUS
NTAPI NTAPI
KdpScreenInit( KdpScreenInit(
_In_ struct _KD_DISPATCH_TABLE *DispatchTable, _In_ struct _KD_DISPATCH_TABLE *DispatchTable,
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
NTSTATUS NTSTATUS
NTAPI NTAPI
KdpSerialInit( KdpSerialInit(
_In_ struct _KD_DISPATCH_TABLE *DispatchTable, _In_ struct _KD_DISPATCH_TABLE *DispatchTable,
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
NTSTATUS NTSTATUS
NTAPI NTAPI
KdpDebugLogInit( KdpDebugLogInit(
_In_ struct _KD_DISPATCH_TABLE *DispatchTable, _In_ struct _KD_DISPATCH_TABLE *DispatchTable,
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
#ifdef KDBG #ifdef KDBG
#define KdpKdbgInit KdbInitialize #define KdpKdbgInit KdbInitialize

View file

@ -57,6 +57,8 @@ PKDP_INIT_ROUTINE InitRoutines[KdMax] =
#endif #endif
}; };
extern void KdDbgPortPrintf(PCSTR Format, ...);
/* LOCKING FUNCTIONS *********************************************************/ /* LOCKING FUNCTIONS *********************************************************/
KIRQL KIRQL
@ -196,23 +198,27 @@ NTSTATUS
NTAPI NTAPI
KdpDebugLogInit( KdpDebugLogInit(
_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ PKD_DISPATCH_TABLE DispatchTable,
_In_ ULONG BootPhase) _In_ ULONG InitPhase)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
if (!KdpDebugMode.File) if (!KdpDebugMode.File)
return STATUS_PORT_DISCONNECTED; return STATUS_PORT_DISCONNECTED;
if (BootPhase == 0) KdDbgPortPrintf("%s(%d)\n", __FUNCTION__, InitPhase);
if (InitPhase == 0)
{ {
/////// ENABLING PORT ///////
/* Write out the functions that we support for now */ /* Write out the functions that we support for now */
DispatchTable->KdpPrintRoutine = KdpPrintToLogFile; DispatchTable->KdpPrintRoutine = KdpPrintToLogFile;
/////////////////////////////
/* Register for BootPhase 1 initialization and as a Provider */ /* Register for InitPhase 1 initialization and as a Provider */
DispatchTable->KdpInitRoutine = KdpDebugLogInit; DispatchTable->KdpInitRoutine = KdpDebugLogInit;
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
} }
else if (BootPhase == 1) else if (InitPhase == 1)
{ {
/* Allocate a buffer for debug log */ /* Allocate a buffer for debug log */
KdpDebugBuffer = ExAllocatePoolZero(NonPagedPool, KdpDebugBuffer = ExAllocatePoolZero(NonPagedPool,
@ -229,13 +235,13 @@ KdpDebugLogInit(
/* Initialize spinlock */ /* Initialize spinlock */
KeInitializeSpinLock(&KdpDebugLogSpinLock); KeInitializeSpinLock(&KdpDebugLogSpinLock);
/* Register for later BootPhase 2 reinitialization */ /* Register for later InitPhase 2 reinitialization */
DispatchTable->KdpInitRoutine = KdpDebugLogInit; DispatchTable->KdpInitRoutine = KdpDebugLogInit;
/* Announce ourselves */ /* Announce ourselves */
HalDisplayString(" File log debugging enabled\r\n"); HalDisplayString(" File log debugging enabled\r\n");
} }
else if (BootPhase >= 2) else if (InitPhase >= 2)
{ {
UNICODE_STRING FileName; UNICODE_STRING FileName;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
@ -323,6 +329,7 @@ KdpDebugLogInit(
KeInitializeEvent(&KdpLoggerThreadEvent, SynchronizationEvent, TRUE); KeInitializeEvent(&KdpLoggerThreadEvent, SynchronizationEvent, TRUE);
/////// ENABLING PORT ///////
/* Create the logger thread */ /* Create the logger thread */
Status = PsCreateSystemThread(&ThreadHandle, Status = PsCreateSystemThread(&ThreadHandle,
THREAD_ALL_ACCESS, THREAD_ALL_ACCESS,
@ -345,6 +352,7 @@ KdpDebugLogInit(
sizeof(Priority)); sizeof(Priority));
ZwClose(ThreadHandle); ZwClose(ThreadHandle);
/////////////////////////////
return Status; return Status;
Failure: Failure:
@ -391,13 +399,16 @@ NTSTATUS
NTAPI NTAPI
KdpSerialInit( KdpSerialInit(
_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ PKD_DISPATCH_TABLE DispatchTable,
_In_ ULONG BootPhase) _In_ ULONG InitPhase)
{ {
if (!KdpDebugMode.Serial) if (!KdpDebugMode.Serial)
return STATUS_PORT_DISCONNECTED; return STATUS_PORT_DISCONNECTED;
if (BootPhase == 0) KdDbgPortPrintf("%s(%d)\n", __FUNCTION__, InitPhase);
if (InitPhase == 0)
{ {
/////// ENABLING PORT ///////
/* Write out the functions that we support for now */ /* Write out the functions that we support for now */
DispatchTable->KdpPrintRoutine = KdpSerialPrint; DispatchTable->KdpPrintRoutine = KdpSerialPrint;
@ -408,15 +419,16 @@ KdpSerialInit(
return STATUS_DEVICE_DOES_NOT_EXIST; return STATUS_DEVICE_DOES_NOT_EXIST;
} }
KdComPortInUse = SerialPortInfo.Address; KdComPortInUse = SerialPortInfo.Address;
/////////////////////////////
/* Initialize spinlock */ /* Initialize spinlock */
KeInitializeSpinLock(&KdpSerialSpinLock); KeInitializeSpinLock(&KdpSerialSpinLock);
/* Register for BootPhase 1 initialization and as a Provider */ /* Register for InitPhase 1 initialization and as a Provider */
DispatchTable->KdpInitRoutine = KdpSerialInit; DispatchTable->KdpInitRoutine = KdpSerialInit;
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
} }
else if (BootPhase == 1) else if (InitPhase == 1)
{ {
/* Announce ourselves */ /* Announce ourselves */
HalDisplayString(" Serial debugging enabled\r\n"); HalDisplayString(" Serial debugging enabled\r\n");
@ -514,24 +526,30 @@ NTSTATUS
NTAPI NTAPI
KdpScreenInit( KdpScreenInit(
_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ PKD_DISPATCH_TABLE DispatchTable,
_In_ ULONG BootPhase) _In_ ULONG InitPhase)
{ {
if (!KdpDebugMode.Screen) if (!KdpDebugMode.Screen)
return STATUS_PORT_DISCONNECTED; return STATUS_PORT_DISCONNECTED;
if (BootPhase == 0) KdDbgPortPrintf("%s(%d)\n", __FUNCTION__, InitPhase);
if (InitPhase == 0)
{ {
/////// ENABLING PORT ///////
/* Write out the functions that we support for now */ /* Write out the functions that we support for now */
DispatchTable->KdpPrintRoutine = KdpScreenPrint; DispatchTable->KdpPrintRoutine = KdpScreenPrint;
/////////////////////////////
/* Register for BootPhase 1 initialization and as a Provider */ /* Register for InitPhase 1 initialization and as a Provider */
DispatchTable->KdpInitRoutine = KdpScreenInit; DispatchTable->KdpInitRoutine = KdpScreenInit;
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
} }
else if (BootPhase == 1) else if (InitPhase == 1)
{ {
/////// ENABLING PORT ///////
/* Take control of the display */ /* Take control of the display */
KdpScreenAcquire(); KdpScreenAcquire();
/////////////////////////////
/* Announce ourselves */ /* Announce ourselves */
HalDisplayString(" Screen debugging enabled\r\n"); HalDisplayString(" Screen debugging enabled\r\n");

View file

@ -117,44 +117,51 @@ NTAPI
KdDebuggerInitialize0( KdDebuggerInitialize0(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock) _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PCHAR CommandLine, Port = NULL; // static BOOLEAN AreParamsRetrieved = FALSE;
ULONG i; ULONG i;
BOOLEAN Success = FALSE; BOOLEAN Success = FALSE;
KdDbgPortPrintf("%s(0x%p)\n", __FUNCTION__, LoaderBlock); KdDbgPortPrintf("%s(0x%p)\n", __FUNCTION__, LoaderBlock);
if (LoaderBlock) /* Check if we have a loader block, and if not, attempt to use the
* system one. If it's unavailable (post phase-1 init), just return. */
if (!LoaderBlock)
LoaderBlock = KeLoaderBlock;
// if (!LoaderBlock)
// return STATUS_SUCCESS;
/* Check if we have a command line */
if (LoaderBlock && LoaderBlock->LoadOptions)
{ {
/* Check if we have a command line */ PSTR CommandLine, Port = NULL;
CommandLine = LoaderBlock->LoadOptions; CommandLine = LoaderBlock->LoadOptions;
if (CommandLine) // if (!CommandLine)
// return STATUS_SUCCESS;
/* Upcase it */
_strupr(CommandLine);
/* Get terminal settings */
KdpGetTerminalSettings(CommandLine);
/* Check if we got the /DEBUGPORT parameter(s) */
Port = strstr(CommandLine, "DEBUGPORT");
while (Port)
{ {
/* Upcase it */ /* Move past the actual string, to reach the port*/
_strupr(CommandLine); Port += sizeof("DEBUGPORT") - 1;
/* Get terminal settings */ /* Now get past any spaces and skip the equal sign */
KdpGetTerminalSettings(CommandLine); while (*Port == ' ') Port++;
Port++;
/* Get the port */ /* Get the debug mode and wrapper */
Port = strstr(CommandLine, "DEBUGPORT"); Port = KdpGetDebugMode(Port);
Port = strstr(Port, "DEBUGPORT");
} }
} }
/* Check if we got the /DEBUGPORT parameter(s) */
while (Port)
{
/* Move past the actual string, to reach the port*/
Port += sizeof("DEBUGPORT") - 1;
/* Now get past any spaces and skip the equal sign */
while (*Port == ' ') Port++;
Port++;
/* Get the debug mode and wrapper */
Port = KdpGetDebugMode(Port);
Port = strstr(Port, "DEBUGPORT");
}
/* Use serial port then */ /* Use serial port then */
if (KdpDebugMode.Value == 0) if (KdpDebugMode.Value == 0)
KdpDebugMode.Serial = TRUE; KdpDebugMode.Serial = TRUE;
@ -188,13 +195,13 @@ KdpDriverReinit(
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable; PKD_DISPATCH_TABLE CurrentTable;
PKDP_INIT_ROUTINE KdpInitRoutine; PKDP_INIT_ROUTINE KdpInitRoutine;
ULONG BootPhase = (Count + 1); // Do BootPhase >= 2 ULONG InitPhase = (Count + 1); // Do InitPhase >= 2
BOOLEAN ScheduleReinit = FALSE; BOOLEAN ScheduleReinit = FALSE;
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
DPRINT("*** KD %sREINITIALIZATION - Phase %d ***\n", DPRINT("*** KD %sREINITIALIZATION - Phase %d ***\n",
Context ? "" : "BOOT ", BootPhase); Context ? "" : "BOOT ", InitPhase);
/* Call the registered providers */ /* Call the registered providers */
for (CurrentEntry = KdProviders.Flink; for (CurrentEntry = KdProviders.Flink;
@ -213,7 +220,7 @@ KdpDriverReinit(
/* Get the initialization routine and reset it */ /* Get the initialization routine and reset it */
KdpInitRoutine = CurrentTable->KdpInitRoutine; KdpInitRoutine = CurrentTable->KdpInitRoutine;
CurrentTable->KdpInitRoutine = NULL; CurrentTable->KdpInitRoutine = NULL;
CurrentTable->InitStatus = KdpInitRoutine(CurrentTable, BootPhase); CurrentTable->InitStatus = KdpInitRoutine(CurrentTable, InitPhase);
DPRINT("KdpInitRoutine(%p) returned 0x%08lx\n", DPRINT("KdpInitRoutine(%p) returned 0x%08lx\n",
CurrentTable, CurrentTable->InitStatus); CurrentTable, CurrentTable->InitStatus);
@ -340,6 +347,12 @@ KdDebuggerInitialize1(
KdDbgPortPrintf("%s(0x%p)\n", __FUNCTION__, LoaderBlock); KdDbgPortPrintf("%s(0x%p)\n", __FUNCTION__, LoaderBlock);
//
// TODO: If Init phase 0 wasn't invoked (because the debugger started
// in a disabled state), we need to invoke it there right now, but
// without enabling the corresponding debug ports.
//
/* Make space for the displayed providers' signons */ /* Make space for the displayed providers' signons */
HalDisplayString("\r\n"); HalDisplayString("\r\n");
@ -449,7 +462,7 @@ KdDbgPortPrintf("%s(0x%p)\n", __FUNCTION__, LoaderBlock);
* Once the KdpDriverEntry() driver entrypoint is called, we register * Once the KdpDriverEntry() driver entrypoint is called, we register
* KdpDriverReinit() for re-initialization with the I/O Manager, in order * KdpDriverReinit() for re-initialization with the I/O Manager, in order
* to provide more initialization points. KdpDriverReinit() calls the KD * to provide more initialization points. KdpDriverReinit() calls the KD
* providers at BootPhase >= 2, and schedules further reinitializations * providers at InitPhase >= 2, and schedules further reinitializations
* (at most 3 more) if any of the providers request so. * (at most 3 more) if any of the providers request so.
**/ **/
orgHalInitPnpDriver = orgHalInitPnpDriver =

View file

@ -97,7 +97,7 @@ NTSTATUS
NTAPI NTAPI
KdbInitialize( KdbInitialize(
_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ PKD_DISPATCH_TABLE DispatchTable,
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
BOOLEAN BOOLEAN
NTAPI NTAPI
@ -188,7 +188,7 @@ KdbSymProcessSymbols(
BOOLEAN BOOLEAN
KdbSymInit( KdbSymInit(
_In_ ULONG BootPhase); _In_ ULONG InitPhase);
/* from kdb.c */ /* from kdb.c */

View file

@ -3537,13 +3537,15 @@ KdbDebugPrint(
* debug strings before they will be wiped over by next writes. */ * debug strings before they will be wiped over by next writes. */
} }
extern void KdDbgPortPrintf(PCSTR Format, ...);
/** /**
* @brief Initializes the KDBG debugger. * @brief Initializes the KDBG debugger.
* *
* @param[in] DispatchTable * @param[in] DispatchTable
* Pointer to the KD dispatch table. * Pointer to the KD dispatch table.
* *
* @param[in] BootPhase * @param[in] InitPhase
* Phase of initialization. * Phase of initialization.
* *
* @return A status value. * @return A status value.
@ -3553,15 +3555,19 @@ NTSTATUS
NTAPI NTAPI
KdbInitialize( KdbInitialize(
_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ PKD_DISPATCH_TABLE DispatchTable,
_In_ ULONG BootPhase) _In_ ULONG InitPhase)
{ {
/* Saves the different symbol-loading status across boot phases */ /* Saves the different symbol-loading status across boot phases */
static ULONG LoadSymbols = 0; static ULONG LoadSymbols = 0;
if (BootPhase == 0) KdDbgPortPrintf("%s(%d)\n", __FUNCTION__, InitPhase);
if (InitPhase == 0)
{ {
/////// ENABLING PORT ///////
/* Write out the functions that we support for now */ /* Write out the functions that we support for now */
DispatchTable->KdpPrintRoutine = KdbDebugPrint; DispatchTable->KdpPrintRoutine = KdbDebugPrint;
/////////////////////////////
/* Check if we have a command line */ /* Check if we have a command line */
if (KeLoaderBlock && KeLoaderBlock->LoadOptions) if (KeLoaderBlock && KeLoaderBlock->LoadOptions)
@ -3570,13 +3576,13 @@ KdbInitialize(
KdbpGetCommandLineSettings(KeLoaderBlock->LoadOptions); KdbpGetCommandLineSettings(KeLoaderBlock->LoadOptions);
} }
/* Register for BootPhase 1 initialization and as a Provider */ /* Register for InitPhase 1 initialization and as a Provider */
DispatchTable->KdpInitRoutine = KdbInitialize; DispatchTable->KdpInitRoutine = KdbInitialize;
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
} }
else if (BootPhase == 1) else if (InitPhase == 1)
{ {
/* Register for later BootPhase 2 reinitialization */ /* Register for later InitPhase 2 reinitialization */
DispatchTable->KdpInitRoutine = KdbInitialize; DispatchTable->KdpInitRoutine = KdbInitialize;
/* Initialize Dmesg support */ /* Initialize Dmesg support */
@ -3594,14 +3600,14 @@ KdbInitialize(
KeInitializeSpinLock(&KdpDmesgLogSpinLock); KeInitializeSpinLock(&KdpDmesgLogSpinLock);
} }
/* Initialize symbols support in BootPhase 0 and 1 */ /* Initialize symbols support in InitPhase 0 and 1 */
if (BootPhase <= 1) if (InitPhase <= 1)
{ {
LoadSymbols <<= 1; LoadSymbols <<= 1;
LoadSymbols |= KdbSymInit(BootPhase); LoadSymbols |= KdbSymInit(InitPhase);
} }
if (BootPhase == 1) if (InitPhase == 1)
{ {
/* Announce ourselves */ /* Announce ourselves */
CHAR buffer[60]; CHAR buffer[60];
@ -3613,7 +3619,7 @@ KdbInitialize(
HalDisplayString(buffer); HalDisplayString(buffer);
} }
if (BootPhase >= 2) if (InitPhase >= 2)
{ {
/* I/O is now set up for disk access: load the KDBinit file */ /* I/O is now set up for disk access: load the KDBinit file */
NTSTATUS Status = KdbpCliInit(); NTSTATUS Status = KdbpCliInit();

View file

@ -333,23 +333,23 @@ KdbSymProcessSymbols(
/** /**
* @brief Initializes the KDB symbols implementation. * @brief Initializes the KDB symbols implementation.
* *
* @param[in] BootPhase * @param[in] InitPhase
* Phase of initialization. * Phase of initialization.
* *
* @return * @return
* TRUE if symbols are to be loaded at this given BootPhase; FALSE if not. * TRUE if symbols are to be loaded at this given InitPhase; FALSE if not.
**/ **/
BOOLEAN BOOLEAN
KdbSymInit( KdbSymInit(
_In_ ULONG BootPhase) _In_ ULONG InitPhase)
{ {
#if 1 // FIXME: This is a workaround HACK!! #if 1 // FIXME: This is a workaround HACK!!
static BOOLEAN OrigLoadSymbols = FALSE; static BOOLEAN OrigLoadSymbols = FALSE;
#endif #endif
DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase); DPRINT("KdbSymInit() InitPhase=%d\n", InitPhase);
if (BootPhase == 0) if (InitPhase == 0)
{ {
PSTR CommandLine; PSTR CommandLine;
SHORT Found = FALSE; SHORT Found = FALSE;
@ -405,13 +405,13 @@ KdbSymInit(
} }
#if 1 // FIXME: This is a workaround HACK!! #if 1 // FIXME: This is a workaround HACK!!
// Save the actual value of LoadSymbols but disable it for BootPhase 0. // Save the actual value of LoadSymbols but disable it for InitPhase 0.
OrigLoadSymbols = LoadSymbols; OrigLoadSymbols = LoadSymbols;
LoadSymbols = FALSE; LoadSymbols = FALSE;
return OrigLoadSymbols; return OrigLoadSymbols;
#endif #endif
} }
else if (BootPhase == 1) else if (InitPhase == 1)
{ {
HANDLE Thread; HANDLE Thread;
NTSTATUS Status; NTSTATUS Status;