From: Hermès Bélusca-Maïto Date: Sun, 20 Dec 2015 02:06:40 +0000 (+0000) Subject: [FREELDR] X-Git-Tag: ReactOS-0.4.0~19^2~31 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7642306ded4fa43b826057f4fd9646200afcdb7a [FREELDR] - Allow to specify in freeldr.ini the debugging port parameters, similarly to what NTLDR allows to do: http://naesten.blogspot.fr/2010/07/undocumented-debug-section-in-bootini.html - Update the FREELDR.INI example file to reflect these changes. - Because some FreeLdr components, that need to be initialized before the debugging port parameters can be read from freeldr.ini, use debugging features, we still need to choose some default parameters. For serial ports, we select the possible port starting from COM4 down to COM1. CORE-9023 #comment Revision 70403: Allow to specify a debugging port in freeldr.ini . svn path=/trunk/; revision=70403 --- diff --git a/reactos/boot/freeldr/FREELDR.INI b/reactos/boot/freeldr/FREELDR.INI index e65ec6eadbd..7177121b824 100644 --- a/reactos/boot/freeldr/FREELDR.INI +++ b/reactos/boot/freeldr/FREELDR.INI @@ -29,6 +29,7 @@ ; [FREELOADER] Section Commands: ; +; Debug - FreeLoader debugging port parameters, e.g. /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 ; MessageBox - displays the specified text in a message box upon bootup ; MessageLine - adds a new line of text to a message box (must come before MessageBox command) ; TitleText - text that is displayed in the title box @@ -50,15 +51,15 @@ ; [OS-General] Section Commands: ; -; BootType - sets the boot type: ReactOS, Linux, BootSector, Partition, Drive -; BootPath - ARC path e.g. multi(0)disk(0)rdisk(x)partition(y) +; BootType - sets the boot type: Windows, WindowsNT40, Windows2003, Linux, BootSector, Partition, Drive, ReactOSSetup +; BootPath - ARC path, e.g. multi(0)disk(0)rdisk(x)partition(y) ; DriveMap - maps a BIOS drive number to another (i.e. DriveMap=hd1,hd0 maps harddisk1 to harddisk0 or DriveMap=fd1,fd0) ; [BootSector OSType] Section Commands: ; ; BootSector - sets the filename of the bootsector to be loaded -; [ReactOS OSType] Section Commands: +; [Windows(NT40|2003) OSType] Section Commands: ; ; SystemPath - sets the system root path (must be a valid ARC - Path): ; multi(0)disk(0)rdisk(0)partition(1)\reactos @@ -110,7 +111,7 @@ DriveD="Drive D:" ; Load ReactOS from harddisk (drive C:) [ReactOSHD] -BootType=ReactOS +BootType=Windows2003 SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos Options=/DEBUGPORT=SCREEN Kernel=\REACTOS\SYSTEM32\NTOSKRNL.EXE @@ -118,14 +119,14 @@ Hal=\REACTOS\SYSTEM32\HAL.DLL ; Load ReactOS from floppy (drive A:) [ReactOSFloppy] -BootType=ReactOS +BootType=Windows2003 SystemPath=multi(0)disk(0)fdisk(0) Options=/DEBUGPORT=SCREEN Kernel=\reactos\NTOSKRNL.EXE Hal=\reactos\HAL.DLL ;[ReactOS (Debug)] -;BootType=ReactOS +;BootType=Windows2003 ;SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos ;Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=19200 ;Kernel=\NTOSKRNL.EXE diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index 37ccb2aae60..fbe49838ab8 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -20,6 +20,7 @@ /* INCLUDES *******************************************************************/ #include +#include /* GLOBALS ********************************************************************/ @@ -131,7 +132,7 @@ ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG if (DefaultOSName != NULL) { - for (Idx = 0; Idx #include -/* MACROS *******************************************************************/ - #if DBG -#define DEFAULT_BAUD_RATE 19200 +/* STATIC VARIABLES ***********************************************************/ +#define DEFAULT_BAUD_RATE 19200 -/* STATIC VARIABLES *********************************************************/ +#if defined(_M_IX86) || defined(_M_AMD64) +static const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; +#elif defined(_M_PPC) +static const ULONG BaseArray[] = {0, 0x800003F8}; +#elif defined(_M_MIPS) +static const ULONG BaseArray[] = {0, 0x80006000, 0x80007000}; +#elif defined(_M_ARM) +static const ULONG BaseArray[] = {0, 0xF1012000}; +#else +#error Unknown architecture +#endif -static ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; +#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1) /* The COM port must only be initialized once! */ -static CPPORT Rs232ComPort; -static BOOLEAN PortInitialized = FALSE; - +static ULONG Rs232ComPort = 0; +static CPPORT Rs232ComPortInfo; -/* FUNCTIONS *********************************************************/ +/* FUNCTIONS ******************************************************************/ BOOLEAN Rs232PortInitialize(IN ULONG ComPort, IN ULONG BaudRate) @@ -48,77 +58,73 @@ BOOLEAN Rs232PortInitialize(IN ULONG ComPort, NTSTATUS Status; PUCHAR Address; - if (PortInitialized == FALSE) - { - if (BaudRate == 0) - { - BaudRate = DEFAULT_BAUD_RATE; - } + /* + * Check whether it's the first time we initialize a COM port. + * If not, check whether the specified one was already initialized. + */ + if ((Rs232ComPort != 0) && (Rs232ComPort == ComPort)) + return TRUE; - if (ComPort == 0) - { - if (CpDoesPortExist(UlongToPtr(BaseArray[2]))) - { - Address = UlongToPtr(BaseArray[2]); - } - else if (CpDoesPortExist(UlongToPtr(BaseArray[1]))) - { - Address = UlongToPtr(BaseArray[1]); - } - else - { - return FALSE; - } - } - else if (ComPort <= 4) // 4 == MAX_COM_PORTS + if (BaudRate == 0) + BaudRate = DEFAULT_BAUD_RATE; + + if (ComPort == 0) + { + /* + * Start enumerating COM ports from the last one to the first one, + * and break when we find a valid port. + * If we reach the first element of the list, the invalid COM port, + * then it means that no valid port was found. + */ + for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--) { if (CpDoesPortExist(UlongToPtr(BaseArray[ComPort]))) { Address = UlongToPtr(BaseArray[ComPort]); - } - else - { - return FALSE; + break; } } + if (ComPort == 0) + return FALSE; + } + else if (ComPort <= MAX_COM_PORTS) + { + if (CpDoesPortExist(UlongToPtr(BaseArray[ComPort]))) + Address = UlongToPtr(BaseArray[ComPort]); else - { return FALSE; - } + } + else + { + return FALSE; + } - Status = CpInitialize(&Rs232ComPort, Address, BaudRate); - if (!NT_SUCCESS(Status)) return FALSE; + Status = CpInitialize(&Rs232ComPortInfo, Address, BaudRate); + if (!NT_SUCCESS(Status)) return FALSE; - PortInitialized = TRUE; - } + Rs232ComPort = ComPort; return TRUE; } BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived) { - if (PortInitialized == FALSE) - return FALSE; - - return (CpGetByte(&Rs232ComPort, ByteReceived, TRUE, FALSE) == CP_GET_SUCCESS); + if (Rs232ComPort == 0) return FALSE; + return (CpGetByte(&Rs232ComPortInfo, ByteReceived, TRUE, FALSE) == CP_GET_SUCCESS); } /* BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived) { - if (PortInitialized == FALSE) - return FALSE; - - return (CpGetByte(&Rs232ComPort, ByteReceived, FALSE, FALSE) == CP_GET_SUCCESS); + if (Rs232ComPort == 0) return FALSE; + return (CpGetByte(&Rs232ComPortInfo, ByteReceived, FALSE, FALSE) == CP_GET_SUCCESS); } */ VOID Rs232PortPutByte(UCHAR ByteToSend) { - if (PortInitialized == FALSE) - return; - - CpPutByte(&Rs232ComPort, ByteToSend); + if (Rs232ComPort == 0) return; + CpPutByte(&Rs232ComPortInfo, ByteToSend); } #endif /* DBG */ @@ -126,7 +132,7 @@ VOID Rs232PortPutByte(UCHAR ByteToSend) BOOLEAN Rs232PortInUse(PUCHAR Base) { #if DBG - return ( (PortInitialized && (Rs232ComPort.Address == Base)) ? TRUE : FALSE ); + return ( ((Rs232ComPort != 0) && (Rs232ComPortInfo.Address == Base)) ? TRUE : FALSE ); #else return FALSE; #endif diff --git a/reactos/boot/freeldr/freeldr/debug.c b/reactos/boot/freeldr/freeldr/debug.c index 48e3bbcdddb..2855f4e27cc 100644 --- a/reactos/boot/freeldr/freeldr/debug.c +++ b/reactos/boot/freeldr/freeldr/debug.c @@ -18,7 +18,6 @@ */ #include - #include #if DBG && !defined(_M_ARM) @@ -33,36 +32,31 @@ #define DBG_DEFAULT_LEVELS (ERR_LEVEL|FIXME_LEVEL) +static UCHAR DbgChannels[DBG_CHANNELS_COUNT]; + #define SCREEN 1 #define RS232 2 #define BOCHS 4 -#define COM1 1 -#define COM2 2 -#define COM3 3 -#define COM4 4 - -#define BOCHS_OUTPUT_PORT 0xe9 - -static UCHAR DbgChannels[DBG_CHANNELS_COUNT]; +#define BOCHS_OUTPUT_PORT 0xE9 ULONG DebugPort = RS232; -// ULONG DebugPort = SCREEN; -// ULONG DebugPort = BOCHS; -// ULONG DebugPort = SCREEN|BOCHS; -#ifdef _WINKD_ -/* COM1 is the WinDbg port */ -ULONG ComPort = COM2; -#else -ULONG ComPort = COM1; -#endif -// ULONG BaudRate = 19200; + +/* Serial debug connection */ +ULONG ComPort = 0; // The COM port initializer chooses the first available port starting from COM4 down to COM1. ULONG BaudRate = 115200; +ULONG PortIrq = 0; // Not used at the moment. BOOLEAN DebugStartOfLine = TRUE; -VOID DebugInit(VOID) +VOID DebugInit(BOOLEAN MainInit) { + PCHAR CommandLine, PortString, BaudString, IrqString; + ULONG Value; + CHAR DebugString[256]; + + /* Always reset the debugging channels */ + #if defined (DEBUG_ALL) memset(DbgChannels, MAX_LEVEL, DBG_CHANNELS_COUNT); #elif defined (DEBUG_WARN) @@ -83,9 +77,121 @@ VOID DebugInit(VOID) DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL; #endif + /* Check for pre- or main initialization phase */ + if (!MainInit) + { + /* Pre-initialization phase: use the FreeLdr command-line debugging string */ + CommandLine = (PCHAR)CmdLineGetDebugString(); + + /* If no command-line is provided, initialize the debug port with default settings */ + if (CommandLine == NULL) + goto Done; + + strcpy(DebugString, CommandLine); + } + else + { + /* Main initialization phase: use the FreeLdr INI debugging string */ + + ULONG_PTR SectionId; + + if (!IniOpenSection("FreeLoader", &SectionId)) + return; + + if (!IniReadSettingByName(SectionId, "Debug", DebugString, sizeof(DebugString))) + return; + } + + /* Get the Command Line */ + CommandLine = DebugString; + + /* 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 /DEBUGPORT parameters. + * NOTE: Inspired by reactos/ntoskrnl/kd/kdinit.c, KdInitSystem(...) + */ + while (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++; + + /* Check for possible ports and set the port to use */ + if (strncmp(PortString, "SCREEN", 6) == 0) + { + PortString += 6; + DebugPort |= SCREEN; + } + else if (strncmp(PortString, "BOCHS", 5) == 0) + { + PortString += 5; + DebugPort |= BOCHS; + } + else if (strncmp(PortString, "COM", 3) == 0) + { + PortString += 3; + DebugPort |= RS232; + + /* Set the port to use */ + Value = atol(PortString); + if (Value) ComPort = Value; + } + + PortString = strstr(PortString, "DEBUGPORT"); + } + + /* 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) BaudRate = 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) PortIrq = Value; + } + } + +Done: + /* Try to initialize the port; if it fails, remove the corresponding flag */ if (DebugPort & RS232) { - Rs232PortInitialize(ComPort, BaudRate); + if (!Rs232PortInitialize(ComPort, BaudRate)) + DebugPort &= ~RS232; } } @@ -114,9 +220,9 @@ VOID DebugPrintChar(UCHAR Character) ULONG DbgPrint(const char *Format, ...) { - int i; - int Length; va_list ap; + int Length; + char* ptr; CHAR Buffer[512]; va_start(ap, Format); @@ -133,10 +239,9 @@ DbgPrint(const char *Format, ...) Length = sizeof(Buffer); } - for (i = 0; i < Length; i++) - { - DebugPrintChar(Buffer[i]); - } + ptr = Buffer; + while (Length--) + DebugPrintChar(*ptr++); return 0; } @@ -149,7 +254,7 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, . char *ptr = Buffer; /* Mask out unwanted debug messages */ - if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS )) + if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS)) { return; } @@ -191,9 +296,8 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, . VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length) { - PUCHAR BufPtr = (PUCHAR)Buffer; - ULONG Idx; - ULONG Idx2; + PUCHAR BufPtr = (PUCHAR)Buffer; + ULONG Idx, Idx2; /* Mask out unwanted debug messages */ if (!(DbgChannels[Mask] & TRACE_LEVEL)) @@ -202,7 +306,7 @@ DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length) DebugStartOfLine = FALSE; // We don't want line headers DbgPrint("Dumping buffer at %p with length of %lu bytes:\n", Buffer, Length); - for (Idx=0; Idx 20) && (BufPtr[Idx] < 0x80)) { @@ -257,10 +361,10 @@ DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op) { int iLevel, iChannel; - if (channel == NULL || *channel == L'\0' || strlen(channel) == 0 ) + if (channel == NULL || *channel == '\0' || strlen(channel) == 0) return FALSE; - if (level == NULL || *level == L'\0' || strlen(level) == 0 ) + if (level == NULL || *level == '\0' || strlen(level) == 0) iLevel = MAX_LEVEL; else if (strcmp(level, "err") == 0) iLevel = ERR_LEVEL; @@ -290,9 +394,9 @@ DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op) { int i; - for(i= 0 ; i < DBG_CHANNELS_COUNT; i++) + for (i = 0; i < DBG_CHANNELS_COUNT; i++) { - if(op==L'+') + if (op == '+') DbgChannels[i] |= iLevel; else DbgChannels[i] &= ~iLevel; @@ -302,7 +406,7 @@ DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op) } else return FALSE; - if (op == L'+') + if (op == '+') DbgChannels[iChannel] |= iLevel; else DbgChannels[iChannel] &= ~iLevel; diff --git a/reactos/boot/freeldr/freeldr/freeldr.c b/reactos/boot/freeldr/freeldr/freeldr.c index d6bcaa8c6a0..7c7ee14e02b 100644 --- a/reactos/boot/freeldr/freeldr/freeldr.c +++ b/reactos/boot/freeldr/freeldr/freeldr.c @@ -26,19 +26,21 @@ DBG_DEFAULT_CHANNEL(WARNING); /* FUNCTIONS ******************************************************************/ -VOID __cdecl BootMain(LPSTR CmdLine) +VOID __cdecl BootMain(IN PCCH CmdLine) { CmdLineParse(CmdLine); MachInit(CmdLine); FsInit(); - DebugInit(); + /* Debugger pre-initialization */ + DebugInit(FALSE); TRACE("BootMain() called.\n"); /* Check if the CPU is new enough */ FrLdrCheckCpuCompatiblity(); + /* UI pre-initialization */ if (!UiInitialize(FALSE)) { UiMessageBoxCritical("Unable to initialize UI."); diff --git a/reactos/boot/freeldr/freeldr/include/cmdline.h b/reactos/boot/freeldr/freeldr/include/cmdline.h index 68f61a11a3c..3ab13c21fdc 100644 --- a/reactos/boot/freeldr/freeldr/include/cmdline.h +++ b/reactos/boot/freeldr/freeldr/include/cmdline.h @@ -19,8 +19,9 @@ #pragma once -VOID CmdLineParse(IN PCHAR CmdLine); +VOID CmdLineParse(IN PCCH CmdLine); +PCCH CmdLineGetDebugString(VOID); PCCH CmdLineGetDefaultOS(VOID); LONG CmdLineGetTimeOut(VOID); diff --git a/reactos/boot/freeldr/freeldr/include/debug.h b/reactos/boot/freeldr/freeldr/include/debug.h index be0d906cee8..9cf62ebb8ee 100644 --- a/reactos/boot/freeldr/freeldr/include/debug.h +++ b/reactos/boot/freeldr/freeldr/include/debug.h @@ -40,7 +40,7 @@ #if DBG && !defined(_M_ARM) - VOID DebugInit(VOID); + VOID DebugInit(BOOLEAN MainInit); ULONG DbgPrint(const char *Format, ...); VOID DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...); VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length); @@ -113,7 +113,7 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr); #define UNIMPLEMENTED - #define DebugInit() + #define DebugInit(init) #define BugCheck(fmt, ...) #define DbgDumpBuffer(mask, buf, len) #define DbgParseDebugChannels(val) diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index d96d4000394..0bdc9988655 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -119,7 +119,7 @@ #include #endif -VOID __cdecl BootMain(LPSTR CmdLine); +VOID __cdecl BootMain(IN PCCH CmdLine); VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem); VOID RunLoader(VOID); VOID FrLdrCheckCpuCompatiblity(VOID);