2005-04-25 14:44:48 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* FILE: ntoskrnl/kd/kdinit.c
|
|
|
|
* PURPOSE: Kernel Debugger Initializtion
|
2005-05-09 01:38:29 +00:00
|
|
|
*
|
2005-04-25 14:44:48 +00:00
|
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2005-04-25 14:44:48 +00:00
|
|
|
|
2005-06-04 10:05:20 +00:00
|
|
|
/* Make bochs debug output in the very early boot phase available */
|
|
|
|
//#define AUTO_ENABLE_BOCHS
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* VARIABLES ***************************************************************/
|
|
|
|
|
2013-05-07 00:14:36 +00:00
|
|
|
ULONG PortNumber = DEFAULT_DEBUG_PORT;
|
|
|
|
CPPORT PortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
|
2005-04-25 14:44:48 +00:00
|
|
|
ULONG KdpPortIrq;
|
2005-06-04 10:05:20 +00:00
|
|
|
#ifdef AUTO_ENABLE_BOCHS
|
2009-02-04 16:26:02 +00:00
|
|
|
KDP_DEBUG_MODE KdpDebugMode = {{{.Bochs=TRUE}}};
|
2005-06-04 10:05:20 +00:00
|
|
|
#else
|
2005-04-25 14:44:48 +00:00
|
|
|
KDP_DEBUG_MODE KdpDebugMode;
|
2006-01-15 08:49:26 +00:00
|
|
|
#endif
|
2005-04-25 14:44:48 +00:00
|
|
|
PKDP_INIT_ROUTINE WrapperInitRoutine;
|
|
|
|
KD_DISPATCH_TABLE WrapperTable;
|
2005-10-09 00:45:33 +00:00
|
|
|
BOOLEAN KdpEarlyBreak = FALSE;
|
2005-06-04 10:05:20 +00:00
|
|
|
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
|
|
|
|
KD_DISPATCH_TABLE DispatchTable[KdMax];
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit,
|
|
|
|
KdpSerialInit,
|
2006-01-15 08:49:26 +00:00
|
|
|
KdpInitDebugLog,
|
2007-07-06 09:02:16 +00:00
|
|
|
KdpBochsInit,
|
|
|
|
KdpKdbgInit};
|
2005-04-25 14:44:48 +00:00
|
|
|
|
2011-11-21 05:28:08 +00:00
|
|
|
extern ANSI_STRING KdpLogFileName;
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
|
|
|
|
PCHAR
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
INIT_FUNCTION
|
2005-04-25 14:44:48 +00:00
|
|
|
KdpGetDebugMode(PCHAR Currentp2)
|
|
|
|
{
|
2011-11-21 05:28:08 +00:00
|
|
|
PCHAR p1, p2 = Currentp2;
|
2005-04-25 14:44:48 +00:00
|
|
|
ULONG Value;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Check for Screen Debugging */
|
|
|
|
if (!_strnicmp(p2, "SCREEN", 6))
|
|
|
|
{
|
|
|
|
/* Enable It */
|
|
|
|
p2 += 6;
|
|
|
|
KdpDebugMode.Screen = TRUE;
|
|
|
|
}
|
|
|
|
/* Check for Serial Debugging */
|
|
|
|
else if (!_strnicmp(p2, "COM", 3))
|
|
|
|
{
|
|
|
|
/* Gheck for a valid Serial Port */
|
|
|
|
p2 += 3;
|
2011-11-22 02:30:16 +00:00
|
|
|
if (*p2 != ':')
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2011-11-22 02:30:16 +00:00
|
|
|
Value = (ULONG)atol(p2);
|
|
|
|
if (Value > 0 && Value < 5)
|
|
|
|
{
|
|
|
|
/* Valid port found, enable Serial Debugging */
|
|
|
|
KdpDebugMode.Serial = TRUE;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2011-11-22 02:30:16 +00:00
|
|
|
/* Set the port to use */
|
2013-05-07 00:14:36 +00:00
|
|
|
SerialPortNumber = Value;
|
2011-11-22 02:30:16 +00:00
|
|
|
KdpPort = Value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Value = strtoul(p2 + 1, NULL, 0);
|
|
|
|
if (Value)
|
|
|
|
{
|
|
|
|
KdpDebugMode.Serial = TRUE;
|
2013-05-07 00:14:36 +00:00
|
|
|
SerialPortInfo.Address = UlongToPtr(Value);
|
|
|
|
SerialPortNumber = 0;
|
2011-11-22 02:30:16 +00:00
|
|
|
KdpPort = 0;
|
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
}
|
2011-11-21 05:28:08 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Check for Debug Log Debugging */
|
|
|
|
else if (!_strnicmp(p2, "FILE", 4))
|
|
|
|
{
|
|
|
|
/* Enable It */
|
|
|
|
p2 += 4;
|
|
|
|
KdpDebugMode.File = TRUE;
|
2011-11-21 05:28:08 +00:00
|
|
|
if (*p2 == ':')
|
|
|
|
{
|
|
|
|
p2++;
|
|
|
|
p1 = p2;
|
|
|
|
while (*p2 != '\0' && *p2 != ' ') p2++;
|
|
|
|
KdpLogFileName.MaximumLength = KdpLogFileName.Length = p2 - p1;
|
|
|
|
KdpLogFileName.Buffer = p1;
|
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
2006-01-15 08:49:26 +00:00
|
|
|
/* Check for BOCHS Debugging */
|
|
|
|
else if (!_strnicmp(p2, "BOCHS", 5))
|
|
|
|
{
|
|
|
|
/* Enable It */
|
|
|
|
p2 += 5;
|
|
|
|
KdpDebugMode.Bochs = TRUE;
|
|
|
|
}
|
|
|
|
|
2009-06-22 11:32:58 +00:00
|
|
|
/* Check for GDB Debugging */
|
|
|
|
else if (!_strnicmp(p2, "GDB", 3))
|
|
|
|
{
|
|
|
|
/* Enable it */
|
|
|
|
p2 += 3;
|
|
|
|
KdpDebugMode.Gdb = TRUE;
|
|
|
|
|
|
|
|
/* Enable Debugging */
|
|
|
|
KdDebuggerNotPresent = FALSE;
|
2016-10-06 19:01:33 +00:00
|
|
|
KdDebuggerEnabled = TRUE;
|
|
|
|
SharedUserData->KdDebuggerEnabled = TRUE;
|
2009-06-22 11:32:58 +00:00
|
|
|
WrapperInitRoutine = KdpGdbStubInit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for PICE Debugging */
|
|
|
|
else if (!_strnicmp(p2, "PICE", 4))
|
|
|
|
{
|
|
|
|
/* Enable it */
|
|
|
|
p2 += 4;
|
|
|
|
KdpDebugMode.Pice = TRUE;
|
|
|
|
|
|
|
|
/* Enable Debugging */
|
|
|
|
KdDebuggerNotPresent = FALSE;
|
2016-10-06 19:01:33 +00:00
|
|
|
KdDebuggerEnabled = TRUE;
|
|
|
|
SharedUserData->KdDebuggerEnabled = TRUE;
|
2009-06-22 11:32:58 +00:00
|
|
|
}
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
return p2;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
INIT_FUNCTION
|
2005-04-25 14:44:48 +00:00
|
|
|
KdpCallInitRoutine(ULONG BootPhase)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PKD_DISPATCH_TABLE CurrentTable;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call the registered handlers */
|
|
|
|
CurrentEntry = KdProviders.Flink;
|
|
|
|
while (CurrentEntry != &KdProviders)
|
|
|
|
{
|
|
|
|
/* Get the current table */
|
2005-05-09 01:38:29 +00:00
|
|
|
CurrentTable = CONTAINING_RECORD(CurrentEntry,
|
|
|
|
KD_DISPATCH_TABLE,
|
2005-04-25 14:44:48 +00:00
|
|
|
KdProvidersList);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call it */
|
|
|
|
CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Next Table */
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call the Wrapper Init Routine */
|
|
|
|
if (WrapperInitRoutine)
|
|
|
|
WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
|
|
|
|
}
|
|
|
|
|
2006-10-08 04:05:27 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2005-04-25 14:44:48 +00:00
|
|
|
KdInitSystem(ULONG BootPhase,
|
2006-09-30 03:33:50 +00:00
|
|
|
PLOADER_PARAMETER_BLOCK LoaderBlock)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
|
|
|
ULONG Value;
|
|
|
|
ULONG i;
|
2006-10-02 05:40:36 +00:00
|
|
|
PCHAR CommandLine, Port, BaudRate, Irq;
|
2006-10-01 20:27:36 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Set Default Port Options */
|
|
|
|
if (BootPhase == 0)
|
|
|
|
{
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Get the Command Line */
|
|
|
|
CommandLine = LoaderBlock->LoadOptions;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Upcase it */
|
|
|
|
_strupr(CommandLine);
|
|
|
|
|
2009-06-22 11:32:58 +00:00
|
|
|
/* XXX Check for settings that we support */
|
2006-10-02 05:40:36 +00:00
|
|
|
if (strstr(CommandLine, "BREAK")) KdpEarlyBreak = TRUE;
|
|
|
|
if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE;
|
2010-05-15 03:21:54 +00:00
|
|
|
else if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled = FALSE;
|
|
|
|
else if (strstr(CommandLine, "DEBUG"))
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2011-11-21 05:28:08 +00:00
|
|
|
/* Enable the kernel debugger */
|
2010-05-06 01:45:10 +00:00
|
|
|
KdDebuggerNotPresent = FALSE;
|
2016-10-06 19:01:33 +00:00
|
|
|
KdDebuggerEnabled = TRUE;
|
2009-06-22 11:32:58 +00:00
|
|
|
#ifdef KDBG
|
2010-05-06 01:45:10 +00:00
|
|
|
/* Get the KDBG Settings */
|
|
|
|
KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
|
2009-06-22 11:32:58 +00:00
|
|
|
#endif
|
2010-05-06 01:45:10 +00:00
|
|
|
}
|
2009-06-22 11:32:58 +00:00
|
|
|
|
2016-10-06 19:01:33 +00:00
|
|
|
/* Let user-mode know our state */
|
|
|
|
SharedUserData->KdDebuggerEnabled = KdDebuggerEnabled;
|
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Get the port and baud rate */
|
|
|
|
Port = strstr(CommandLine, "DEBUGPORT");
|
|
|
|
BaudRate = strstr(CommandLine, "BAUDRATE");
|
|
|
|
Irq = strstr(CommandLine, "IRQ");
|
|
|
|
|
2009-06-22 11:32:58 +00:00
|
|
|
/* Check if we got the /DEBUGPORT parameter(s) */
|
|
|
|
while (Port)
|
2006-10-02 05:40:36 +00:00
|
|
|
{
|
|
|
|
/* Move past the actual string, to reach the port*/
|
2009-06-22 11:32:58 +00:00
|
|
|
Port += sizeof("DEBUGPORT") - 1;
|
2006-10-02 05:40:36 +00:00
|
|
|
|
|
|
|
/* Now get past any spaces and skip the equal sign */
|
|
|
|
while (*Port == ' ') Port++;
|
|
|
|
Port++;
|
|
|
|
|
|
|
|
/* Get the debug mode and wrapper */
|
|
|
|
Port = KdpGetDebugMode(Port);
|
2009-06-22 11:32:58 +00:00
|
|
|
Port = strstr(Port, "DEBUGPORT");
|
2006-10-02 05:40:36 +00:00
|
|
|
}
|
|
|
|
|
2011-11-21 05:28:08 +00:00
|
|
|
/* Use serial port then */
|
|
|
|
if (KdDebuggerEnabled && KdpDebugMode.Value == 0)
|
|
|
|
KdpDebugMode.Serial = TRUE;
|
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Check if we got a baud rate */
|
|
|
|
if (BaudRate)
|
|
|
|
{
|
|
|
|
/* Move past the actual string, to reach the rate */
|
2009-06-22 11:32:58 +00:00
|
|
|
BaudRate += sizeof("BAUDRATE") - 1;
|
2006-10-02 05:40:36 +00:00
|
|
|
|
|
|
|
/* Now get past any spaces */
|
|
|
|
while (*BaudRate == ' ') BaudRate++;
|
|
|
|
|
|
|
|
/* And make sure we have a rate */
|
|
|
|
if (*BaudRate)
|
2005-04-25 14:44:48 +00:00
|
|
|
{
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Read and set it */
|
|
|
|
Value = atol(BaudRate + 1);
|
|
|
|
if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
2006-10-02 05:40:36 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Check Serial Port Settings [IRQ] */
|
|
|
|
if (Irq)
|
|
|
|
{
|
|
|
|
/* Move past the actual string, to reach the rate */
|
2009-06-22 11:32:58 +00:00
|
|
|
Irq += sizeof("IRQ") - 1;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* Now get past any spaces */
|
|
|
|
while (*Irq == ' ') Irq++;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-10-02 05:40:36 +00:00
|
|
|
/* And make sure we have an IRQ */
|
|
|
|
if (*Irq)
|
|
|
|
{
|
|
|
|
/* Read and set it */
|
|
|
|
Value = atol(Irq + 1);
|
|
|
|
if (Value) KdpPortIrq = Value;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
}
|
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call Providers at Phase 0 */
|
|
|
|
for (i = 0; i < KdMax; i++)
|
|
|
|
{
|
|
|
|
InitRoutines[i](&DispatchTable[i], 0);
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-25 14:44:48 +00:00
|
|
|
/* Call Wrapper at Phase 0 */
|
|
|
|
if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
|
2006-10-08 04:05:27 +00:00
|
|
|
return TRUE;
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
2009-06-22 11:32:58 +00:00
|
|
|
else /* BootPhase > 0 */
|
2008-07-31 07:31:55 +00:00
|
|
|
{
|
|
|
|
#ifdef _M_IX86
|
|
|
|
KdpEnableSafeMem();
|
|
|
|
#endif
|
|
|
|
}
|
2005-04-25 14:44:48 +00:00
|
|
|
|
|
|
|
/* Call the Initialization Routines of the Registered Providers */
|
|
|
|
KdpCallInitRoutine(BootPhase);
|
2006-10-08 04:05:27 +00:00
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return TRUE;
|
2005-04-25 14:44:48 +00:00
|
|
|
}
|
|
|
|
|
2009-06-22 11:32:58 +00:00
|
|
|
/* EOF */
|