diff --git a/bootdata/xtldr/xtldr.ini b/bootdata/xtldr/xtldr.ini index 4537da4..8bd454f 100644 --- a/bootdata/xtldr/xtldr.ini +++ b/bootdata/xtldr/xtldr.ini @@ -6,7 +6,6 @@ # Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate; # it is also possible to specify custom port address with: COM0:[address],[baud_rate] # Default - specifies which operating system listen in config file will be started if no choice is made -# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel # Timeout - sets the countdown timer (in seconds) before the default OS get started automatically # Tune - plays a tune on the pcspeaker right before the XTLDR loads # @@ -25,7 +24,6 @@ Tune=400 880 2 988 2 783 2 392 2 587 3 Debug=COM1,115200 Timeout=30 -Theme=Fancy Default=ExectOS [ExectOS] diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h new file mode 100644 index 0000000..60d52e5 --- /dev/null +++ b/sdk/xtdk/bltypes.h @@ -0,0 +1,89 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/bmtypes.h + * DESCRIPTION: XT Boot Manager structures definitions + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTDK_BMTYPES_H +#define __XTDK_BMTYPES_H + +#include +#include + + +/* XTLDR directories */ +#define XTBL_LOADER_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\" +#define XTBL_THEMES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\THEMES\\" + +/* XTLDR Debug Port type definitions */ +#define XTBL_DEBUGPORT_SCREEN 1 +#define XTBL_DEBUGPORT_SERIAL 2 + +/* Loader protocol routine pointers */ +typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory); +typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); +typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); +typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); +typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); +typedef VOID (*PBL_CONSOLE_PRINT)(IN PUINT16 Format, IN ...); +typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); +typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); +typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); +typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); +typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); + +/* XTLDR Configuration data */ +typedef struct _XTBL_CONFIGURATION +{ + PWCHAR Default; + PWCHAR Debug; + ULONG DebugPort; + BOOLEAN Shell; + ULONG Timeout; + PWCHAR Tune; +} XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; + +/* XTLDR Status data */ +typedef struct _XTBL_STATUS +{ + BOOLEAN BootServices; + EFI_HANDLE ImageHandle; + PEFI_SYSTEM_TABLE SystemTable; +} XTBL_STATUS, *PXTBL_STATUS; + +/* XTLDR Loader protocol */ +typedef struct _XTBL_LOADER_PROTOCOL +{ + struct + { + PBL_CONSOLE_CLEAR_SCREEN ClearScreen; + PBL_CONSOLE_DISABLE_CURSOR DisableCursor; + PBL_CONSOLE_ENABLE_CURSOR EnableCursor; + PBL_CONSOLE_PRINT Print; + } Console; + struct + { + PBL_DEBUG_PRINT Print; + } Debug; + struct + { + PBL_ALLOCATE_PAGES AllocatePages; + PBL_ALLOCATE_POOL AllocatePool; + PBL_FREE_PAGES FreePages; + PBL_FREE_POOL FreePool; + } Memory; + struct + { + PBL_OPEN_XT_PROTOCOL Open; + } Protocol; + struct + { + PBL_EXIT_BOOT_SERVICES ExitBootServices; + PBL_SLEEP_EXECUTION SleepExecution; + } Util; +} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; + +#endif /* __XTDK_BMTYPES_H */ diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtblapi.h similarity index 72% rename from sdk/xtdk/xtbmapi.h rename to sdk/xtdk/xtblapi.h index 35fab90..f58c149 100644 --- a/sdk/xtdk/xtbmapi.h +++ b/sdk/xtdk/xtblapi.h @@ -1,8 +1,8 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: sdk/xtdk/xtbmapi.h - * DESCRIPTION: Top level header for the XT Boot Manager API + * FILE: sdk/xtdk/xtblapi.h + * DESCRIPTION: Top level header for the XT Boot Loader API * DEVELOPERS: Rafal Kupiec */ @@ -16,7 +16,7 @@ #include /* Architecture-specific XT forward references */ -#include ARCH_HEADER(xtstruct.h) +// #include ARCH_HEADER(xtstruct.h) /* Architecture-independent XT API */ #include @@ -32,15 +32,16 @@ #include /* Architecture dependent XT kernel data types */ -#include ARCH_HEADER(artypes.h) -#include ARCH_HEADER(hltypes.h) +// #include ARCH_HEADER(artypes.h) +// #include ARCH_HEADER(hltypes.h) /* XT Kernel runtime routines */ +#include #include /* Architecture specific XT kernel routines */ -#include ARCH_HEADER(arfuncs.h) -#include ARCH_HEADER(hlfuncs.h) +// #include ARCH_HEADER(arfuncs.h) +// #include ARCH_HEADER(hlfuncs.h) /* Boot Manager specific structures */ -#include +#include diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 198e406..2004d41 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -10,9 +10,12 @@ include_directories( list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/config.c ${XTLDR_SOURCE_DIR}/console.c + ${XTLDR_SOURCE_DIR}/debug.c + ${XTLDR_SOURCE_DIR}/efiutils.c ${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.c + ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/xtldr.c) diff --git a/xtldr2/config.c b/xtldr2/config.c index b10257b..e854c55 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -7,7 +7,7 @@ * Jozef Nagy */ -#include +#include /** * Parses configuration INI file contents. @@ -117,7 +117,7 @@ BlConfigParseIniFile(IN PWCHAR FileContents, */ XTCDECL VOID -BlpConfigParseCommandLine(VOID) +BlpParseCommandLineOptions(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -131,7 +131,7 @@ BlpConfigParseCommandLine(VOID) if(LoadedImage && LoadedImage->LoadOptions) { /* Update global boot loader configuration */ - BlpConfigUpdateGlobalConfiguration(LoadedImage->LoadOptions); + BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions); } } } @@ -148,7 +148,7 @@ BlpConfigParseCommandLine(VOID) */ XTCDECL VOID -BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) +BlpUpdateGlobalConfiguration(IN PWCHAR Options) { PWCHAR Argument, LastArg; SIZE_T Length; @@ -177,27 +177,20 @@ BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) Argument += 6; Length = RtlWideStringLength(Argument, 0); - /* Save debug port in global configuration */ - BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Debug); - RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); - BlpConfiguration.Debug[Length] = '\0'; + /* Store debug port configuration if not set already */ + if(BlpConfiguration.Debug == NULL) + { + /* Save debug port in global configuration */ + BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Debug); + RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); + BlpConfiguration.Debug[Length] = '\0'; + } } else if(RtlWideStringCompare(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } - else if(RtlWideStringCompare(Argument, L"THEME=", 6) == 0) - { - /* Skip to the argument value */ - Argument += 6; - Length = RtlWideStringLength(Argument, 0); - - /* Save theme in global configuration */ - BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Theme); - RtlCopyMemory(BlpConfiguration.Theme, Argument, (Length * sizeof(WCHAR)) - 1); - BlpConfiguration.Theme[Length] = '\0'; - } else if(RtlWideStringCompare(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ diff --git a/xtldr2/console.c b/xtldr2/console.c index d96ab94..c0911c9 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -52,27 +52,6 @@ BlConsoleEnableCursor() EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); } -/** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlConsoleInitialize() -{ - /* Clear console buffers */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); - EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); - EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); - - /* Clear screen and enable cursor */ - BlConsoleClearScreen(); - BlConsoleEnableCursor(); -} - /** * This routine formats the input string and prints it out to the stdout and serial console. * @@ -99,10 +78,42 @@ BlConsolePrint(IN PUINT16 Format, /* Format and print the string to the stdout */ BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + /* Print to serial console only if not running under OVMF */ + if(RtlWideStringCompare(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) + { + /* Check if debugging enabled and if EFI serial port is fully initialized */ + if(DEBUG && (BlpSerialPort.Flags & COMPORT_FLAG_INIT)) + { + /* Format and print the string to the serial console */ + BlpStringPrint(BlpDebugPutChar, Format, Arguments); + } + } + /* Clean up the va_list */ VA_END(Arguments); } +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpConsoleInitialize() +{ + /* Clear console buffers */ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); + EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); + EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + + /* Clear screen and enable cursor */ + BlConsoleClearScreen(); + BlConsoleEnableCursor(); +} + /** * Writes a character to the default EFI console. * diff --git a/xtldr2/debug.c b/xtldr2/debug.c new file mode 100644 index 0000000..3a4b689 --- /dev/null +++ b/xtldr2/debug.c @@ -0,0 +1,260 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/debug.c + * DESCRIPTION: XT Boot Loader debugging support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine formats the input string and prints it out to the debug ports. + * + * @param Format + * The formatted string that is to be written to the output. + * + * @param ... + * Depending on the format string, this routine might expect a sequence of additional arguments. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDebugPrint(IN PUINT16 Format, + IN ...) +{ + VA_LIST Arguments; + + /* Check if debugging enabled and if EFI serial port is fully initialized */ + if(DEBUG) + { + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Check if serial debug port is enabled */ + if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpSerialPort.Flags & COMPORT_FLAG_INIT)) + { + /* Format and print the string to the serial console */ + BlpStringPrint(BlpDebugPutChar, Format, Arguments); + } + + /* Check if screen debug port is enabled and Boot Services are still available */ + if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) + { + /* Format and print the string to the screen */ + BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + } + + /* Clean up the va_list */ + VA_END(Arguments); + } +} + +/** + * This routine initializes the XTLDR debug console. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpInitializeDebugConsole() +{ + ULONG PortAddress, PortNumber, BaudRate; + PWCHAR DebugPort, LastPort; + EFI_STATUS Status; + + /* Set default serial port options */ + PortAddress = 0; + PortNumber = 0; + BaudRate = 0; + + /* Make sure any debug options are provided */ + if(BlpConfiguration.Debug) + { + /* Find all debug ports */ + DebugPort = RtlWideStringTokenize(BlpConfiguration.Debug, L";", &LastPort); + + /* Iterate over all debug ports */ + while(DebugPort != NULL) + { + /* Check what port is set for debugging */ + if(RtlWideStringCompare(DebugPort, L"COM", 3) == 0) + { + /* Read COM port number */ + DebugPort += 3; + while(*DebugPort >= '0' && *DebugPort <= '9') + { + /* Get port number */ + PortNumber *= 10; + PortNumber += *DebugPort - '0'; + DebugPort++; + } + + /* Check if custom COM port address supplied */ + if(PortNumber == 0 && RtlWideStringCompare(DebugPort, L":0x", 3) == 0) + { + /* COM port address provided */ + DebugPort += 3; + while((*DebugPort >= '0' && *DebugPort <= '9') || + (*DebugPort >= 'A' && *DebugPort <= 'F') || + (*DebugPort >= 'a' && *DebugPort <= 'f')) + { + /* Get port address */ + PortAddress *= 16; + if(*DebugPort >= '0' && *DebugPort <= '9') + { + PortAddress += *DebugPort - '0'; + } + else if(*DebugPort >= 'A' && *DebugPort <= 'F') + { + PortAddress += *DebugPort - 'A' + 10; + } + else if(*DebugPort >= 'a' && *DebugPort <= 'f') + { + PortAddress += *DebugPort - 'a' + 10; + } + DebugPort++; + } + } + + /* Look for additional COM port parameters */ + if(*DebugPort == ',') + { + /* Baud rate provided */ + DebugPort++; + while(*DebugPort >= '0' && *DebugPort <= '9') + { + /* Get baud rate */ + BaudRate *= 10; + BaudRate += *DebugPort - '0'; + DebugPort++; + } + } + + /* Enable debug port */ + BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; + } + else if(RtlWideStringCompare(DebugPort, L"SCREEN", 5) == 0) + { + /* Enable debug port */ + BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN; + } + else + { + /* Unsupported debug port specified */ + BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort); + BlSleepExecution(3000); + } + + /* Take next debug port */ + DebugPort = RtlWideStringTokenize(NULL, L";", &LastPort); + } + } + + /* Check if serial debug port is enabled */ + if(BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) + { + /* Try to initialize COM port */ + Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); + if(Status != STATUS_EFI_SUCCESS) + { + /* Remove serial debug port, as COM port initialization failed and return */ + BlpConfiguration.DebugPort &= ~XTBL_DEBUGPORT_SERIAL; + return Status; + } + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine initializes the serial debug console. + * + * @param PortNumber + * Supplies a port number. + * + * @param PortAddress + * Supplies an address of the COM port. + * + * @param BaudRate + * Supplies an optional port baud rate. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpInitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate) +{ + EFI_STATUS EfiStatus; + XTSTATUS Status; + + /* Print debug message depending on port settings */ + if(PortAddress) + { + BlConsolePrint(L"Initializing serial console at COM port address: 0x%lx\n", PortAddress); + } + else + { + BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber); + } + + /* Initialize COM port */ + Status = HlInitializeComPort(&BlpSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); + + /* Port not found under supplied address */ + if(Status == STATUS_NOT_FOUND && PortAddress) + { + /* This might be PCI(E) serial controller, try to activate I/O space access first */ + EfiStatus = BlpActivateSerialIOController(); + if(EfiStatus == STATUS_EFI_SUCCESS) + { + /* Try to reinitialize COM port */ + BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); + Status = HlInitializeComPort(&BlpSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); + } + } + + /* Check COM port initialization status code */ + if(Status != STATUS_SUCCESS) + { + /* Serial port initialization failed, mark as not ready */ + return STATUS_EFI_NOT_READY; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Writes a character to the serial console. + * + * @param Character + * The integer promotion of the character to be written. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpDebugPutChar(IN USHORT Character) +{ + USHORT Buffer[2]; + + /* Write character to the serial console */ + Buffer[0] = Character; + Buffer[1] = 0; + + HlComPortPutByte(&BlpSerialPort, Buffer[0]); +} diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c new file mode 100644 index 0000000..104db69 --- /dev/null +++ b/xtldr2/efiutils.c @@ -0,0 +1,82 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/efiutils.c + * DESCRIPTION: EFI related routines for XT Boot Loader + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Exits EFI boot services. + * + * @param MapKey + * Identifies the current memory map of the system. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlExitBootServices(IN UINT_PTR MapKey) +{ + EFI_STATUS Status; + + /* Attempt to exit boot services */ + Status = EfiSystemTable->BootServices->ExitBootServices(BlpStatus.ImageHandle, MapKey); + if(Status != STATUS_EFI_SUCCESS) + { + /* Retry as UEFI spec says to do it twice */ + Status = EfiSystemTable->BootServices->ExitBootServices(BlpStatus.ImageHandle, MapKey); + } + + /* Make sure boot services were successfully exited */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Mark EFI Boot Services as no longer available */ + BlpStatus.BootServices = FALSE; + } + + /* Return EFI status code */ + return Status; +} + +/** + * Puts the system to sleep for the specified number of milliseconds. + * + * @param Milliseconds + * Supplies the number of milliseconds to sleep. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlSleepExecution(IN ULONG_PTR Milliseconds) +{ + EfiSystemTable->BootServices->Stall(Milliseconds * 1000); +} + +/** + * Initializes EFI Boot Loader (XTLDR). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpInitializeEfiBootLoader() +{ + /* Set current XTLDR status */ + BlpStatus.BootServices = TRUE; + BlpStatus.ImageHandle = EfiImageHandle; + BlpStatus.SystemTable = EfiSystemTable; + + /* Initialize console */ + BlpConsoleInitialize(); +} diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 14277ac..6017862 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -6,11 +6,11 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /* XT Boot Loader configuration data */ -XTBM_CONFIGURATION BlpConfiguration = {0}; +XTBL_CONFIGURATION BlpConfiguration = {0}; /* XT Boot Loader hex table */ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; @@ -18,6 +18,9 @@ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; /* Serial port configuration */ CPPORT BlpSerialPort; +/* XT Boot Loader status data */ +XTBL_STATUS BlpStatus = {0}; + /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/hardware.c b/xtldr2/hardware.c index 8cf2a47..4b6e6b7 100644 --- a/xtldr2/hardware.c +++ b/xtldr2/hardware.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,7 +18,7 @@ */ XTCDECL EFI_STATUS -BlpHwActivateSerialIOController() +BlpActivateSerialIOController() { EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index e2a05b1..5b03b5b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -1,7 +1,7 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/xtbm.h + * FILE: xtldr/includes/bootman.h * DESCRIPTION: XTLDR Boot Loader related structures and routines forward references * DEVELOPERS: Rafal Kupiec */ @@ -9,23 +9,27 @@ #ifndef __XTLDR_BOOTMAN_H #define __XTLDR_BOOTMAN_H -#include +#include /* XTLDR routine callbacks */ typedef VOID (BMPRINTCHAR)(IN USHORT Character); +/* XTLDR routines forward references */ +XTCDECL +EFI_STATUS +BlExitBootServices(IN UINT_PTR MapKey); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory); + OUT PEFI_PHYSICAL_ADDRESS Memory); XTCDECL EFI_STATUS BlMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory); + OUT PVOID *Memory); -/* XTLDR routines forward references */ XTCDECL VOID BlConsoleClearScreen(); @@ -38,24 +42,54 @@ XTCDECL VOID BlConsoleEnableCursor(); +XTCDECL +VOID +BlConsolePrint(IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BlDebugPrint(IN PUINT16 Format, + IN ...); + XTCDECL EFI_STATUS -BlMemoreFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory); +BlMemoryFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory); XTCDECL EFI_STATUS BlMemoryFreePool(IN PVOID Memory); +XTCDECL +EFI_STATUS +BlOpenXtProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); XTCDECL VOID -BlConsoleInitialize(); +BlSleepExecution(IN ULONG_PTR Milliseconds); + +XTCDECL +EFI_STATUS +BlStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +XTCDECL +EFI_STATUS +BlpActivateSerialIOController(); XTCDECL VOID -BlConsolePrint(IN PUINT16 Format, - IN ...); +BlpParseCommandLineOptions(VOID); + +XTCDECL +VOID +BlpUpdateGlobalConfiguration(IN PWCHAR Options); + +XTCDECL +VOID +BlpConsoleInitialize(); XTCDECL VOID @@ -63,15 +97,25 @@ BlpConsolePrintChar(IN USHORT Character); XTCDECL VOID -BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN VA_LIST Arguments); +BlpDebugPutChar(IN USHORT Character); XTCDECL EFI_STATUS -BmStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); +BlpInitializeDebugConsole(); +XTCDECL +VOID +BlpInitializeEfiBootLoader(); + +XTCDECL +EFI_STATUS +BlpInitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate); + +XTCDECL +EFI_STATUS +BlpRegisterXtLoaderProtocol(); XTCDECL VOID @@ -86,7 +130,9 @@ BlConfigParseIniFile(IN PWCHAR FileContents, XTCDECL VOID -BlpConfigParseCommandLine(VOID); +BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments); XTCDECL VOID @@ -118,8 +164,4 @@ XTCDECL UINT64 BlpStringReadPadding(IN PUINT16 *Format); -XTCDECL -VOID -BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options); - #endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 5b652fc..b6d22c0 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -1,7 +1,7 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/xtbm.h + * FILE: xtldr/includes/globals.h * DESCRIPTION: XTLDR global variables * DEVELOPERS: Rafal Kupiec */ @@ -9,10 +9,10 @@ #ifndef __XTLDR_GLOBALS_H #define __XTLDR_GLOBALS_H -#include +#include /* XT Boot Loader configuration data */ -EXTERN XTBM_CONFIGURATION BlpConfiguration; +EXTERN XTBL_CONFIGURATION BlpConfiguration; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; @@ -20,6 +20,9 @@ EXTERN PUINT16 BlpHexTable; /* Serial port configuration */ EXTERN CPPORT BlpSerialPort; +/* XT Boot Loader status data */ +EXTERN XTBL_STATUS BlpStatus; + /* EFI Image Handle */ EXTERN EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/includes/xtbm.h b/xtldr2/includes/xtldr.h similarity index 66% rename from xtldr2/includes/xtbm.h rename to xtldr2/includes/xtldr.h index 7a9c9d4..497b0b1 100644 --- a/xtldr2/includes/xtbm.h +++ b/xtldr2/includes/xtldr.h @@ -1,18 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/xtbm.h + * FILE: xtldr/includes/xtldr.h * DESCRIPTION: Top level header for XTLDR * DEVELOPERS: Rafal Kupiec */ -#ifndef __XTLDR_XTBM_H -#define __XTLDR_XTBM_H +#ifndef __XTLDR_XTLDR_H +#define __XTLDR_XTLDR_H -#include +#include #include #include #include -#endif /* __XTLDR_XTBM_H */ +#endif /* __XTLDR_XTLDR_H */ diff --git a/xtldr2/memory.c b/xtldr2/memory.c index 6ef6998..19e9397 100644 --- a/xtldr2/memory.c +++ b/xtldr2/memory.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -67,7 +67,7 @@ BlMemoryAllocatePool(IN UINT_PTR Size, */ XTCDECL EFI_STATUS -BlMemoreFreePages(IN UINT64 Pages, +BlMemoryFreePages(IN UINT64 Pages, IN EFI_PHYSICAL_ADDRESS Memory) { return EfiSystemTable->BootServices->FreePages(Memory, Pages); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c new file mode 100644 index 0000000..34aa2bb --- /dev/null +++ b/xtldr2/protocol.c @@ -0,0 +1,109 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/protocol.c + * DESCRIPTION: XT Boot Loader protocol support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine locates and opens the requested XT boot loader protocol. + * + * @param ProtocolHandler + * Supplies the address where a pointer to the opened protocol is returned. + * + * @param ProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlOpenXtProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) +{ + PEFI_HANDLE Handles = NULL; + EFI_STATUS Status; + UINT_PTR Count; + UINT Index; + + /* Try to locate the handles */ + Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULL, &Count, &Handles); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get handles */ + return Status; + } + + /* Check if any handles returned */ + if(Count > 0) + { + /* Iterate through all given handles */ + for(Index = 0; Index < Count; Index++) + { + /* Try to open protocol */ + Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], ProtocolGuid, + ProtocolHandler, EfiImageHandle, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + + /* Check if successfully opened the loader protocol */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Protocol found and successfully opened */ + break; + } + } + } + + /* Free handles */ + EfiSystemTable->BootServices->FreePool(Handles); + + /* Make sure the loaded protocol has been found */ + if(*ProtocolHandler == NULL) + { + /* Protocol not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine registers XTLDR protocol for further usage by modules. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpRegisterXtLoaderProtocol() +{ + EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; + XTBL_LOADER_PROTOCOL LdrProtocol; + EFI_HANDLE Handle = NULL; + + /* Set all routines available via loader protocol */ + LdrProtocol.Console.ClearScreen = BlConsoleClearScreen; + LdrProtocol.Console.DisableCursor = BlConsoleDisableCursor; + LdrProtocol.Console.EnableCursor = BlConsoleEnableCursor; + LdrProtocol.Console.Print = BlConsolePrint; + LdrProtocol.Debug.Print = BlDebugPrint; + LdrProtocol.Memory.AllocatePages = BlMemoryAllocatePages; + LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; + LdrProtocol.Memory.FreePages = BlMemoryFreePages; + LdrProtocol.Memory.FreePool = BlMemoryFreePool; + LdrProtocol.Protocol.Open = BlOpenXtProtocol; + LdrProtocol.Util.ExitBootServices = BlExitBootServices; + LdrProtocol.Util.SleepExecution = BlSleepExecution; + + /* Register XTLDR loader protocol */ + BlDebugPrint(L"Registering XT loader protocol\n"); + return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, &LdrProtocol); +} diff --git a/xtldr2/string.c b/xtldr2/string.c index 58b0d86..991fbce 100644 --- a/xtldr2/string.c +++ b/xtldr2/string.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index feac3d5..b21c1c8 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -43,8 +43,41 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, /* Parse INI Configuration file */ BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default - specifies which operating system listen in config file will be started if no choice is made\n# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# SystemName - sets a long operating system name that will be shown on the boot menu\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile - sets kernel filename with optional path relative to SystemPath\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\n# HalFile - sets HAL filename with optional path relative to SystemPath\n# Parameters - specifies extra boot options for the kernel\n[XTLDR]Tune=400 880 2 988 2 783 2 392 2 587 3Debug=COM1,115200Timeout=30Theme=FancyDefault=ExectOS[ExectOS]SystemName=\"ExectOS Operating System\"SystemType=XTOSSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOSKernelFile=xtoskrnl.exeParameters=DEBUG DEBUGPORT=COM1,115200[Windows]SystemName=\"Microsoft Windows 2000\"SystemType=NT50SystemPath=multi(0)disk(0)rdisk(0)partition(2)/WindowsKernelFile=ntoskrnl.exeHalFile=hal.dllParameters=/NOGUIBOOT /MININT[Linux]SystemName=\"GNU/Linux\"SystemType=LINUXSystemPath=multi(0)disk(0)rdisk(0)partition(3)/bootKernelFile=vmlinuzInitrdFile=initramfs.cpio.gzParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); + /* Initialize XTLDR and early print XTLDR version */ + BlpInitializeEfiBootLoader(); BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + /* Parse configuration options passed from UEFI shell */ + BlpParseCommandLineOptions(); + + /* Attempt to early initialize debug console */ + if(DEBUG) + { + Status = BlpInitializeDebugConsole(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Initialization failed, notify user on stdout */ + BlConsolePrint(L"ERROR: Failed to initialize debug console\n"); + BlSleepExecution(3000); + } + } + + /* Disable watchdog timer */ + Status = EfiSystemTable->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to disable the timer, print message */ + BlDebugPrint(L"WARNING: Failed to disable watchdog timer\n"); + } + + /* Register loader protocol */ + Status = BlpRegisterXtLoaderProtocol(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to register loader protocol */ + BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol\n"); + } + /* Temporary infinite loop */ for(;;);