From 22a4a0901f286d1396af5ae9043f5160dbea87ae Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Thu, 1 Mar 2012 16:32:00 +0000 Subject: [PATCH] [freeldr] - Implement enabling extended debug output in freeldr without the need to recompile it. Add an option in the f8 menu that allows the user to specify which debug channels and levels will be enabled. svn path=/trunk/; revision=55946 --- reactos/boot/freeldr/freeldr/debug.c | 128 ++++++++++++++++--- reactos/boot/freeldr/freeldr/include/debug.h | 38 +++--- reactos/boot/freeldr/freeldr/options.c | 30 ++++- 3 files changed, 161 insertions(+), 35 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/debug.c b/reactos/boot/freeldr/freeldr/debug.c index 987ed78863c..56c5709683f 100644 --- a/reactos/boot/freeldr/freeldr/debug.c +++ b/reactos/boot/freeldr/freeldr/debug.c @@ -29,19 +29,7 @@ //#define DEBUG_CUSTOM #define DEBUG_NONE -#if defined (DEBUG_ALL) -ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM | - DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS | - DPRINT_LINUX | DPRINT_HWDETECT | DPRINT_PELOADER | DPRINT_WINDOWS; -#elif defined (DEBUG_INIFILE) -ULONG DebugPrintMask = DPRINT_INIFILE; -#elif defined (DEBUG_REACTOS) -ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY; -#elif defined (DEBUG_CUSTOM) -ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_WINDOWS; -#else //#elif defined (DEBUG_NONE) -ULONG DebugPrintMask = 0; -#endif +#define DBG_DEFAULT_LEVELS (ERR_LEVEL|FIXME_LEVEL) #define SCREEN 1 #define RS232 2 @@ -54,6 +42,9 @@ ULONG DebugPrintMask = 0; #define BOCHS_OUTPUT_PORT 0xe9 + +static UCHAR DbgChannels[DBG_CHANNELS_COUNT]; + ULONG DebugPort = RS232; //ULONG DebugPort = SCREEN; //ULONG DebugPort = BOCHS; @@ -66,6 +57,22 @@ BOOLEAN DebugStartOfLine = TRUE; VOID DebugInit(VOID) { +#if defined (DEBUG_ALL) + memset(DbgChannels, MAX_LEVEL, DBG_CHANNELS_COUNT); +#else + memset(DbgChannels, 0, DBG_CHANNELS_COUNT); +#endif + +#if defined (DEBUG_INIFILE) + DbgChannels[DPRINT_INIFILE] = MAX_LEVEL; +#elif defined (DEBUG_REACTOS) + DbgChannels[DPRINT_REACTOS] = MAX_LEVEL; + DbgChannels[DPRINT_REGISTRY] = MAX_LEVEL; +#elif defined (DEBUG_CUSTOM) + DbgChannels[DPRINT_WARNING] = MAX_LEVEL; + DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL; +#endif + if (DebugPort & RS232) { Rs232PortInitialize(ComPort, BaudRate); @@ -135,7 +142,7 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, . char *ptr = Buffer; // Mask out unwanted debug messages - if (Level >= WARN_LEVEL && !(Mask & DebugPrintMask)) + if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS )) { return; } @@ -182,7 +189,7 @@ DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length) ULONG Idx2; // Mask out unwanted debug messages - if (!(Mask & DebugPrintMask)) + if (!(DbgChannels[Mask] & TRACE_LEVEL)) { return; } @@ -306,3 +313,94 @@ KeBugCheckEx( assert(FALSE); for (;;); } + + +static BOOLEAN +DbgAddDebugChannel( CHAR* channel, CHAR* level, CHAR op) +{ + int iLevel, iChannel; + + if(channel == NULL || *channel == L'\0' ||strlen(channel) == 0 ) + return FALSE; + + if(level == NULL || *level == L'\0' ||strlen(level) == 0 ) + iLevel = MAX_LEVEL; + else if(strcmp(level, "err") == 0) + iLevel = ERR_LEVEL; + else if(strcmp(level, "fixme") == 0) + iLevel = FIXME_LEVEL; + else if(strcmp(level, "warn") == 0) + iLevel = WARN_LEVEL; + else if (strcmp(level, "trace") == 0) + iLevel = TRACE_LEVEL; + else + return FALSE; + + if(strcmp(channel, "memory") == 0) iChannel = DPRINT_MEMORY; + else if(strcmp(channel, "filesystem") == 0) iChannel = DPRINT_FILESYSTEM; + else if(strcmp(channel, "inifile") == 0) iChannel = DPRINT_INIFILE; + else if(strcmp(channel, "ui") == 0) iChannel = DPRINT_UI; + else if(strcmp(channel, "disk") == 0) iChannel = DPRINT_DISK; + else if(strcmp(channel, "cache") == 0) iChannel = DPRINT_CACHE; + else if(strcmp(channel, "registry") == 0) iChannel = DPRINT_REGISTRY; + else if(strcmp(channel, "linux") == 0) iChannel = DPRINT_LINUX; + else if(strcmp(channel, "hwdetect") == 0) iChannel = DPRINT_HWDETECT; + else if(strcmp(channel, "windows") == 0) iChannel = DPRINT_WINDOWS; + else if(strcmp(channel, "peloader") == 0) iChannel = DPRINT_PELOADER; + else if(strcmp(channel, "scsiport") == 0) iChannel = DPRINT_SCSIPORT; + else if(strcmp(channel, "heap") == 0) iChannel = DPRINT_HEAP; + else if(strcmp(channel, "all") == 0) + { + int i; + + for(i= 0 ; i < DBG_CHANNELS_COUNT; i++) + { + if(op==L'+') + DbgChannels[i] |= iLevel; + else + DbgChannels[i] &= ~iLevel; + } + + return TRUE; + } + + if(op==L'+') + DbgChannels[iChannel] |= iLevel; + else + DbgChannels[iChannel] &= ~iLevel; + + return TRUE; +} + +BOOLEAN +DbgParseDebugChannels(PCHAR Value) +{ + CHAR *str, *separator, *c, op; + + str = Value; + + do + { + separator = strchr(str, L','); + if(separator != NULL) + *separator = L'\0'; + + c = strchr(str, L'+'); + if(c == NULL) + c = strchr(str, L'-'); + + if(c != NULL) + { + op = *c; + *c = L'\0'; + c++; + + DbgAddDebugChannel(c, str, op); + } + + str = separator + 1; + }while(separator != NULL); + + return TRUE; +} + diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index bd2b60978fb..e51ac5d87fd 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -20,23 +20,25 @@ #ifndef __DEBUG_H #define __DEBUG_H -// OR this with DebugPrintMask to enable ... -#define DPRINT_NONE 0x00000000 // No debug print -#define DPRINT_WARNING 0x00000001 // debugger messages and other misc stuff -#define DPRINT_MEMORY 0x00000002 // memory management messages -#define DPRINT_FILESYSTEM 0x00000004 // file system messages -#define DPRINT_INIFILE 0x00000008 // .ini file messages -#define DPRINT_UI 0x00000010 // user interface messages -#define DPRINT_DISK 0x00000020 // disk messages -#define DPRINT_CACHE 0x00000040 // cache messages -#define DPRINT_REGISTRY 0x00000080 // registry messages -#define DPRINT_REACTOS 0x00000100 // ReactOS messages -#define DPRINT_LINUX 0x00000200 // Linux messages -#define DPRINT_HWDETECT 0x00000400 // hardware detection messages -#define DPRINT_WINDOWS 0x00000800 // messages from Windows loader -#define DPRINT_PELOADER 0x00001000 // messages from PE images loader -#define DPRINT_SCSIPORT 0x00002000 // messages from SCSI miniport -#define DPRINT_HEAP 0x00004000 // messages in a bottle +#define DPRINT_NONE 0 // No debug print +#define DPRINT_WARNING 1 // debugger messages and other misc stuff +#define DPRINT_MEMORY 2 // memory management messages +#define DPRINT_FILESYSTEM 3 // file system messages +#define DPRINT_INIFILE 4 // .ini file messages +#define DPRINT_UI 5 // user interface messages +#define DPRINT_DISK 6 // disk messages +#define DPRINT_CACHE 7 // cache messages +#define DPRINT_REGISTRY 8 // registry messages +#define DPRINT_REACTOS 9 // ReactOS messages +#define DPRINT_LINUX 10 // Linux messages +#define DPRINT_HWDETECT 11 // hardware detection messages +#define DPRINT_WINDOWS 12 // messages from Windows loader +#define DPRINT_PELOADER 13 // messages from PE images loader +#define DPRINT_SCSIPORT 14 // messages from SCSI miniport +#define DPRINT_HEAP 15 // messages in a bottle +#define DBG_CHANNELS_COUNT 16 + +BOOLEAN DbgParseDebugChannels(PCHAR Value); #if DBG && !defined(_M_ARM) @@ -50,6 +52,8 @@ #define WARN_LEVEL 0x4 #define TRACE_LEVEL 0x8 + #define MAX_LEVEL ERR_LEVEL | FIXME_LEVEL | WARN_LEVEL | TRACE_LEVEL + #define DBG_DEFAULT_CHANNEL(ch) static int DbgDefaultChannel = DPRINT_##ch #define ERR_CH(ch, fmt, ...) DbgPrint2(DPRINT_##ch, ERR_LEVEL, __FILE__, __LINE__, fmt, ##__VA_ARGS__) diff --git a/reactos/boot/freeldr/freeldr/options.c b/reactos/boot/freeldr/freeldr/options.c index 5b64b46a077..dc6e85c080d 100644 --- a/reactos/boot/freeldr/freeldr/options.c +++ b/reactos/boot/freeldr/freeldr/options.c @@ -18,6 +18,7 @@ */ #include +#include PCSTR OptionsMenuList[] = { @@ -32,6 +33,7 @@ PCSTR OptionsMenuList[] = "Last Known Good Configuration", "Directory Services Restore Mode", "Debugging Mode", + "FreeLdr debugging", "SEPARATOR", @@ -43,6 +45,21 @@ PCSTR OptionsMenuList[] = #endif }; +PCSTR FrldrDbgMsg = "Enable freeldr debug channels\n" + "Acceptable syntax: [level1]#channel1[,[level2]#channel2]\n" + "level can be one of: trace,warn,fixme,err\n" + " if the level is ommited all levels\n" + " are enabled for the specified channel\n" + "# can be either + or -\n" + "channel can be one of the following:\n" + " all,warning,memory,filesystem,inifile,ui,disk,cache,registry,\n" + " reactos,linux,hwdetect,windows,peloader,scsiport,heap\n" + "Examples:\n" + " trace+windows,trace+reactos\n" + " +hwdetect,err-disk\n" + " +peloader\n" + "NOTE: all letters must be lowercase, no spaces allowed\n"; + enum OptionMenuItems { SAFE_MODE = 0, @@ -56,14 +73,15 @@ enum OptionMenuItems LAST_KNOWN_GOOD_CONFIGURATION = 6, DIRECTORY_SERVICES_RESTORE_MODE = 7, DEBUGGING_MODE = 8, + FREELDR_DEBUGGING = 9, - SEPARATOR2 = 9, + SEPARATOR2 = 10, #ifdef HAS_OPTION_MENU_CUSTOM_BOOT - CUSTOM_BOOT = 10, + CUSTOM_BOOT = 11, #endif #ifdef HAS_OPTION_MENU_REBOOT - REBOOT = 11, + REBOOT = 12, #endif }; @@ -81,6 +99,7 @@ BOOLEAN DebuggingMode = FALSE; VOID DoOptionsMenu(VOID) { ULONG SelectedMenuItem; + CHAR DebugChannelString[100]; if (!UiDisplayMenu(OptionsMenuList, OptionsMenuItemCount, 0, -1, &SelectedMenuItem, TRUE, NULL)) { @@ -122,6 +141,11 @@ VOID DoOptionsMenu(VOID) case DEBUGGING_MODE: DebuggingMode = TRUE; break; + case FREELDR_DEBUGGING: + DebugChannelString[0]=0; + if(UiEditBox(FrldrDbgMsg, DebugChannelString, 100)) + DbgParseDebugChannels(DebugChannelString); + break; //case SEPARATOR2: // break; #ifdef HAS_OPTION_MENU_CUSTOM_BOOT