From 7f41f83026d7c4aaa3b2af5241101ec6765fafe1 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 2 Dec 2023 19:11:59 +0100 Subject: [PATCH 001/182] Add common header for XTLDR and its modules --- sdk/xtdk/xtbmapi.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 sdk/xtdk/xtbmapi.h diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtbmapi.h new file mode 100644 index 0000000..8ab3f07 --- /dev/null +++ b/sdk/xtdk/xtbmapi.h @@ -0,0 +1,19 @@ +/** + * 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 + * DEVELOPERS: Rafal Kupiec + */ + +/* Base XT headers */ +#include +#include +#include +#include + +/* Architecture-independent XT API */ +#include +#include +#include +#include -- 2.45.1 From 4076175436113dd2bfbf5c6b0882fcb94c98115b Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 2 Dec 2023 22:24:58 +0100 Subject: [PATCH 002/182] Initial XTLDR import --- CMakeLists.txt | 2 +- xtldr2/CMakeLists.txt | 34 ++++++++++++++++++++++++++++++++++ xtldr2/README.md | 14 ++++++++++++++ xtldr2/globals.c | 16 ++++++++++++++++ xtldr2/includes/xtbm.h | 29 +++++++++++++++++++++++++++++ xtldr2/xtldr.c | 38 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 xtldr2/CMakeLists.txt create mode 100644 xtldr2/README.md create mode 100644 xtldr2/globals.c create mode 100644 xtldr2/includes/xtbm.h create mode 100644 xtldr2/xtldr.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bc2200c..b9bf79e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,5 +70,5 @@ set_disk_image_size(128) # Build all subprojects add_subdirectory(bootdata) -add_subdirectory(xtldr) +add_subdirectory(xtldr2) add_subdirectory(xtoskrnl) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt new file mode 100644 index 0000000..084d603 --- /dev/null +++ b/xtldr2/CMakeLists.txt @@ -0,0 +1,34 @@ +# XT Boot Manager +PROJECT(XTLDR) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/globals.c + ${XTLDR_SOURCE_DIR}/xtldr.c) + +# Link static XTLDR library +add_library(libxtldr ${XTLDR_SOURCE}) + +# Link bootloader executable +add_executable(xtldr ${XTLDR_SOURCE}) + +# Add linker libraries +target_link_libraries(xtldr libxtos) + +# Set proper binary name and install target +if(ARCH STREQUAL "i686") + set(BINARY_NAME "bootia32") +elseif(ARCH STREQUAL "amd64") + set(BINARY_NAME "bootx64") +endif() +set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi) +set_install_target(xtldr efi/boot) + +# Set loader entrypoint and subsystem +set_entrypoint(xtldr "BmStartXtLoader") +set_subsystem(xtldr efi_application) diff --git a/xtldr2/README.md b/xtldr2/README.md new file mode 100644 index 0000000..ae4fe9f --- /dev/null +++ b/xtldr2/README.md @@ -0,0 +1,14 @@ +## XT Boot Manager (XTLDR) +The XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS. +As an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems, +like old and deprecated BIOS. + +One of the notable features of XTLDR is its modular design. The boot loader is divided into different modules, with only +the essential core being loaded during the boot process. This modular approach allows for a more efficient and +streamlined boot experience, as only the necessary functionality is loaded, reducing the boot time and system resource +usage. + +XTLDR includes various modules that provide specific functionalities required for the boot process. For example, there is +a module dedicated to supporting the XTOS boot protocol, which is the specific protocol used by XTOS for loading and +executing the OS kernel. Additionally, there is a module for handling PE/COFF (Portable Executable) binaries, which is +a commonly used format of executable files used by the XTOS. diff --git a/xtldr2/globals.c b/xtldr2/globals.c new file mode 100644 index 0000000..dda53f5 --- /dev/null +++ b/xtldr2/globals.c @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/globals.c + * DESCRIPTION: XT Boot Manager global variables + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* EFI Image Handle */ +EFI_HANDLE EfiImageHandle; + +/* EFI System Table */ +PEFI_SYSTEM_TABLE EfiSystemTable; diff --git a/xtldr2/includes/xtbm.h b/xtldr2/includes/xtbm.h new file mode 100644 index 0000000..252d1e2 --- /dev/null +++ b/xtldr2/includes/xtbm.h @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/includes/xtbm.h + * DESCRIPTION: Top level header for XTLDR + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_XTBM_H +#define __XTLDR_XTBM_H + +#include +#include + + +/* EFI Image Handle */ +EXTERN EFI_HANDLE EfiImageHandle; + +/* EFI System Table */ +EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; + + +/* XTLDR routines forward references */ +XTCDECL +EFI_STATUS +BmStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif /* __XTLDR_XTBM_H */ diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c new file mode 100644 index 0000000..5c1df65 --- /dev/null +++ b/xtldr2/xtldr.c @@ -0,0 +1,38 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/xtldr.c + * DESCRIPTION: XTOS UEFI Boot Manager + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine is the entry point of the XT EFI boot manager. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_STATUS Status; + + /* Set the system table and image handle */ + EfiImageHandle = ImageHandle; + EfiSystemTable = SystemTable; + + /* This point should be never reached, if this happen return error code */ + return STATUS_EFI_LOAD_ERROR; +} -- 2.45.1 From 03b6e9cd907f04e1954c17786fba692dc899f9ae Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 2 Dec 2023 22:38:58 +0100 Subject: [PATCH 003/182] Initialize the UEFI console --- xtldr2/CMakeLists.txt | 1 + xtldr2/console.c | 48 ++++++++++++++++++++++++++++++++++++++++++ xtldr2/includes/xtbm.h | 8 +++++++ xtldr2/xtldr.c | 3 +++ 4 files changed, 60 insertions(+) create mode 100644 xtldr2/console.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 084d603..3da0dc2 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -8,6 +8,7 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/xtldr.c) diff --git a/xtldr2/console.c b/xtldr2/console.c new file mode 100644 index 0000000..0bf55d1 --- /dev/null +++ b/xtldr2/console.c @@ -0,0 +1,48 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/console.c + * DESCRIPTION: EFI console support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine clears the UEFI console screen. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmClearScreen() +{ + /* Clear screen */ + EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); +} + +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmInitializeConsole() +{ + /* Clear console buffers */ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); + EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); + EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + + /* Clear screen */ + BmClearScreen(); + + /* Enable cursor */ + EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); +} diff --git a/xtldr2/includes/xtbm.h b/xtldr2/includes/xtbm.h index 252d1e2..d3fe630 100644 --- a/xtldr2/includes/xtbm.h +++ b/xtldr2/includes/xtbm.h @@ -21,6 +21,14 @@ EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; /* XTLDR routines forward references */ +XTCDECL +VOID +BmClearScreen(); + +XTCDECL +VOID +BmInitializeConsole(); + XTCDECL EFI_STATUS BmStartXtLoader(IN EFI_HANDLE ImageHandle, diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 5c1df65..22ac4cb 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -33,6 +33,9 @@ BmStartXtLoader(IN EFI_HANDLE ImageHandle, EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; + /* Initialize UEFI console */ + BmInitializeConsole(); + /* This point should be never reached, if this happen return error code */ return STATUS_EFI_LOAD_ERROR; } -- 2.45.1 From b1ef23148bd96af47b218239a464fc14fd321ff0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 2 Dec 2023 22:48:30 +0100 Subject: [PATCH 004/182] Let UEFI firmware load xtldr into lower half --- xtldr2/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 3da0dc2..22258dd 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -31,5 +31,6 @@ set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi) set_install_target(xtldr efi/boot) # Set loader entrypoint and subsystem +set_imagebase(xtldr ${BASEADDRESS_XTLDR}) set_entrypoint(xtldr "BmStartXtLoader") set_subsystem(xtldr efi_application) -- 2.45.1 From f0fbeadc1cf2095e52ca50a5c59ddd6de1db4e8c Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 2 Dec 2023 23:51:22 +0100 Subject: [PATCH 005/182] Implement BmDisableCursor(), BmEnableCursor() and BmPrintChar() routines --- xtldr2/console.c | 56 +++++++++++++++++++++++++++++++++++++++--- xtldr2/includes/xtbm.h | 12 +++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/xtldr2/console.c b/xtldr2/console.c index 0bf55d1..7bfd862 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -24,6 +24,34 @@ BmClearScreen() EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); } +/** + * Disables the cursor on the UEFI console. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmDisableCursor() +{ + EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); +} + +/** + * Enables the cursor on the UEFI console. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmEnableCursor() +{ + EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); +} + /** * This routine initializes the EFI console. * @@ -40,9 +68,29 @@ BmInitializeConsole() EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); - /* Clear screen */ + /* Clear screen and enable cursor */ BmClearScreen(); - - /* Enable cursor */ - EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); + BmEnableCursor(); +} + +/** + * Writes a character to the default EFI 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 +BmPrintChar(IN USHORT Character) +{ + USHORT Buffer[2]; + + /* Write character to the screen console */ + Buffer[0] = Character; + Buffer[1] = 0; + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); } diff --git a/xtldr2/includes/xtbm.h b/xtldr2/includes/xtbm.h index d3fe630..53224d7 100644 --- a/xtldr2/includes/xtbm.h +++ b/xtldr2/includes/xtbm.h @@ -25,10 +25,22 @@ XTCDECL VOID BmClearScreen(); +XTCDECL +VOID +BmDisableCursor(); + +XTCDECL +VOID +BmEnableCursor(); + XTCDECL VOID BmInitializeConsole(); +XTCDECL +VOID +BmPrintChar(IN USHORT Character); + XTCDECL EFI_STATUS BmStartXtLoader(IN EFI_HANDLE ImageHandle, -- 2.45.1 From 78ac03b0396795d3502a56c3764605b687da7c30 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 00:24:56 +0100 Subject: [PATCH 006/182] Add string manipulation support --- xtldr2/CMakeLists.txt | 1 + xtldr2/globals.c | 3 + xtldr2/includes/bootman.h | 86 ++++++++ xtldr2/includes/globals.h | 24 +++ xtldr2/includes/xtbm.h | 35 +-- xtldr2/string.c | 444 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 560 insertions(+), 33 deletions(-) create mode 100644 xtldr2/includes/bootman.h create mode 100644 xtldr2/includes/globals.h create mode 100644 xtldr2/string.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 22258dd..43e1747 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/globals.c + ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library diff --git a/xtldr2/globals.c b/xtldr2/globals.c index dda53f5..10ba127 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -9,6 +9,9 @@ #include +/* XT Boot Loader hex table */ +STATIC PUINT16 BmpHexTable = L"0123456789ABCDEF"; + /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h new file mode 100644 index 0000000..20c7cdf --- /dev/null +++ b/xtldr2/includes/bootman.h @@ -0,0 +1,86 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/includes/xtbm.h + * DESCRIPTION: XTLDR Boot Manager related structures and routines forward references + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_BOOTMAN_H +#define __XTLDR_BOOTMAN_H + +#include + + +/* XTLDR routine callbacks */ +typedef VOID (BMPRINTCHAR)(IN USHORT Character); + +/* XTLDR routines forward references */ +XTCDECL +VOID +BmClearScreen(); + +XTCDECL +VOID +BmDisableCursor(); + +XTCDECL +VOID +BmEnableCursor(); + +XTCDECL +VOID +BmInitializeConsole(); + +XTCDECL +VOID +BmPrintChar(IN USHORT Character); + +XTCDECL +VOID +BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments); + +XTCDECL +EFI_STATUS +BmStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +XTCDECL +VOID +BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, + IN INT Number, + IN UINT Base); + +XTCDECL +VOID +BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, + IN INT_PTR Number, + IN UINT_PTR Base); + +XTCDECL +VOID +BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, + IN UINT Number, + IN UINT Base, + IN UINT Padding); + +XTCDECL +VOID +BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, + IN UINT_PTR Number, + IN UINT_PTR Base, + IN UINT_PTR Padding); + +XTCDECL +UINT64 +BmpReadStringPadding(IN PUINT16 *Format); + +#endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h new file mode 100644 index 0000000..ca7dcda --- /dev/null +++ b/xtldr2/includes/globals.h @@ -0,0 +1,24 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/includes/xtbm.h + * DESCRIPTION: XTLDR global variables + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_GLOBALS_H +#define __XTLDR_GLOBALS_H + +#include + + +/* XT Boot Loader hex table */ +EXTERN PUINT16 BmpHexTable; + +/* EFI Image Handle */ +EXTERN EFI_HANDLE EfiImageHandle; + +/* EFI System Table */ +EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; + +#endif /* __XTLDR_GLOBALS_H */ diff --git a/xtldr2/includes/xtbm.h b/xtldr2/includes/xtbm.h index 53224d7..7a9c9d4 100644 --- a/xtldr2/includes/xtbm.h +++ b/xtldr2/includes/xtbm.h @@ -12,38 +12,7 @@ #include #include - -/* EFI Image Handle */ -EXTERN EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; - - -/* XTLDR routines forward references */ -XTCDECL -VOID -BmClearScreen(); - -XTCDECL -VOID -BmDisableCursor(); - -XTCDECL -VOID -BmEnableCursor(); - -XTCDECL -VOID -BmInitializeConsole(); - -XTCDECL -VOID -BmPrintChar(IN USHORT Character); - -XTCDECL -EFI_STATUS -BmStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); +#include +#include #endif /* __XTLDR_XTBM_H */ diff --git a/xtldr2/string.c b/xtldr2/string.c new file mode 100644 index 0000000..be812c5 --- /dev/null +++ b/xtldr2/string.c @@ -0,0 +1,444 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/string.c + * DESCRIPTION: EFI string manipulation support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine formats the input string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Format + * The formatted string that is to be written to the specified device. + * + * @param Arguments + * A value identifying a variable arguments list initialized with VA_START. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments) +{ + PEFI_GUID Guid; + PUCHAR String; + PWCHAR WideString; + ULONG PaddingCount; + + /* Read the variable arguments */ + for(; *Format; ++Format) + { + switch(*Format) + { + case L'%': + switch(*++Format) + { + case L'b': + /* Boolean */ + BmpFormatString(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); + break; + case L'c': + /* Character */ + PrintCharRoutine(VA_ARG(Arguments, INT)); + break; + case L'd': + /* Signed 32-bit integer */ + BmpPrintSigned32String(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); + break; + case L'g': + /* EFI GUID */ + Guid = VA_ARG(Arguments, PEFI_GUID); + BmpFormatString(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, + Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], + Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]); + break; + case L'l': + /* 64-bit numbers */ + switch(*++Format) + { + case L'd': + /* Signed 64-bit integer */ + BmpPrintSigned64String(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); + break; + case L'u': + /* Unsigned 64-bit integer */ + BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); + break; + case L'x': + /* Unsigned 64-bit hexadecimal integer */ + BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); + break; + default: + /* Unknown by default */ + PrintCharRoutine(L'?'); + break; + } + break; + case L'p': + /* Pointer address */ + BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); + break; + case L's': + /* String of characters */ + String = VA_ARG(Arguments, PUCHAR); + while(*String) + { + PrintCharRoutine(*String++); + } + break; + case L'S': + WideString = VA_ARG(Arguments, PWCHAR); + while(*WideString) + { + PrintCharRoutine((UCHAR)*WideString++); + } + break; + case L'u': + /* Unsigned 32-bit integer */ + BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0); + break; + case L'x': + /* Unsigned 32-bit hexadecimal integer */ + BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0); + break; + case L'0': + /* Zero padded numbers */ + ++Format; + PaddingCount = BmpReadStringPadding(&Format); + switch(*Format) + { + case L'd': + /* Zero-padded, signed 32-bit integer */ + BmpPrintSigned32String(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); + break; + case L'l': + /* 64-bit numbers */ + switch(*++Format) + { + case L'd': + /* Zero-padded, signed 64-bit integer */ + BmpPrintSigned64String(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); + break; + case L'u': + /* Zero-padded, unsigned 64-bit integer */ + BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); + break; + case L'x': + /* Zero-padded, unsigned 64-bit hexadecimal integer */ + BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); + break; + default: + /* Unknown by default */ + PrintCharRoutine(L'?'); + break; + } + break; + case L'u': + /* Zero-padded, unsigned 32-bit integer */ + BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount); + break; + case L'x': + /* Zero-padded, unsigned 32-bit hexadecimal integer */ + BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount); + break; + default: + /* Unknown by default */ + PrintCharRoutine(L'?'); + break; + } + break; + case L'%': + /* Percent character */ + PrintCharRoutine(L'%'); + break; + default: + /* Unknown by default */ + PrintCharRoutine(L'?'); + break; + } + break; + case L'\r': + /* Carriage return is ignored */ + break; + case L'\n': + /* New line together with carriage return */ + PrintCharRoutine(L'\r'); + PrintCharRoutine(L'\n'); + break; + default: + /* Put character by default */ + PrintCharRoutine(*Format); + break; + } + } +} + +/** + * This routine formats the input string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Format + * The formatted string that is to be written to the specified device. + * + * @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 +BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN ...) +{ + VA_LIST Arguments; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Format and print the string to the desired output */ + BmPrintString(PrintCharRoutine, Format, Arguments); + + /* Clean up the va_list */ + VA_END(Arguments); +} + +/** + * This routine converts 32-bit integer as string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Number + * 32-bit integer value. + * + * @param Base + * Specifies the number base system representation. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, + IN INT Number, + IN UINT Base) +{ + /* Print - (minus) if this is negative value */ + if(Number < 0) + { + PrintCharRoutine(L'-'); + Number *= -1; + } + + /* Print the integer value */ + BmpPrintUnsigned32String(PrintCharRoutine, Number, Base, 0); +} + +/** + * This routine converts 64-bit integer as string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Number + * 64-bit integer value. + * + * @param Base + * Specifies the number base system representation. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, + IN INT_PTR Number, + IN UINT_PTR Base) +{ + /* Print - (minus) if this is negative value */ + if(Number < 0) + { + PrintCharRoutine(L'-'); + Number *= -1; + } + + /* Print the integer value */ + BmpPrintUnsigned64String(PrintCharRoutine, Number, Base, 0); +} + +/** + * This routine converts 32-bit unsigned integer as string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Number + * 32-bit integer value. + * + * @param Base + * Specifies the number base system representation. + * + * @param Padding + * Specifies the number of leading zeros to complete the field width. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, + IN UINT Number, + IN UINT Base, + IN UINT Padding) +{ + UINT Buffer[20]; + UINT NumberLength; + PUINT Pointer; + + /* Set pointer to the end of buffer */ + Pointer = Buffer + ARRAY_SIZE(Buffer); + + /* Convert value to specified base system */ + *--Pointer = 0; + do + { + *--Pointer = BmpHexTable[Number % Base]; + } while(Pointer >= Buffer && (Number /= Base)); + + /* Calculate number length */ + NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; + + /* Check if leading zeros are needed */ + if(NumberLength < Padding) + { + Padding -= NumberLength; + while(Padding--) + { + /* Write leading zeroes */ + PrintCharRoutine(L'0'); + } + } + + /* Print value to the console */ + for(; *Pointer; ++Pointer) + { + PrintCharRoutine(*Pointer); + } +} + +/** + * This routine converts 64-bit unsigned integer as string and prints it using specified routine. + * + * @param PrintCharRoutine + * Pointer to the routine that writes an input data to specific device. + * + * @param Number + * 64-bit integer value. + * + * @param Base + * Specifies the number base system representation. + * + * @param Padding + * Specifies the number of leading zeros to complete the field width. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, + IN UINT_PTR Number, + IN UINT_PTR Base, + IN UINT_PTR Padding) +{ + UINT16 Buffer[20]; + UINT_PTR NumberLength; + PUINT16 Pointer; + + /* Set pointer to the end of buffer */ + Pointer = Buffer + ARRAY_SIZE(Buffer); + + /* Convert value to specified base system */ + *--Pointer = 0; + do + { + *--Pointer = BmpHexTable[Number % Base]; + } while(Pointer >= Buffer && (Number /= Base)); + + /* Calculate number length */ + NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; + + /* Check if leading zeros are needed */ + if(NumberLength < Padding) + { + Padding -= NumberLength; + while(Padding--) + { + /* Write leading zeroes */ + PrintCharRoutine(L'0'); + } + } + + /* Print value to the console */ + for(; *Pointer; ++Pointer) + { + PrintCharRoutine(*Pointer); + } +} + +/** + * Reads the number of padding characters from the format string. + * + * @param Format + * The format string. + * + * @return Number of padding characters. + * + * @since XT 1.0 + */ +XTCDECL +UINT64 +BmpReadStringPadding(IN PUINT16 *Format) +{ + ULONG Count = 0; + PUINT16 Fmt = *Format; + + /* Read the padding */ + for(;; ++Fmt) + { + switch(*Fmt) + { + case L'0' ... L'9': + /* Check the number of leading zeroes */ + Count = Count * 10 + *Fmt - L'0'; + break; + default: + /* No padding by default */ + *Format = Fmt; + return Count; + } + } + + /* No padding by default */ + return 0; +} -- 2.45.1 From 26cee38e31ba7bc7e9aa788cd67a88cab7670b18 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 00:39:55 +0100 Subject: [PATCH 007/182] Include more headers --- sdk/xtdk/xtbmapi.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtbmapi.h index 8ab3f07..d0de696 100644 --- a/sdk/xtdk/xtbmapi.h +++ b/sdk/xtdk/xtbmapi.h @@ -12,8 +12,31 @@ #include #include +/* XT forward references */ +#include + +/* Architecture-specific XT forward references */ +#include ARCH_HEADER(xtstruct.h) + /* Architecture-independent XT API */ #include #include #include #include +#include +#include + +/* Architecture independent XT kernel data types */ +#include +#include + +/* Architecture dependent XT kernel data types */ +#include ARCH_HEADER(artypes.h) +#include ARCH_HEADER(hltypes.h) + +/* XT Kernel runtime routines */ +#include + +/* Architecture specific XT kernel routines */ +#include ARCH_HEADER(arfuncs.h) +#include ARCH_HEADER(hlfuncs.h) -- 2.45.1 From 6ba0557392db8c97e02a2a89b7b26b83d52af77f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 00:40:25 +0100 Subject: [PATCH 008/182] Add missing whitespace character to the comment --- sdk/xtdk/xtkmapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/xtdk/xtkmapi.h b/sdk/xtdk/xtkmapi.h index ecaa892..15813cd 100644 --- a/sdk/xtdk/xtkmapi.h +++ b/sdk/xtdk/xtkmapi.h @@ -48,6 +48,6 @@ #include #include -/* Architecture specific XT routines*/ +/* Architecture specific XT routines */ #include ARCH_HEADER(arfuncs.h) #include ARCH_HEADER(hlfuncs.h) -- 2.45.1 From f161b37fafeb25efd9fdb9cfbc6f24c3d94b2849 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 00:43:13 +0100 Subject: [PATCH 009/182] Implement BmPrint() routine --- xtldr2/console.c | 30 ++++++++++++++++++++++++++++++ xtldr2/globals.c | 3 +++ xtldr2/includes/bootman.h | 5 +++++ xtldr2/includes/globals.h | 3 +++ 4 files changed, 41 insertions(+) diff --git a/xtldr2/console.c b/xtldr2/console.c index 7bfd862..e9f0d16 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -73,6 +73,36 @@ BmInitializeConsole() BmEnableCursor(); } +/** + * This routine formats the input string and prints it out to the stdout and serial console. + * + * @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 +BmPrint(IN PUINT16 Format, + IN ...) +{ + VA_LIST Arguments; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Format and print the string to the stdout */ + BmPrintString(BmPrintChar, Format, Arguments); + + /* Clean up the va_list */ + VA_END(Arguments); +} + /** * Writes a character to the default EFI console. * diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 10ba127..ef1cbbc 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -12,6 +12,9 @@ /* XT Boot Loader hex table */ STATIC PUINT16 BmpHexTable = L"0123456789ABCDEF"; +/* Serial port configuration */ +CPPORT BmpSerialPort; + /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 20c7cdf..6a449ce 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -32,6 +32,11 @@ XTCDECL VOID BmInitializeConsole(); +XTCDECL +VOID +BmPrint(IN PUINT16 Format, + IN ...); + XTCDECL VOID BmPrintChar(IN USHORT Character); diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index ca7dcda..a9b2fab 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -15,6 +15,9 @@ /* XT Boot Loader hex table */ EXTERN PUINT16 BmpHexTable; +/* Serial port configuration */ +EXTERN CPPORT BmpSerialPort; + /* EFI Image Handle */ EXTERN EFI_HANDLE EfiImageHandle; -- 2.45.1 From a99ce415cacacd203b93408324f3312f27228d23 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 00:50:44 +0100 Subject: [PATCH 010/182] Early print XTLDR version --- xtldr2/xtldr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 22ac4cb..e8f7306 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -33,8 +33,12 @@ BmStartXtLoader(IN EFI_HANDLE ImageHandle, EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; - /* Initialize UEFI console */ + /* Initialize UEFI console and early print XTLDR version */ BmInitializeConsole(); + BmPrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + + /* Temporary infinite loop */ + for(;;); /* This point should be never reached, if this happen return error code */ return STATUS_EFI_LOAD_ERROR; -- 2.45.1 From 40696e2a1eac583a85f272150cba03fb19d99044 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 09:17:58 +0100 Subject: [PATCH 011/182] Include iotypes as well --- sdk/xtdk/xtbmapi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtbmapi.h index d0de696..cd77ffa 100644 --- a/sdk/xtdk/xtbmapi.h +++ b/sdk/xtdk/xtbmapi.h @@ -28,6 +28,7 @@ /* Architecture independent XT kernel data types */ #include +#include #include /* Architecture dependent XT kernel data types */ -- 2.45.1 From 3fc97ae98b7ec807e5bde5a7c52437ee85b86588 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 09:18:50 +0100 Subject: [PATCH 012/182] Basic memory support --- xtldr2/CMakeLists.txt | 1 + xtldr2/memory.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 xtldr2/memory.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 43e1747..6ffbf47 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/globals.c + ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/xtldr.c) diff --git a/xtldr2/memory.c b/xtldr2/memory.c new file mode 100644 index 0000000..f3e0cf0 --- /dev/null +++ b/xtldr2/memory.c @@ -0,0 +1,92 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/memory.c + * DESCRIPTION: XT Boot Manager EFI memory management + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine allocates one or more 4KB pages. + * + * @param Pages + * The number of contiguous 4KB pages to allocate. + * + * @param Memory + * The pointer to a physical address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmAllocateEfiPages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory) +{ + return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); +} + +/** + * This routine allocates a pool memory. + * + * @param Size + * The number of bytes to allocate from the pool. + * + * @param Memory + * The pointer to a physical address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmAllocateEfiPool(IN UINT_PTR Size, + OUT PVOID *Memory) +{ + /* Allocate pool */ + return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); +} + +/** + * This routine frees memory pages. + * + * @param Pages + * The number of contiguous 4 KB pages to free. + * + * @param Memory + * The base physical address of the pages to be freed. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmFreeEfiPages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory) +{ + return EfiSystemTable->BootServices->FreePages(Memory, Pages); +} + +/** + * Returns pool memory to the system. + * + * @param Memory + * The pointer to the buffer to free. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmFreeEfiPool(IN PVOID Memory) +{ + /* Free pool */ + return EfiSystemTable->BootServices->FreePool(Memory); +} -- 2.45.1 From 5e4248351ee1c709a9e13c5ff929c48fb9b7773a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 09:21:33 +0100 Subject: [PATCH 013/182] Add missing forward references --- xtldr2/includes/bootman.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 6a449ce..1fa2014 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -15,6 +15,16 @@ /* XTLDR routine callbacks */ typedef VOID (BMPRINTCHAR)(IN USHORT Character); +XTCDECL +EFI_STATUS +BmAllocateEfiPages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory); + +XTCDECL +EFI_STATUS +BmAllocateEfiPool(IN UINT_PTR Size, + OUT PVOID *Memory); + /* XTLDR routines forward references */ XTCDECL VOID @@ -28,6 +38,16 @@ XTCDECL VOID BmEnableCursor(); +XTCDECL +EFI_STATUS +BmFreeEfiPages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory); + +XTCDECL +EFI_STATUS +BmFreeEfiPool(IN PVOID Memory); + + XTCDECL VOID BmInitializeConsole(); -- 2.45.1 From e302f662bb8964b82ad2d97caa9407ac80508e05 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 10:22:24 +0100 Subject: [PATCH 014/182] Implement BmActivateSerialIOController() routine --- xtldr2/CMakeLists.txt | 1 + xtldr2/hardware.c | 112 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 xtldr2/hardware.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 6ffbf47..5ebd7a1 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/globals.c + ${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/xtldr.c) diff --git a/xtldr2/hardware.c b/xtldr2/hardware.c new file mode 100644 index 0000000..3f3c8b3 --- /dev/null +++ b/xtldr2/hardware.c @@ -0,0 +1,112 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/hardware.c + * DESCRIPTION: XT Boot Manager EFI hardware support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Enables I/O space access to all serial controllers found on the PCI(E) root bridge. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BmActivateSerialIOController() +{ + EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; + PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; + USHORT Bus, Device, Function, Command; + UINT_PTR Index, PciHandleSize; + PEFI_HANDLE PciHandle = NULL; + PCI_COMMON_HEADER PciHeader; + EFI_STATUS Status; + UINT64 Address; + + /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */ + PciHandleSize = sizeof(EFI_HANDLE); + Status = BmAllocateEfiPool(PciHandleSize, (PVOID*)&PciHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Get all instances of PciRootBridgeIo */ + Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle); + if(Status == STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Reallocate more memory as requested by UEFI */ + BmFreeEfiPool(PciHandle); + Status = BmAllocateEfiPool(PciHandleSize, (PVOID*)&PciHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory reallocation failure */ + return Status; + } + + /* Second attempt to get instances of PciRootBridgeIo */ + Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle); + } + + /* Make sure successfully obtained PciRootBridgeIo instances */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get PciRootBridgeIo instances */ + return Status; + } + + /* Enumerate all devices for each handle, which decides a segment and a bus number range */ + for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++) + { + /* Get inferface from the protocol */ + Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get interface */ + return Status; + } + + /* Enumerate whole PCI bridge */ + for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++) + { + /* Enumerate all devices for each bus */ + for(Device = 0; Device < PCI_MAX_DEVICES; Device++) + { + /* Enumerate all functions for each devices */ + for(Function = 0; Function < PCI_MAX_FUNCTION; Function++) + { + /* Read configuration space */ + Address = ((UINT64)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) + + (((UINT_PTR) Function) << 8) + ((UINT_PTR) 0))); + PciDev->Pci.Read(PciDev, 2, Address, sizeof (PciHeader) / sizeof (UINT32), &PciHeader); + + /* Check if device exists */ + if(PciHeader.VendorId == PCI_INVALID_VENDORID) + { + /* Skip non-existen device */ + continue; + } + + /* Check if device is serial controller or multiport serial controller */ + if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02)) + { + /* Enable I/O space access */ + Address |= 0x4; + Command = PCI_ENABLE_IO_SPACE; + Status = PciDev->Pci.Write(PciDev, 1, Address, 1, &Command); + } + } + } + } + } + + /* Return SUCCESS */ + return STATUS_EFI_SUCCESS; +} -- 2.45.1 From ab7fa5ffa4b43485f0071c5044cb5d5b50d8fb0f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 14:22:14 +0100 Subject: [PATCH 015/182] Initial XTLDR configuration --- xtldr2/CMakeLists.txt | 1 + xtldr2/config.c | 116 ++++++++++++++++++++++++++++++++++++++ xtldr2/globals.c | 3 + xtldr2/includes/bootman.h | 9 +++ xtldr2/includes/globals.h | 3 + 5 files changed, 132 insertions(+) create mode 100644 xtldr2/config.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 5ebd7a1..911fca8 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -8,6 +8,7 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/config.c ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/hardware.c diff --git a/xtldr2/config.c b/xtldr2/config.c new file mode 100644 index 0000000..2e1c8d2 --- /dev/null +++ b/xtldr2/config.c @@ -0,0 +1,116 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/config.c + * DESCRIPTION: XT Boot Manager Configuration + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +XTCDECL +VOID +BmpParseCommandLineOptions(VOID) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + EFI_STATUS Status; + + /* Handle loaded image protocol */ + Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); + if(Status == STATUS_EFI_SUCCESS) + { + /* Check if launched from UEFI shell */ + if(LoadedImage && LoadedImage->LoadOptions) + { + /* Update global boot loader configuration */ + BmpUpdateGlobalConfiguration(LoadedImage->LoadOptions); + } + } +} + +XTCDECL +VOID +BmpUpdateGlobalConfiguration(IN PWCHAR Options) +{ + PWCHAR Argument, LastArg; + SIZE_T Length; + + /* Tokenize provided options */ + Argument = RtlWideStringTokenize(Options, L" ", &LastArg); + + /* Iterate over all arguments passed to boot loader */ + while(Argument != NULL) + { + /* Check all provided parameters */ + if(RtlWideStringCompare(Argument, L"DEFAULT=", 8) == 0) + { + /* Skip to the argument value and calculate argument length */ + Argument += 8; + Length = RtlWideStringLength(Argument, 0); + + /* Save default OS parameter in global configuration */ + BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Default); + RtlCopyMemory(BmpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); + BmpConfiguration.Default[Length] = '\0'; + } + else if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) + { + /* Skip to the argument value */ + Argument += 6; + Length = RtlWideStringLength(Argument, 0); + + /* Save debug port in global configuration */ + BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Debug); + RtlCopyMemory(BmpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); + BmpConfiguration.Debug[Length] = '\0'; + } + else if(RtlWideStringCompare(Argument, L"SHELL", 5) == 0) + { + /* Force shell mode */ + BmpConfiguration.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 */ + BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Theme); + RtlCopyMemory(BmpConfiguration.Theme, Argument, (Length * sizeof(WCHAR)) - 1); + BmpConfiguration.Theme[Length] = '\0'; + } + else if(RtlWideStringCompare(Argument, L"TIMEOUT=", 8) == 0) + { + /* Skip to the argument value */ + Argument += 8; + + /* Zero the timeout */ + BmpConfiguration.Timeout = 0; + + /* Read the timeout value and store it in global configuration */ + while(*Argument >= '0' && *Argument <= '9') + { + BmpConfiguration.Timeout *= 10; + BmpConfiguration.Timeout += *Argument - '0'; + Argument++; + } + } + else if(RtlWideStringCompare(Argument, L"TUNE=", 5) == 0) + { + /* Skip to the argument value */ + Argument += 5; + Length = RtlWideStringLength(Argument, 0); + + /* Save theme in global configuration */ + BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Tune); + RtlCopyMemory(BmpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); + BmpConfiguration.Tune[Length] = '\0'; + } + + /* Take next argument */ + Argument = RtlWideStringTokenize(NULL, L" ", &LastArg); + } +} diff --git a/xtldr2/globals.c b/xtldr2/globals.c index ef1cbbc..8c5f2b9 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -9,6 +9,9 @@ #include +/* XT Boot Loader configuration data */ +XTBM_CONFIGURATION BmpConfiguration = {0}; + /* XT Boot Loader hex table */ STATIC PUINT16 BmpHexTable = L"0123456789ABCDEF"; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 1fa2014..87d772f 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -72,12 +72,17 @@ EFI_STATUS BmStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); + XTCDECL VOID BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...); +XTCDECL +VOID +BmpParseCommandLineOptions(VOID); + XTCDECL VOID BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, @@ -108,4 +113,8 @@ XTCDECL UINT64 BmpReadStringPadding(IN PUINT16 *Format); +XTCDECL +VOID +BmpUpdateGlobalConfiguration(IN PWCHAR Options); + #endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index a9b2fab..ad7d7eb 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -12,6 +12,9 @@ #include +/* XT Boot Loader configuration data */ +EXTERN XTBM_CONFIGURATION BmpConfiguration; + /* XT Boot Loader hex table */ EXTERN PUINT16 BmpHexTable; -- 2.45.1 From 55bd9e326f05f1c8769aa6ddca7ba082ddeef495 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 14:24:43 +0100 Subject: [PATCH 016/182] Add XTBM_CONFIGURATION structure definition --- sdk/xtdk/bmtypes.h | 26 ++++++++++++++++++++++++++ sdk/xtdk/xtbmapi.h | 3 +++ 2 files changed, 29 insertions(+) create mode 100644 sdk/xtdk/bmtypes.h diff --git a/sdk/xtdk/bmtypes.h b/sdk/xtdk/bmtypes.h new file mode 100644 index 0000000..8f75f5a --- /dev/null +++ b/sdk/xtdk/bmtypes.h @@ -0,0 +1,26 @@ +/** + * 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 + + +/* XTLDR configuration data */ +typedef struct _XTBM_CONFIGURATION +{ + PWCHAR Default; + PWCHAR Debug; + BOOLEAN Shell; + PWCHAR Theme; + ULONG Timeout; + PWCHAR Tune; +} XTBM_CONFIGURATION, *PXTBM_CONFIGURATION; + +#endif /* __XTDK_BMTYPES_H */ diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtbmapi.h index cd77ffa..35fab90 100644 --- a/sdk/xtdk/xtbmapi.h +++ b/sdk/xtdk/xtbmapi.h @@ -41,3 +41,6 @@ /* Architecture specific XT kernel routines */ #include ARCH_HEADER(arfuncs.h) #include ARCH_HEADER(hlfuncs.h) + +/* Boot Manager specific structures */ +#include -- 2.45.1 From fce8a50321d1ec0a400007691a4aad02a2e59d86 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 16:04:12 +0100 Subject: [PATCH 017/182] Refactor part 1 --- xtldr2/CMakeLists.txt | 2 +- xtldr2/config.c | 57 ++++++++++++++++++++++++------------- xtldr2/console.c | 20 ++++++------- xtldr2/globals.c | 8 +++--- xtldr2/hardware.c | 10 +++---- xtldr2/includes/bootman.h | 40 +++++++++++++------------- xtldr2/includes/globals.h | 6 ++-- xtldr2/memory.c | 16 +++++------ xtldr2/string.c | 60 +++++++++++++++++++-------------------- xtldr2/xtldr.c | 6 ++-- 10 files changed, 121 insertions(+), 104 deletions(-) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 911fca8..198e406 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -36,5 +36,5 @@ set_install_target(xtldr efi/boot) # Set loader entrypoint and subsystem set_imagebase(xtldr ${BASEADDRESS_XTLDR}) -set_entrypoint(xtldr "BmStartXtLoader") +set_entrypoint(xtldr "BlStartXtLoader") set_subsystem(xtldr efi_application) diff --git a/xtldr2/config.c b/xtldr2/config.c index 2e1c8d2..2c8ac23 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -2,16 +2,23 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/config.c - * DESCRIPTION: XT Boot Manager Configuration + * DESCRIPTION: XT Boot Loader Configuration * DEVELOPERS: Rafal Kupiec */ #include +/** + * Parses command line arguments and updates global configuration. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -BmpParseCommandLineOptions(VOID) +BlpConfigParseCommandLine(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -25,14 +32,24 @@ BmpParseCommandLineOptions(VOID) if(LoadedImage && LoadedImage->LoadOptions) { /* Update global boot loader configuration */ - BmpUpdateGlobalConfiguration(LoadedImage->LoadOptions); + BlpConfigUpdateGlobalConfiguration(LoadedImage->LoadOptions); } } } +/** + * Updates XTLDR configuration based on provided options. + * + * @param Options + * Supplies a formatted list of options to be processed and stored in global configuration. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -BmpUpdateGlobalConfiguration(IN PWCHAR Options) +BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) { PWCHAR Argument, LastArg; SIZE_T Length; @@ -51,9 +68,9 @@ BmpUpdateGlobalConfiguration(IN PWCHAR Options) Length = RtlWideStringLength(Argument, 0); /* Save default OS parameter in global configuration */ - BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Default); - RtlCopyMemory(BmpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); - BmpConfiguration.Default[Length] = '\0'; + BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Default); + RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); + BlpConfiguration.Default[Length] = '\0'; } else if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) { @@ -62,14 +79,14 @@ BmpUpdateGlobalConfiguration(IN PWCHAR Options) Length = RtlWideStringLength(Argument, 0); /* Save debug port in global configuration */ - BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Debug); - RtlCopyMemory(BmpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); - BmpConfiguration.Debug[Length] = '\0'; + 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 */ - BmpConfiguration.Shell = TRUE; + BlpConfiguration.Shell = TRUE; } else if(RtlWideStringCompare(Argument, L"THEME=", 6) == 0) { @@ -78,9 +95,9 @@ BmpUpdateGlobalConfiguration(IN PWCHAR Options) Length = RtlWideStringLength(Argument, 0); /* Save theme in global configuration */ - BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Theme); - RtlCopyMemory(BmpConfiguration.Theme, Argument, (Length * sizeof(WCHAR)) - 1); - BmpConfiguration.Theme[Length] = '\0'; + 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) { @@ -88,13 +105,13 @@ BmpUpdateGlobalConfiguration(IN PWCHAR Options) Argument += 8; /* Zero the timeout */ - BmpConfiguration.Timeout = 0; + BlpConfiguration.Timeout = 0; /* Read the timeout value and store it in global configuration */ while(*Argument >= '0' && *Argument <= '9') { - BmpConfiguration.Timeout *= 10; - BmpConfiguration.Timeout += *Argument - '0'; + BlpConfiguration.Timeout *= 10; + BlpConfiguration.Timeout += *Argument - '0'; Argument++; } } @@ -105,9 +122,9 @@ BmpUpdateGlobalConfiguration(IN PWCHAR Options) Length = RtlWideStringLength(Argument, 0); /* Save theme in global configuration */ - BmAllocateEfiPool(Length, (PVOID *)&BmpConfiguration.Tune); - RtlCopyMemory(BmpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); - BmpConfiguration.Tune[Length] = '\0'; + BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Tune); + RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); + BlpConfiguration.Tune[Length] = '\0'; } /* Take next argument */ diff --git a/xtldr2/console.c b/xtldr2/console.c index e9f0d16..d96ab94 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -18,7 +18,7 @@ */ XTCDECL VOID -BmClearScreen() +BlConsoleClearScreen() { /* Clear screen */ EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); @@ -33,7 +33,7 @@ BmClearScreen() */ XTCDECL VOID -BmDisableCursor() +BlConsoleDisableCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); } @@ -47,7 +47,7 @@ BmDisableCursor() */ XTCDECL VOID -BmEnableCursor() +BlConsoleEnableCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); } @@ -61,7 +61,7 @@ BmEnableCursor() */ XTCDECL VOID -BmInitializeConsole() +BlConsoleInitialize() { /* Clear console buffers */ EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); @@ -69,8 +69,8 @@ BmInitializeConsole() EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); /* Clear screen and enable cursor */ - BmClearScreen(); - BmEnableCursor(); + BlConsoleClearScreen(); + BlConsoleEnableCursor(); } /** @@ -88,8 +88,8 @@ BmInitializeConsole() */ XTCDECL VOID -BmPrint(IN PUINT16 Format, - IN ...) +BlConsolePrint(IN PUINT16 Format, + IN ...) { VA_LIST Arguments; @@ -97,7 +97,7 @@ BmPrint(IN PUINT16 Format, VA_START(Arguments, Format); /* Format and print the string to the stdout */ - BmPrintString(BmPrintChar, Format, Arguments); + BlpStringPrint(BlpConsolePrintChar, Format, Arguments); /* Clean up the va_list */ VA_END(Arguments); @@ -115,7 +115,7 @@ BmPrint(IN PUINT16 Format, */ XTCDECL VOID -BmPrintChar(IN USHORT Character) +BlpConsolePrintChar(IN USHORT Character) { USHORT Buffer[2]; diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 8c5f2b9..14277ac 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/globals.c - * DESCRIPTION: XT Boot Manager global variables + * DESCRIPTION: XT Boot Loader global variables * DEVELOPERS: Rafal Kupiec */ @@ -10,13 +10,13 @@ /* XT Boot Loader configuration data */ -XTBM_CONFIGURATION BmpConfiguration = {0}; +XTBM_CONFIGURATION BlpConfiguration = {0}; /* XT Boot Loader hex table */ -STATIC PUINT16 BmpHexTable = L"0123456789ABCDEF"; +STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; /* Serial port configuration */ -CPPORT BmpSerialPort; +CPPORT BlpSerialPort; /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/hardware.c b/xtldr2/hardware.c index 3f3c8b3..8cf2a47 100644 --- a/xtldr2/hardware.c +++ b/xtldr2/hardware.c @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/hardware.c - * DESCRIPTION: XT Boot Manager EFI hardware support + * DESCRIPTION: EFI hardware support for XT Boot Loader * DEVELOPERS: Rafal Kupiec */ @@ -18,7 +18,7 @@ */ XTCDECL EFI_STATUS -BmActivateSerialIOController() +BlpHwActivateSerialIOController() { EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; @@ -31,7 +31,7 @@ BmActivateSerialIOController() /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */ PciHandleSize = sizeof(EFI_HANDLE); - Status = BmAllocateEfiPool(PciHandleSize, (PVOID*)&PciHandle); + Status = BlMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -43,8 +43,8 @@ BmActivateSerialIOController() if(Status == STATUS_EFI_BUFFER_TOO_SMALL) { /* Reallocate more memory as requested by UEFI */ - BmFreeEfiPool(PciHandle); - Status = BmAllocateEfiPool(PciHandleSize, (PVOID*)&PciHandle); + BlMemoryFreePool(PciHandle); + Status = BlMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle); if(Status != STATUS_EFI_SUCCESS) { /* Memory reallocation failure */ diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 87d772f..a4665fa 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/includes/xtbm.h - * DESCRIPTION: XTLDR Boot Manager related structures and routines forward references + * DESCRIPTION: XTLDR Boot Loader related structures and routines forward references * DEVELOPERS: Rafal Kupiec */ @@ -17,53 +17,53 @@ typedef VOID (BMPRINTCHAR)(IN USHORT Character); XTCDECL EFI_STATUS -BmAllocateEfiPages(IN UINT64 Pages, +BlMemoryAllocatePages(IN UINT64 Pages, OUT PEFI_PHYSICAL_ADDRESS Memory); XTCDECL EFI_STATUS -BmAllocateEfiPool(IN UINT_PTR Size, +BlMemoryAllocatePool(IN UINT_PTR Size, OUT PVOID *Memory); /* XTLDR routines forward references */ XTCDECL VOID -BmClearScreen(); +BlConsoleClearScreen(); XTCDECL VOID -BmDisableCursor(); +BlConsoleDisableCursor(); XTCDECL VOID -BmEnableCursor(); +BlConsoleEnableCursor(); XTCDECL EFI_STATUS -BmFreeEfiPages(IN UINT64 Pages, +BlMemoreFreePages(IN UINT64 Pages, IN EFI_PHYSICAL_ADDRESS Memory); XTCDECL EFI_STATUS -BmFreeEfiPool(IN PVOID Memory); +BlMemoryFreePool(IN PVOID Memory); XTCDECL VOID -BmInitializeConsole(); +BlConsoleInitialize(); XTCDECL VOID -BmPrint(IN PUINT16 Format, +BlConsolePrint(IN PUINT16 Format, IN ...); XTCDECL VOID -BmPrintChar(IN USHORT Character); +BlpConsolePrintChar(IN USHORT Character); XTCDECL VOID -BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN VA_LIST Arguments); @@ -75,46 +75,46 @@ BmStartXtLoader(IN EFI_HANDLE ImageHandle, XTCDECL VOID -BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, +BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...); XTCDECL VOID -BmpParseCommandLineOptions(VOID); +BlpConfigParseCommandLine(VOID); XTCDECL VOID -BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned32(IN BMPRINTCHAR PrintCharRoutine, IN INT Number, IN UINT Base); XTCDECL VOID -BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned64(IN BMPRINTCHAR PrintCharRoutine, IN INT_PTR Number, IN UINT_PTR Base); XTCDECL VOID -BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned32(IN BMPRINTCHAR PrintCharRoutine, IN UINT Number, IN UINT Base, IN UINT Padding); XTCDECL VOID -BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned64(IN BMPRINTCHAR PrintCharRoutine, IN UINT_PTR Number, IN UINT_PTR Base, IN UINT_PTR Padding); XTCDECL UINT64 -BmpReadStringPadding(IN PUINT16 *Format); +BlpStringReadPadding(IN PUINT16 *Format); XTCDECL VOID -BmpUpdateGlobalConfiguration(IN PWCHAR Options); +BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options); #endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index ad7d7eb..d9e1419 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -13,13 +13,13 @@ /* XT Boot Loader configuration data */ -EXTERN XTBM_CONFIGURATION BmpConfiguration; +EXTERN XTBM_CONFIGURATION BlpConfiguration; /* XT Boot Loader hex table */ -EXTERN PUINT16 BmpHexTable; +EXTERN PUINT16 BlpHexTable; /* Serial port configuration */ -EXTERN CPPORT BmpSerialPort; +EXTERN CPPORT BlpSerialPort; /* EFI Image Handle */ EXTERN EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/memory.c b/xtldr2/memory.c index f3e0cf0..6ef6998 100644 --- a/xtldr2/memory.c +++ b/xtldr2/memory.c @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/memory.c - * DESCRIPTION: XT Boot Manager EFI memory management + * DESCRIPTION: XT Boot Loader memory management * DEVELOPERS: Rafal Kupiec */ @@ -24,8 +24,8 @@ */ XTCDECL EFI_STATUS -BmAllocateEfiPages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory) +BlMemoryAllocatePages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory) { return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); } @@ -45,8 +45,8 @@ BmAllocateEfiPages(IN UINT64 Pages, */ XTCDECL EFI_STATUS -BmAllocateEfiPool(IN UINT_PTR Size, - OUT PVOID *Memory) +BlMemoryAllocatePool(IN UINT_PTR Size, + OUT PVOID *Memory) { /* Allocate pool */ return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); @@ -67,8 +67,8 @@ BmAllocateEfiPool(IN UINT_PTR Size, */ XTCDECL EFI_STATUS -BmFreeEfiPages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory) +BlMemoreFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory) { return EfiSystemTable->BootServices->FreePages(Memory, Pages); } @@ -85,7 +85,7 @@ BmFreeEfiPages(IN UINT64 Pages, */ XTCDECL EFI_STATUS -BmFreeEfiPool(IN PVOID Memory) +BlMemoryFreePool(IN PVOID Memory) { /* Free pool */ return EfiSystemTable->BootServices->FreePool(Memory); diff --git a/xtldr2/string.c b/xtldr2/string.c index be812c5..58b0d86 100644 --- a/xtldr2/string.c +++ b/xtldr2/string.c @@ -27,9 +27,9 @@ */ XTCDECL VOID -BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN VA_LIST Arguments) +BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments) { PEFI_GUID Guid; PUCHAR String; @@ -46,7 +46,7 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, { case L'b': /* Boolean */ - BmpFormatString(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); + BlpStringFormat(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); break; case L'c': /* Character */ @@ -54,12 +54,12 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, break; case L'd': /* Signed 32-bit integer */ - BmpPrintSigned32String(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); + BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); break; case L'g': /* EFI GUID */ Guid = VA_ARG(Arguments, PEFI_GUID); - BmpFormatString(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, + BlpStringFormat(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]); break; @@ -69,15 +69,15 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, { case L'd': /* Signed 64-bit integer */ - BmpPrintSigned64String(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); + BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); break; case L'u': /* Unsigned 64-bit integer */ - BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); break; case L'x': /* Unsigned 64-bit hexadecimal integer */ - BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); break; default: /* Unknown by default */ @@ -87,7 +87,7 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, break; case L'p': /* Pointer address */ - BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); break; case L's': /* String of characters */ @@ -106,21 +106,21 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, break; case L'u': /* Unsigned 32-bit integer */ - BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0); break; case L'x': /* Unsigned 32-bit hexadecimal integer */ - BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0); break; case L'0': /* Zero padded numbers */ ++Format; - PaddingCount = BmpReadStringPadding(&Format); + PaddingCount = BlpStringReadPadding(&Format); switch(*Format) { case L'd': /* Zero-padded, signed 32-bit integer */ - BmpPrintSigned32String(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); + BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); break; case L'l': /* 64-bit numbers */ @@ -128,15 +128,15 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, { case L'd': /* Zero-padded, signed 64-bit integer */ - BmpPrintSigned64String(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); + BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); break; case L'u': /* Zero-padded, unsigned 64-bit integer */ - BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); break; case L'x': /* Zero-padded, unsigned 64-bit hexadecimal integer */ - BmpPrintUnsigned64String(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); break; default: /* Unknown by default */ @@ -146,11 +146,11 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, break; case L'u': /* Zero-padded, unsigned 32-bit integer */ - BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount); break; case L'x': /* Zero-padded, unsigned 32-bit hexadecimal integer */ - BmpPrintUnsigned32String(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount); break; default: /* Unknown by default */ @@ -202,7 +202,7 @@ BmPrintString(IN IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, +BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...) { @@ -212,7 +212,7 @@ BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, VA_START(Arguments, Format); /* Format and print the string to the desired output */ - BmPrintString(PrintCharRoutine, Format, Arguments); + BlpStringPrint(PrintCharRoutine, Format, Arguments); /* Clean up the va_list */ VA_END(Arguments); @@ -236,7 +236,7 @@ BmpFormatString(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned32(IN BMPRINTCHAR PrintCharRoutine, IN INT Number, IN UINT Base) { @@ -248,7 +248,7 @@ BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, } /* Print the integer value */ - BmpPrintUnsigned32String(PrintCharRoutine, Number, Base, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, Number, Base, 0); } /** @@ -269,7 +269,7 @@ BmpPrintSigned32String(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned64(IN BMPRINTCHAR PrintCharRoutine, IN INT_PTR Number, IN UINT_PTR Base) { @@ -281,7 +281,7 @@ BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, } /* Print the integer value */ - BmpPrintUnsigned64String(PrintCharRoutine, Number, Base, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, Number, Base, 0); } /** @@ -305,7 +305,7 @@ BmpPrintSigned64String(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned32(IN BMPRINTCHAR PrintCharRoutine, IN UINT Number, IN UINT Base, IN UINT Padding) @@ -321,7 +321,7 @@ BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, *--Pointer = 0; do { - *--Pointer = BmpHexTable[Number % Base]; + *--Pointer = BlpHexTable[Number % Base]; } while(Pointer >= Buffer && (Number /= Base)); /* Calculate number length */ @@ -366,7 +366,7 @@ BmpPrintUnsigned32String(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned64(IN BMPRINTCHAR PrintCharRoutine, IN UINT_PTR Number, IN UINT_PTR Base, IN UINT_PTR Padding) @@ -382,7 +382,7 @@ BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, *--Pointer = 0; do { - *--Pointer = BmpHexTable[Number % Base]; + *--Pointer = BlpHexTable[Number % Base]; } while(Pointer >= Buffer && (Number /= Base)); /* Calculate number length */ @@ -418,7 +418,7 @@ BmpPrintUnsigned64String(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL UINT64 -BmpReadStringPadding(IN PUINT16 *Format) +BlpStringReadPadding(IN PUINT16 *Format) { ULONG Count = 0; PUINT16 Fmt = *Format; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index e8f7306..9075a47 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/xtldr.c - * DESCRIPTION: XTOS UEFI Boot Manager + * DESCRIPTION: XTOS UEFI Boot Loader * DEVELOPERS: Rafal Kupiec */ @@ -10,7 +10,7 @@ /** - * This routine is the entry point of the XT EFI boot manager. + * This routine is the entry point of the XT EFI boot loader. * * @param ImageHandle * Firmware-allocated handle that identifies the image. @@ -24,7 +24,7 @@ */ XTCDECL EFI_STATUS -BmStartXtLoader(IN EFI_HANDLE ImageHandle, +BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { EFI_STATUS Status; -- 2.45.1 From a66456979a882e35fedfb3236352b8da954bf959 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 16:09:05 +0100 Subject: [PATCH 018/182] Refactor part 2 --- xtldr2/xtldr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 9075a47..8a6bb3f 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -34,8 +34,8 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiSystemTable = SystemTable; /* Initialize UEFI console and early print XTLDR version */ - BmInitializeConsole(); - BmPrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + BlConsoleInitialize(); + BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Temporary infinite loop */ for(;;); -- 2.45.1 From d2f06a27587dc2a9d8f21b822f5976cd316658f0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 16:44:01 +0100 Subject: [PATCH 019/182] Refactor part 3 --- sdk/xtdk/{xtbmapi.h => xtblapi.h} | 0 xtldr2/config.c | 2 +- xtldr2/console.c | 2 +- xtldr2/globals.c | 2 +- xtldr2/hardware.c | 2 +- xtldr2/includes/bootman.h | 4 ++-- xtldr2/includes/globals.h | 4 ++-- xtldr2/includes/{xtbm.h => xtldr.h} | 10 +++++----- xtldr2/memory.c | 2 +- xtldr2/string.c | 2 +- xtldr2/xtldr.c | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) rename sdk/xtdk/{xtbmapi.h => xtblapi.h} (100%) rename xtldr2/includes/{xtbm.h => xtldr.h} (66%) diff --git a/sdk/xtdk/xtbmapi.h b/sdk/xtdk/xtblapi.h similarity index 100% rename from sdk/xtdk/xtbmapi.h rename to sdk/xtdk/xtblapi.h diff --git a/xtldr2/config.c b/xtldr2/config.c index 2c8ac23..beb72cc 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** diff --git a/xtldr2/console.c b/xtldr2/console.c index d96ab94..b4d7388 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 14277ac..844833c 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /* XT Boot Loader configuration data */ diff --git a/xtldr2/hardware.c b/xtldr2/hardware.c index 8cf2a47..9824cc2 100644 --- a/xtldr2/hardware.c +++ b/xtldr2/hardware.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index a4665fa..73abcb5 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,7 +9,7 @@ #ifndef __XTLDR_BOOTMAN_H #define __XTLDR_BOOTMAN_H -#include +#include /* XTLDR routine callbacks */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index d9e1419..3ac01d9 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,7 +9,7 @@ #ifndef __XTLDR_GLOBALS_H #define __XTLDR_GLOBALS_H -#include +#include /* XT Boot Loader configuration data */ 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..a91a99e 100644 --- a/xtldr2/memory.c +++ b/xtldr2/memory.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** 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 8a6bb3f..9a8eeb5 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** -- 2.45.1 From 023f2c72b34b2774ab344cb03784606daaa95e4b Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 16:47:03 +0100 Subject: [PATCH 020/182] Refactor part 4 --- sdk/xtdk/{bmtypes.h => bltypes.h} | 0 sdk/xtdk/xtblapi.h | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename sdk/xtdk/{bmtypes.h => bltypes.h} (100%) diff --git a/sdk/xtdk/bmtypes.h b/sdk/xtdk/bltypes.h similarity index 100% rename from sdk/xtdk/bmtypes.h rename to sdk/xtdk/bltypes.h diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index 35fab90..ececebb 100644 --- a/sdk/xtdk/xtblapi.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 */ @@ -43,4 +43,4 @@ #include ARCH_HEADER(hlfuncs.h) /* Boot Manager specific structures */ -#include +#include -- 2.45.1 From a101ddf55574f6c6fd75b70e708f47e6a961b3bb Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 23:14:34 +0100 Subject: [PATCH 021/182] Add debug port type definitions --- sdk/xtdk/bltypes.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 8f75f5a..20c33d2 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -12,11 +12,16 @@ #include +/* Debug port type definitions */ +#define XTBL_DEBUGPORT_SCREEN 1 +#define XTBL_DEBUGPORT_SERIAL 2 + /* XTLDR configuration data */ typedef struct _XTBM_CONFIGURATION { PWCHAR Default; PWCHAR Debug; + ULONG DebugPort; BOOLEAN Shell; PWCHAR Theme; ULONG Timeout; -- 2.45.1 From 6a03db6fcd302b98b09e02f5ba80787230226f1c Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 23:15:10 +0100 Subject: [PATCH 022/182] Include hltypes header --- sdk/xtdk/xtblapi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index ececebb..ef5260f 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -36,6 +36,7 @@ #include ARCH_HEADER(hltypes.h) /* XT Kernel runtime routines */ +#include #include /* Architecture specific XT kernel routines */ -- 2.45.1 From 5131a682b87b579553fcc278d6b0df73a5546c17 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 23:18:49 +0100 Subject: [PATCH 023/182] Refactor part 5; Implement debugging ports --- xtldr2/CMakeLists.txt | 2 + xtldr2/console.c | 53 +++++--- xtldr2/debug.c | 260 ++++++++++++++++++++++++++++++++++++++ xtldr2/efiutils.c | 27 ++++ xtldr2/hardware.c | 2 +- xtldr2/includes/bootman.h | 61 ++++++--- xtldr2/xtldr.c | 17 ++- 7 files changed, 381 insertions(+), 41 deletions(-) create mode 100644 xtldr2/debug.c create mode 100644 xtldr2/efiutils.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 198e406..465b1c7 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -10,6 +10,8 @@ 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 diff --git a/xtldr2/console.c b/xtldr2/console.c index b4d7388..c0911c9 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -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..dcfddc5 --- /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) && (EfiSystemTable->BootServices != 0)) + { + /* Format and print the string to the screen */ + BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + } + + /* Clean up the va_list */ + VA_END(Arguments); + } +} + +/** + * 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 +BlpDebugInitializeComPort(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; +} + +/** + * This routine initializes the XTLDR debug console. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpDebugInitializeConsole() +{ + 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 = BlpDebugInitializeComPort(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; +} + +/** + * 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..3cded88 --- /dev/null +++ b/xtldr2/efiutils.c @@ -0,0 +1,27 @@ +/** + * 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 + + +/** + * 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); +} diff --git a/xtldr2/hardware.c b/xtldr2/hardware.c index 9824cc2..4b6e6b7 100644 --- a/xtldr2/hardware.c +++ b/xtldr2/hardware.c @@ -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 73abcb5..3a310ae 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -15,17 +15,17 @@ /* XTLDR routine callbacks */ typedef VOID (BMPRINTCHAR)(IN USHORT Character); +/* XTLDR routines forward references */ 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,40 +38,67 @@ 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); + IN EFI_PHYSICAL_ADDRESS Memory); XTCDECL EFI_STATUS BlMemoryFreePool(IN PVOID Memory); +XTCDECL +VOID +BlSleepExecution(IN ULONG_PTR Milliseconds); + +XTCDECL +EFI_STATUS +BlStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +XTCDECL +EFI_STATUS +BlpActivateSerialIOController(); XTCDECL VOID -BlConsoleInitialize(); +BlpConfigParseCommandLine(VOID); XTCDECL VOID -BlConsolePrint(IN PUINT16 Format, - IN ...); +BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options); + +XTCDECL +VOID +BlpConsoleInitialize(); XTCDECL VOID BlpConsolePrintChar(IN USHORT Character); XTCDECL -VOID -BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN VA_LIST Arguments); +EFI_STATUS +BlpDebugInitializeComPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate); XTCDECL EFI_STATUS -BmStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); +BlpDebugInitializeConsole(); +XTCDECL +VOID +BlpDebugPutChar(IN USHORT Character); XTCDECL VOID @@ -81,7 +108,9 @@ BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, XTCDECL VOID -BlpConfigParseCommandLine(VOID); +BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments); XTCDECL VOID @@ -113,8 +142,4 @@ XTCDECL UINT64 BlpStringReadPadding(IN PUINT16 *Format); -XTCDECL -VOID -BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options); - #endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 9a8eeb5..dfa0a03 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -34,9 +34,24 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiSystemTable = SystemTable; /* Initialize UEFI console and early print XTLDR version */ - BlConsoleInitialize(); + BlpConsoleInitialize(); BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + /* Parse configuration options passed from UEFI shell */ + BlpConfigParseCommandLine(); + + /* Attempt to early initialize debug console */ + if(DEBUG) + { + Status = BlpDebugInitializeConsole(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Initialization failed, notify user on stdout */ + BlConsolePrint(L"ERROR: Failed to initialize debug console\n"); + BlSleepExecution(3000); + } + } + /* Temporary infinite loop */ for(;;); -- 2.45.1 From 9f36d397f0e5232efa2a400345f8718f5c1a487a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 23:42:59 +0100 Subject: [PATCH 024/182] Do not overwrite some options for easy debugging and testing new themes --- xtldr2/config.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index beb72cc..c0b5b13 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -78,10 +78,14 @@ 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) { @@ -94,10 +98,14 @@ BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) 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'; + /* Store theme configuration if not set already */ + if(BlpConfiguration.Theme == NULL) + { + /* 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) { -- 2.45.1 From 9a3e0f69fa6ea75c324a2f89750579e33284593b Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 3 Dec 2023 23:46:20 +0100 Subject: [PATCH 025/182] Disable watchdog timer --- xtldr2/xtldr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index dfa0a03..2c96e1d 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -52,6 +52,14 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } } + /* 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"); + } + /* Temporary infinite loop */ for(;;); -- 2.45.1 From 2b2efd0dd3548172530ce40447978e9fd99e3930 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 4 Dec 2023 16:32:07 +0100 Subject: [PATCH 026/182] Refactor part 6 --- sdk/xtdk/bltypes.h | 15 ++++- sdk/xtdk/xtblapi.h | 10 +-- xtldr2/debug.c | 130 +++++++++++++++++++------------------- xtldr2/efiutils.c | 55 ++++++++++++++++ xtldr2/globals.c | 5 +- xtldr2/includes/bootman.h | 20 ++++-- xtldr2/includes/globals.h | 5 +- xtldr2/xtldr.c | 10 +-- 8 files changed, 162 insertions(+), 88 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 20c33d2..59ff5ab 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -10,14 +10,15 @@ #define __XTDK_BMTYPES_H #include +#include -/* Debug port type definitions */ +/* XTLDR Debug port type definitions */ #define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SERIAL 2 /* XTLDR configuration data */ -typedef struct _XTBM_CONFIGURATION +typedef struct _XTBL_CONFIGURATION { PWCHAR Default; PWCHAR Debug; @@ -26,6 +27,14 @@ typedef struct _XTBM_CONFIGURATION PWCHAR Theme; ULONG Timeout; PWCHAR Tune; -} XTBM_CONFIGURATION, *PXTBM_CONFIGURATION; +} XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; + +/* XTLDR status data */ +typedef struct _XTBL_STATUS +{ + BOOLEAN BootServices; + EFI_HANDLE ImageHandle; + PEFI_SYSTEM_TABLE SystemTable; +} XTBL_STATUS, *PXTBL_STATUS; #endif /* __XTDK_BMTYPES_H */ diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index ef5260f..f58c149 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -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,16 +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 diff --git a/xtldr2/debug.c b/xtldr2/debug.c index dcfddc5..3a4b689 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -43,7 +43,7 @@ BlDebugPrint(IN PUINT16 Format, } /* Check if screen debug port is enabled and Boot Services are still available */ - if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SCREEN) && (EfiSystemTable->BootServices != 0)) + if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) { /* Format and print the string to the screen */ BlpStringPrint(BlpConsolePrintChar, Format, Arguments); @@ -54,68 +54,6 @@ BlDebugPrint(IN PUINT16 Format, } } -/** - * 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 -BlpDebugInitializeComPort(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; -} - /** * This routine initializes the XTLDR debug console. * @@ -125,7 +63,7 @@ BlpDebugInitializeComPort(IN ULONG PortNumber, */ XTCDECL EFI_STATUS -BlpDebugInitializeConsole() +BlpInitializeDebugConsole() { ULONG PortAddress, PortNumber, BaudRate; PWCHAR DebugPort, LastPort; @@ -223,7 +161,7 @@ BlpDebugInitializeConsole() if(BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) { /* Try to initialize COM port */ - Status = BlpDebugInitializeComPort(PortNumber, PortAddress, BaudRate); + Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); if(Status != STATUS_EFI_SUCCESS) { /* Remove serial debug port, as COM port initialization failed and return */ @@ -236,6 +174,68 @@ BlpDebugInitializeConsole() 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. * diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 3cded88..104db69 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -9,6 +9,41 @@ #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. * @@ -25,3 +60,23 @@ 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 844833c..6017862 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -10,7 +10,7 @@ /* 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/includes/bootman.h b/xtldr2/includes/bootman.h index 3a310ae..5fd9f9b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -16,6 +16,10 @@ 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, @@ -87,18 +91,22 @@ VOID BlpConsolePrintChar(IN USHORT Character); XTCDECL -EFI_STATUS -BlpDebugInitializeComPort(IN ULONG PortNumber, - IN ULONG PortAddress, - IN ULONG BaudRate); +VOID +BlpDebugPutChar(IN USHORT Character); XTCDECL EFI_STATUS -BlpDebugInitializeConsole(); +BlpInitializeDebugConsole(); XTCDECL VOID -BlpDebugPutChar(IN USHORT Character); +BlpInitializeEfiBootLoader(); + +XTCDECL +EFI_STATUS +BlpInitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate); XTCDECL VOID diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 3ac01d9..9d09f76 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -13,7 +13,7 @@ /* XT Boot Loader configuration data */ -EXTERN XTBM_CONFIGURATION BlpConfiguration; +EXTERN XTBL_CONFIGURATION BlpConfiguration; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; @@ -21,6 +21,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/xtldr.c b/xtldr2/xtldr.c index 2c96e1d..7a850d7 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -29,12 +29,8 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, { EFI_STATUS Status; - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Initialize UEFI console and early print XTLDR version */ - BlpConsoleInitialize(); + /* 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 */ @@ -43,7 +39,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, /* Attempt to early initialize debug console */ if(DEBUG) { - Status = BlpDebugInitializeConsole(); + Status = BlpInitializeDebugConsole(); if(Status != STATUS_EFI_SUCCESS) { /* Initialization failed, notify user on stdout */ -- 2.45.1 From aea69a33b9fb292ebee4627761519798c0fcc35c Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 4 Dec 2023 17:33:33 +0100 Subject: [PATCH 027/182] Correct typo --- xtldr2/includes/bootman.h | 2 +- xtldr2/memory.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 5fd9f9b..961718f 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -54,7 +54,7 @@ BlDebugPrint(IN PUINT16 Format, XTCDECL EFI_STATUS -BlMemoreFreePages(IN UINT64 Pages, +BlMemoryFreePages(IN UINT64 Pages, IN EFI_PHYSICAL_ADDRESS Memory); XTCDECL diff --git a/xtldr2/memory.c b/xtldr2/memory.c index a91a99e..19e9397 100644 --- a/xtldr2/memory.c +++ b/xtldr2/memory.c @@ -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); -- 2.45.1 From 02cd8efde9be09117f716b3b5ed9958b694f13c5 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 4 Dec 2023 18:49:34 +0100 Subject: [PATCH 028/182] Add XTLDR protocol support --- sdk/xtdk/bltypes.h | 56 ++++++++++++++++++++++++++++++++++++--- xtldr2/CMakeLists.txt | 1 + xtldr2/efiutils.c | 28 ++++++++++++++++++++ xtldr2/includes/bootman.h | 8 ++++++ 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 59ff5ab..e3590e3 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -13,11 +13,27 @@ #include -/* XTLDR Debug port type definitions */ +/* XTLDR Debug Port type definitions */ #define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SERIAL 2 -/* XTLDR configuration data */ +/* 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_HANDLE (*PBL_GET_EFI_IMAGE_HANDLE)(); +typedef PEFI_SYSTEM_TABLE (*PBL_GET_EFI_SYSTEM_TABLE)(); +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; @@ -29,7 +45,7 @@ typedef struct _XTBL_CONFIGURATION PWCHAR Tune; } XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; -/* XTLDR status data */ +/* XTLDR Status data */ typedef struct _XTBL_STATUS { BOOLEAN BootServices; @@ -37,4 +53,38 @@ typedef struct _XTBL_STATUS 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_GET_EFI_IMAGE_HANDLE GetImageHandle; + PBL_GET_EFI_SYSTEM_TABLE GetSystemTable; + PBL_SLEEP_EXECUTION SleepExecution; + } Util; +} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; + #endif /* __XTDK_BMTYPES_H */ diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 465b1c7..2004d41 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND XTLDR_SOURCE ${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/efiutils.c b/xtldr2/efiutils.c index 104db69..5c1f3f0 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -44,6 +44,34 @@ BlExitBootServices(IN UINT_PTR MapKey) return Status; } +/** + * Returns the EFI image handle. + * + * @return This routine returns the current EFI image handle. + * + * @since XT 1.0 + */ +XTCDECL +EFI_HANDLE +BlGetEfiImageHandle() +{ + return BlpStatus.ImageHandle; +} + +/** + * Returns the EFI system table. + * + * @return This routine returns the current EFI system table. + * + * @since XT 1.0 + */ +XTCDECL +PEFI_SYSTEM_TABLE +BlGetEfiSystemTable() +{ + return BlpStatus.SystemTable; +} + /** * Puts the system to sleep for the specified number of milliseconds. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 961718f..dea207d 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -52,6 +52,14 @@ VOID BlDebugPrint(IN PUINT16 Format, IN ...); +XTCDECL +EFI_HANDLE +BlGetEfiImageHandle(); + +XTCDECL +PEFI_SYSTEM_TABLE +BlGetEfiSystemTable(); + XTCDECL EFI_STATUS BlMemoryFreePages(IN UINT64 Pages, -- 2.45.1 From 0a1df55a0fe93ab978be897def9ced7357f69e53 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 4 Dec 2023 18:53:11 +0100 Subject: [PATCH 029/182] Add XTLDR protocol support, add missing source file --- xtldr2/protocol.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 xtldr2/protocol.c diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c new file mode 100644 index 0000000..6e8d1bb --- /dev/null +++ b/xtldr2/protocol.c @@ -0,0 +1,111 @@ +/** + * 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.GetImageHandle = BlGetEfiImageHandle; + LdrProtocol.Util.GetSystemTable = BlGetEfiSystemTable; + 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); +} -- 2.45.1 From c4f1429a3b092c419687676e82d115868fbb6adb Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 4 Dec 2023 18:58:00 +0100 Subject: [PATCH 030/182] Not really needed as each module will get both ImageHandle and SystemTable --- sdk/xtdk/bltypes.h | 4 ---- xtldr2/efiutils.c | 28 ---------------------------- xtldr2/includes/bootman.h | 8 -------- xtldr2/protocol.c | 2 -- 4 files changed, 42 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index e3590e3..c00a15f 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -28,8 +28,6 @@ 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_HANDLE (*PBL_GET_EFI_IMAGE_HANDLE)(); -typedef PEFI_SYSTEM_TABLE (*PBL_GET_EFI_SYSTEM_TABLE)(); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); @@ -81,8 +79,6 @@ typedef struct _XTBL_LOADER_PROTOCOL struct { PBL_EXIT_BOOT_SERVICES ExitBootServices; - PBL_GET_EFI_IMAGE_HANDLE GetImageHandle; - PBL_GET_EFI_SYSTEM_TABLE GetSystemTable; PBL_SLEEP_EXECUTION SleepExecution; } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 5c1f3f0..104db69 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -44,34 +44,6 @@ BlExitBootServices(IN UINT_PTR MapKey) return Status; } -/** - * Returns the EFI image handle. - * - * @return This routine returns the current EFI image handle. - * - * @since XT 1.0 - */ -XTCDECL -EFI_HANDLE -BlGetEfiImageHandle() -{ - return BlpStatus.ImageHandle; -} - -/** - * Returns the EFI system table. - * - * @return This routine returns the current EFI system table. - * - * @since XT 1.0 - */ -XTCDECL -PEFI_SYSTEM_TABLE -BlGetEfiSystemTable() -{ - return BlpStatus.SystemTable; -} - /** * Puts the system to sleep for the specified number of milliseconds. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index dea207d..961718f 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -52,14 +52,6 @@ VOID BlDebugPrint(IN PUINT16 Format, IN ...); -XTCDECL -EFI_HANDLE -BlGetEfiImageHandle(); - -XTCDECL -PEFI_SYSTEM_TABLE -BlGetEfiSystemTable(); - XTCDECL EFI_STATUS BlMemoryFreePages(IN UINT64 Pages, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 6e8d1bb..34aa2bb 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -101,8 +101,6 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.FreePool = BlMemoryFreePool; LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Util.ExitBootServices = BlExitBootServices; - LdrProtocol.Util.GetImageHandle = BlGetEfiImageHandle; - LdrProtocol.Util.GetSystemTable = BlGetEfiSystemTable; LdrProtocol.Util.SleepExecution = BlSleepExecution; /* Register XTLDR loader protocol */ -- 2.45.1 From 6733146b7124f67e5d45eac0175db234e82ca83a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 5 Dec 2023 22:18:25 +0100 Subject: [PATCH 031/182] Refactor, part 7; register XTLDR protocol --- bootdata/xtldr/xtldr.ini | 2 -- sdk/xtdk/bltypes.h | 5 ++++- xtldr2/config.c | 21 +++------------------ xtldr2/includes/bootman.h | 13 +++++++++++-- xtldr2/xtldr.c | 14 +++++++++++++- 5 files changed, 31 insertions(+), 24 deletions(-) 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 index c00a15f..60d52e5 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -13,6 +13,10 @@ #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 @@ -38,7 +42,6 @@ typedef struct _XTBL_CONFIGURATION PWCHAR Debug; ULONG DebugPort; BOOLEAN Shell; - PWCHAR Theme; ULONG Timeout; PWCHAR Tune; } XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; diff --git a/xtldr2/config.c b/xtldr2/config.c index c0b5b13..22c8de4 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -18,7 +18,7 @@ */ XTCDECL VOID -BlpConfigParseCommandLine(VOID) +BlpParseCommandLineOptions(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -32,7 +32,7 @@ BlpConfigParseCommandLine(VOID) if(LoadedImage && LoadedImage->LoadOptions) { /* Update global boot loader configuration */ - BlpConfigUpdateGlobalConfiguration(LoadedImage->LoadOptions); + BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions); } } } @@ -49,7 +49,7 @@ BlpConfigParseCommandLine(VOID) */ XTCDECL VOID -BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) +BlpUpdateGlobalConfiguration(IN PWCHAR Options) { PWCHAR Argument, LastArg; SIZE_T Length; @@ -92,21 +92,6 @@ BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) /* 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); - - /* Store theme configuration if not set already */ - if(BlpConfiguration.Theme == NULL) - { - /* 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/includes/bootman.h b/xtldr2/includes/bootman.h index 961718f..e0ad29c 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -61,6 +61,11 @@ XTCDECL EFI_STATUS BlMemoryFreePool(IN PVOID Memory); +XTCDECL +EFI_STATUS +BlOpenXtProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); + XTCDECL VOID BlSleepExecution(IN ULONG_PTR Milliseconds); @@ -76,11 +81,11 @@ BlpActivateSerialIOController(); XTCDECL VOID -BlpConfigParseCommandLine(VOID); +BlpParseCommandLineOptions(VOID); XTCDECL VOID -BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options); +BlpUpdateGlobalConfiguration(IN PWCHAR Options); XTCDECL VOID @@ -108,6 +113,10 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG PortAddress, IN ULONG BaudRate); +XTCDECL +EFI_STATUS +BlpRegisterXtLoaderProtocol(); + XTCDECL VOID BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 7a850d7..513cca2 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -29,12 +29,16 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, { EFI_STATUS Status; + /* Set the system table and image handle */ + EfiImageHandle = ImageHandle; + EfiSystemTable = SystemTable; + /* 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 */ - BlpConfigParseCommandLine(); + BlpParseCommandLineOptions(); /* Attempt to early initialize debug console */ if(DEBUG) @@ -56,6 +60,14 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, 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(;;); -- 2.45.1 From 1c94f9ff02aa0a4c69b0afd25c63a682857c325f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 6 Dec 2023 22:47:54 +0100 Subject: [PATCH 032/182] Improvements in string and wide string support * Implement RtlCompareString(), RtlCompareStringInsensitive(), RtlCompareWideString() and RtlCompareWideStringInsensitive() * Rename some routines t omatch naming conventions * Switch to CHAR in string operations --- sdk/xtdk/rtlfuncs.h | 54 ++++++++---- xtldr/efiutil.c | 12 +-- xtldr/modules/xtos/xtos.c | 2 +- xtldr/xtldr.c | 2 +- xtoskrnl/rtl/string.c | 131 +++++++++++++++++++++++++++-- xtoskrnl/rtl/widestr.c | 171 ++++++++++++++++++++++++++------------ xtoskrnl/xtoskrnl.spec | 9 +- 7 files changed, 294 insertions(+), 87 deletions(-) diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index b131ee2..4f275ad 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -54,6 +54,36 @@ RtlCompareMemory(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length); +XTCDECL +SIZE_T +RtlCompareString(IN CONST PCHAR String1, + IN CONST PCHAR String2, + IN SIZE_T Length); + +XTCDECL +SIZE_T +RtlCompareStringInsensitive(IN CONST PCHAR String1, + IN CONST PCHAR String2, + IN SIZE_T Length); + +XTCDECL +SIZE_T +RtlCompareWideString(IN CONST PWCHAR String1, + IN CONST PWCHAR String2, + IN SIZE_T Length); + +XTCDECL +SIZE_T +RtlCompareWideStringInsensitive(IN CONST PWCHAR String1, + IN CONST PWCHAR String2, + IN SIZE_T Length); + +XTCDECL +PWCHAR +RtlConcatenateWideString(OUT PWCHAR Destination, + IN PWCHAR Source, + IN SIZE_T Count); + XTAPI VOID RtlCopyMemory(OUT PVOID Destination, @@ -86,38 +116,26 @@ RtlSetMemory(OUT PVOID Destination, XTCDECL SIZE_T -RtlStringLength(IN CONST PUCHAR String, +RtlStringLength(IN CONST PCHAR String, IN SIZE_T MaxLength); XTCDECL -INT +SIZE_T RtlStringToWideString(OUT PWCHAR Destination, - IN CONST PUCHAR *Source, + IN CONST PCHAR *Source, IN SIZE_T Length); -XTCDECL -INT -RtlWideStringCompare(IN CONST PWCHAR String1, - IN CONST PWCHAR String2, - IN CONST SIZE_T Length); - XTCDECL PWCHAR -RtlWideStringConcatenate(OUT PWCHAR Destination, - IN PWCHAR Source, - IN SIZE_T Count); +RtlTokenizeWideString(IN PWCHAR String, + IN CONST PWCHAR Delimiter, + IN OUT PWCHAR *SavePtr); XTCDECL SIZE_T RtlWideStringLength(IN CONST PWCHAR String, IN SIZE_T MaxLength); -XTCDECL -PWCHAR -RtlWideStringTokenize(IN PWCHAR String, - IN CONST PWCHAR Delimiter, - IN OUT PWCHAR *SavePtr); - XTAPI VOID RtlWriteRegisterByte(IN VOLATILE PVOID Register, diff --git a/xtldr/efiutil.c b/xtldr/efiutil.c index 7c2201c..39d01a3 100644 --- a/xtldr/efiutil.c +++ b/xtldr/efiutil.c @@ -146,19 +146,19 @@ BlComPortInitialize() CommandLine = (PWCHAR)LoadedImage->LoadOptions; /* Find command in command line */ - Argument = RtlWideStringTokenize(CommandLine, L" ", &LastArg); + Argument = RtlTokenizeWideString(CommandLine, L" ", &LastArg); /* Iterate over all arguments passed to boot loader */ while(Argument != NULL) { /* Check if this is DEBUG parameter */ - if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) + if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; /* Make sure COM port is being used */ - if(RtlWideStringCompare(Argument, L"COM", 3)) + if(RtlCompareWideString(Argument, L"COM", 3)) { /* Invalid debug port specified */ BlEfiPrint(L"ERROR: Invalid debug port specified, falling back to defaults\n"); @@ -176,7 +176,7 @@ BlComPortInitialize() } /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlWideStringCompare(Argument, L":0x", 3) == 0) + if(PortNumber == 0 && RtlCompareWideString(Argument, L":0x", 3) == 0) { /* COM port address provided */ Argument += 3; @@ -221,7 +221,7 @@ BlComPortInitialize() } /* Take next argument */ - Argument = RtlWideStringTokenize(NULL, L" ", &LastArg); + Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); } } } @@ -349,7 +349,7 @@ BlEfiPrint(IN PUINT16 Format, BlStringPrint(BlConsolePutChar, Format, Arguments); /* Print to serial console only if not running under OVMF */ - if(RtlWideStringCompare(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) + if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) { /* Check if debugging enabled and if EFI serial port is fully initialized */ if(DEBUG && (EfiSerialPort.Flags & COMPORT_FLAG_INIT)) diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index 07b963f..c663e6a 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -132,7 +132,7 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters) } /* System path has to point to the boot directory */ - RtlWideStringConcatenate(Parameters->SystemPath, L"\\Boot", 0); + RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0); /* Open XTOS system boot directory */ Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 09bf22f..dd9abee 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -116,7 +116,7 @@ BlLoadEfiModules() /* Set correct path to the module file */ RtlCopyMemory(ModulePath, ModulesDirPath, sizeof(ModulePath) / sizeof(WCHAR)); - RtlWideStringConcatenate(ModulePath, ModuleName, 0); + RtlConcatenateWideString(ModulePath, ModuleName, 0); /* Find valid device path */ Status = BlFindVolumeDevicePath(DevicePath, ModulePath, &VolumeDevicePath); diff --git a/xtoskrnl/rtl/string.c b/xtoskrnl/rtl/string.c index aef02b2..3716d6b 100644 --- a/xtoskrnl/rtl/string.c +++ b/xtoskrnl/rtl/string.c @@ -9,6 +9,125 @@ #include +/** + * Compares at most specified number of characters of two C strings. + * + * @param String1 + * String to be compared. + * + * @param String2 + * String to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole strings. + * + * @return Integral value indicating the relationship between the strings. + * + * @since XT 1.0 + */ +XTCDECL +SIZE_T +RtlCompareString(IN CONST PCHAR String1, + IN CONST PCHAR String2, + IN SIZE_T Length) +{ + SIZE_T Index; + + /* Iterate through the strings */ + for(Index = 0; ; Index++) { + /* Check if length limit reached */ + if(Index != 0 && Index == Length) + { + /* Skip checking next characters */ + break; + } + + /* Check if string characters are equal */ + if(String1[Index] != String2[Index]) + { + /* Different characters found */ + return String1[Index] < String2[Index] ? -1 : 1; + } + + /* Check if end of string reached */ + if(!String1[Index] || !String2[Index]) + { + /* Equal strings until the end of one of them */ + return 0; + } + } + + /* Strings are equal */ + return 0; +} + +/** + * Compares at most specified number of characters of two C strings, while ignoring differences in case. + * + * @param String1 + * String to be compared. + * + * @param String2 + * String to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole strings. + * + * @return Integral value indicating the relationship between the strings. + * + * @since XT 1.0 + */ +XTCDECL +SIZE_T +RtlCompareStringInsensitive(IN CONST PCHAR String1, + IN CONST PCHAR String2, + IN SIZE_T Length) +{ + CHAR Character1; + CHAR Character2; + ULONG Index = 0; + + /* Iterate through the strings */ + while(String1[Index] != '\0' && String2[Index] != '\0') + { + /* Check if length limit reached */ + if(Index != 0 && Index == Length) + { + /* Skip checking next characters */ + break; + } + + /* Get the characters */ + Character1 = String1[Index]; + Character2 = String2[Index]; + + /* Lowercase string1 character if needed */ + if(String1[Index] >= 'A' && String1[Index] <= 'Z') + { + Character1 = String1[Index] - 'A' + 'a'; + } + + /* Lowercase string2 character if needed */ + if(String2[Index] >= 'A' && String2[Index] <= 'Z') + { + Character2 = String2[Index] - 'A' + 'a'; + } + + /* Compare the characters */ + if(Character1 != Character2) + { + /* Strings are not equal */ + return Character1 > Character2 ? 1 : -1; + } + + /* Get next character */ + Index++; + } + + /* Strings are equal */ + return 0; +} + /** * Calculates the length of a given string. * @@ -24,7 +143,7 @@ */ XTCDECL SIZE_T -RtlStringLength(IN CONST PUCHAR String, +RtlStringLength(IN CONST PCHAR String, IN SIZE_T MaxLength) { SIZE_T Length; @@ -47,7 +166,7 @@ RtlStringLength(IN CONST PUCHAR String, } } - /* Return wide string length */ + /* Return string length */ return Length; } @@ -68,12 +187,12 @@ RtlStringLength(IN CONST PUCHAR String, * @since XT 1.0 */ XTCDECL -INT +SIZE_T RtlStringToWideString(OUT PWCHAR Destination, - IN CONST PUCHAR *Source, + IN CONST PCHAR *Source, IN SIZE_T Length) { - PUCHAR LocalSource = *Source; + PCHAR LocalSource = *Source; SIZE_T Count = Length; if(Destination == NULL) @@ -83,7 +202,7 @@ RtlStringToWideString(OUT PWCHAR Destination, while(Count) { - if((*Destination = (UCHAR)*LocalSource) == 0) + if((*Destination = *LocalSource) == 0) { LocalSource = NULL; break; diff --git a/xtoskrnl/rtl/widestr.c b/xtoskrnl/rtl/widestr.c index 57e1fe2..6bb77c4 100644 --- a/xtoskrnl/rtl/widestr.c +++ b/xtoskrnl/rtl/widestr.c @@ -19,17 +19,17 @@ * Wide string to be compared. * * @param Length - * Maximum number of characters to compare. If no limit set, it compares whole strings. + * Maximum number of characters to compare. If no limit set, it compares whole wide strings. * * @return Integral value indicating the relationship between the wide strings. * * @since XT 1.0 */ XTCDECL -INT -RtlWideStringCompare(IN CONST PWCHAR String1, +SIZE_T +RtlCompareWideString(IN CONST PWCHAR String1, IN CONST PWCHAR String2, - IN CONST SIZE_T Length) + IN SIZE_T Length) { SIZE_T Index; @@ -42,22 +42,89 @@ RtlWideStringCompare(IN CONST PWCHAR String1, break; } - /* Check if string characters are equal */ + /* Check if wide string characters are equal */ if(String1[Index] != String2[Index]) { /* Different characters found */ return String1[Index] < String2[Index] ? -1 : 1; } - /* Check if end of string reached */ + /* Check if end of wide string reached */ if(!String1[Index] || !String2[Index]) { - /* Equal strings until the end of one of them */ + /* Equal wide strings until the end of one of them */ return 0; } } - /* Strings are equal */ + /* Wide strings are equal */ + return 0; +} + +/** + * Compares at most specified number of characters of two C wide strings, while ignoring differences in case. + * + * @param String1 + * Wide string to be compared. + * + * @param String2 + * Wide string to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole wide strings. + * + * @return Integral value indicating the relationship between the wide strings. + * + * @since XT 1.0 + */ +XTCDECL +SIZE_T +RtlCompareWideStringInsensitive(IN CONST PWCHAR String1, + IN CONST PWCHAR String2, + IN SIZE_T Length) +{ + WCHAR Character1; + WCHAR Character2; + ULONG Index = 0; + + /* Iterate through the wide strings */ + while(String1[Index] != '\0' && String2[Index] != '\0') + { + /* Check if length limit reached */ + if(Index != 0 && Index == Length) + { + /* Skip checking next characters */ + break; + } + + /* Get the characters */ + Character1 = String1[Index]; + Character2 = String2[Index]; + + /* Lowercase wide string1 character if needed */ + if(String1[Index] >= 'A' && String1[Index] <= 'Z') + { + Character1 = String1[Index] - 'A' + 'a'; + } + + /* Lowercase wide string2 character if needed */ + if(String2[Index] >= 'A' && String2[Index] <= 'Z') + { + Character2 = String2[Index] - 'A' + 'a'; + } + + /* Compare the characters */ + if(Character1 != Character2) + { + /* Wide strings are not equal */ + return Character1 > Character2 ? 1 : -1; + } + + /* Get next character */ + Index++; + } + + /* Wide strings are equal */ return 0; } @@ -79,7 +146,7 @@ RtlWideStringCompare(IN CONST PWCHAR String1, */ XTCDECL PWCHAR -RtlWideStringConcatenate(OUT PWCHAR Destination, +RtlConcatenateWideString(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count) { @@ -120,48 +187,6 @@ RtlWideStringConcatenate(OUT PWCHAR Destination, return DestString; } -/** - * Calculates the length of a given wide string. - * - * @param String - * Pointer to the null-terminated wide string to be examined. - * - * @param MaxLength - * Maximum number of wide characters to examine. If no limit set, it examines whole string. - * - * @return The length of the null-terminated wide string. - * - * @since: XT 1.0 - */ -XTCDECL -SIZE_T -RtlWideStringLength(IN CONST PWCHAR String, - IN SIZE_T MaxLength) -{ - SIZE_T Length; - - /* Check if NULL pointer passed */ - if(String == NULL) - { - return 0; - } - - /* Iterate through the wide string */ - for(Length = 0; ; Length++) - { - - /* Check if NULL found or max length limit reached */ - if((Length != 0 && Length == MaxLength) || !String[Length]) - { - /* Finish examination */ - break; - } - } - - /* Return wide string length */ - return Length; -} - /** * Finds the next token in a null-terminated wide string. * @@ -180,7 +205,7 @@ RtlWideStringLength(IN CONST PWCHAR String, */ XTCDECL PWCHAR -RtlWideStringTokenize(IN PWCHAR String, +RtlTokenizeWideString(IN PWCHAR String, IN CONST PWCHAR Delimiter, IN OUT PWCHAR *SavePtr) { @@ -231,3 +256,45 @@ RtlWideStringTokenize(IN PWCHAR String, while(SpanChar != L'\0'); } } + +/** + * Calculates the length of a given wide string. + * + * @param String + * Pointer to the null-terminated wide string to be examined. + * + * @param MaxLength + * Maximum number of wide characters to examine. If no limit set, it examines whole string. + * + * @return The length of the null-terminated wide string. + * + * @since: XT 1.0 + */ +XTCDECL +SIZE_T +RtlWideStringLength(IN CONST PWCHAR String, + IN SIZE_T MaxLength) +{ + SIZE_T Length; + + /* Check if NULL pointer passed */ + if(String == NULL) + { + return 0; + } + + /* Iterate through the wide string */ + for(Length = 0; ; Length++) + { + + /* Check if NULL found or max length limit reached */ + if((Length != 0 && Length == MaxLength) || !String[Length]) + { + /* Finish examination */ + break; + } + } + + /* Return wide string length */ + return Length; +} diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index 9a79a41..0864d76 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -32,12 +32,15 @@ @ stdcall RtlReadRegisterByte(ptr) @ stdcall RtlReadRegisterLong(ptr) @ stdcall RtlReadRegisterShort(ptr) +@ cdecl RtlCompareString(str str long) +@ cdecl RtlCompareStringInsensitive(str str long) @ cdecl RtlStringLength(str long) @ cdecl RtlStringToWideString(wstr str long) -@ cdecl RtlWideStringCompare(wstr wstr long) -@ cdecl RtlWideStringConcatenate(wstr wstr long) +@ cdecl RtlCompareWideString(wstr wstr long) +@ cdecl RtlCompareWideStringInsensitive(wstr wstr long) +@ cdecl RtlConcatenateWideString(wstr wstr long) +@ cdecl RtlTokenizeWideString(wstr wstr wstr) @ cdecl RtlWideStringLength(wstr long) -@ cdecl RtlWideStringTokenize(wstr wstr wstr) @ stdcall RtlWriteRegisterByte(ptr long) @ stdcall RtlWriteRegisterLong(ptr long) @ stdcall RtlWriteRegisterShort(ptr long) -- 2.45.1 From cd1ab2128bcb3f53b569f619fa285dfb1f1611df Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 6 Dec 2023 22:56:31 +0100 Subject: [PATCH 033/182] Match new RTL API to fix build --- xtldr2/config.c | 14 +++++++------- xtldr2/console.c | 2 +- xtldr2/debug.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 22c8de4..b3f845a 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -55,13 +55,13 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) SIZE_T Length; /* Tokenize provided options */ - Argument = RtlWideStringTokenize(Options, L" ", &LastArg); + Argument = RtlTokenizeWideString(Options, L" ", &LastArg); /* Iterate over all arguments passed to boot loader */ while(Argument != NULL) { /* Check all provided parameters */ - if(RtlWideStringCompare(Argument, L"DEFAULT=", 8) == 0) + if(RtlCompareWideString(Argument, L"DEFAULT=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; @@ -72,7 +72,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Default[Length] = '\0'; } - else if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) + else if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; @@ -87,12 +87,12 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) BlpConfiguration.Debug[Length] = '\0'; } } - else if(RtlWideStringCompare(Argument, L"SHELL", 5) == 0) + else if(RtlCompareWideString(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } - else if(RtlWideStringCompare(Argument, L"TIMEOUT=", 8) == 0) + else if(RtlCompareWideString(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ Argument += 8; @@ -108,7 +108,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) Argument++; } } - else if(RtlWideStringCompare(Argument, L"TUNE=", 5) == 0) + else if(RtlCompareWideString(Argument, L"TUNE=", 5) == 0) { /* Skip to the argument value */ Argument += 5; @@ -121,6 +121,6 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) } /* Take next argument */ - Argument = RtlWideStringTokenize(NULL, L" ", &LastArg); + Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); } } diff --git a/xtldr2/console.c b/xtldr2/console.c index c0911c9..08f2341 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -79,7 +79,7 @@ BlConsolePrint(IN PUINT16 Format, BlpStringPrint(BlpConsolePrintChar, Format, Arguments); /* Print to serial console only if not running under OVMF */ - if(RtlWideStringCompare(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) + if(RtlCompareWideString(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)) diff --git a/xtldr2/debug.c b/xtldr2/debug.c index 3a4b689..87b4a08 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -78,13 +78,13 @@ BlpInitializeDebugConsole() if(BlpConfiguration.Debug) { /* Find all debug ports */ - DebugPort = RtlWideStringTokenize(BlpConfiguration.Debug, L";", &LastPort); + DebugPort = RtlTokenizeWideString(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) + if(RtlCompareWideString(DebugPort, L"COM", 3) == 0) { /* Read COM port number */ DebugPort += 3; @@ -97,7 +97,7 @@ BlpInitializeDebugConsole() } /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlWideStringCompare(DebugPort, L":0x", 3) == 0) + if(PortNumber == 0 && RtlCompareWideString(DebugPort, L":0x", 3) == 0) { /* COM port address provided */ DebugPort += 3; @@ -140,7 +140,7 @@ BlpInitializeDebugConsole() /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; } - else if(RtlWideStringCompare(DebugPort, L"SCREEN", 5) == 0) + else if(RtlCompareWideString(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN; @@ -153,7 +153,7 @@ BlpInitializeDebugConsole() } /* Take next debug port */ - DebugPort = RtlWideStringTokenize(NULL, L";", &LastPort); + DebugPort = RtlTokenizeWideString(NULL, L";", &LastPort); } } -- 2.45.1 From 2356f4da54a320988e3820bf23dda07beea4a070 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 6 Dec 2023 23:09:43 +0100 Subject: [PATCH 034/182] Import volumes suppport --- xtldr2/CMakeLists.txt | 1 + xtldr2/globals.c | 3 + xtldr2/includes/bootman.h | 55 +++ xtldr2/includes/globals.h | 3 + xtldr2/volume.c | 900 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 962 insertions(+) create mode 100644 xtldr2/volume.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 2004d41..cda9b16 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c + # ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 6017862..ae67696 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -21,6 +21,9 @@ CPPORT BlpSerialPort; /* XT Boot Loader status data */ XTBL_STATUS BlpStatus = {0}; +/* List of available block devices */ +LIST_ENTRY EfiBlockDevices; + /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index e0ad29c..2a1647a 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -16,10 +16,31 @@ typedef VOID (BMPRINTCHAR)(IN USHORT Character); /* XTLDR routines forward references */ +XTCDECL +EFI_STATUS +BlCloseVolume(IN PEFI_HANDLE VolumeHandle); + +XTCDECL +EFI_STATUS +BlEnumerateBlockDevices(); + XTCDECL EFI_STATUS BlExitBootServices(IN UINT_PTR MapKey); +XTCDECL +EFI_STATUS +BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); + +XTCDECL +EFI_STATUS +BlGetVolumeDevicePath(IN PCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PCHAR *ArcName, + OUT PCHAR *Path); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, @@ -30,6 +51,12 @@ EFI_STATUS BlMemoryAllocatePool(IN UINT_PTR Size, OUT PVOID *Memory); +XTCDECL +EFI_STATUS +BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle); + XTCDECL VOID BlConsoleClearScreen(); @@ -79,6 +106,34 @@ XTCDECL EFI_STATUS BlpActivateSerialIOController(); +XTCDECL +EFI_STATUS +BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); + +XTCDECL +EFI_STATUS +BlpDissectVolumeArcPath(IN PCHAR SystemPath, + OUT PCHAR *ArcName, + OUT PCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber); + +XTCDECL +PEFI_DEVICE_PATH_PROTOCOL +BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); + +XTCDECL +EFI_STATUS +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); + +XTCDECL +BOOLEAN +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode); + XTCDECL VOID BlpParseCommandLineOptions(VOID); diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 9d09f76..c43b052 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -24,6 +24,9 @@ EXTERN CPPORT BlpSerialPort; /* XT Boot Loader status data */ EXTERN XTBL_STATUS BlpStatus; +/* List of available block devices */ +EXTERN LIST_ENTRY EfiBlockDevices; + /* EFI Image Handle */ EXTERN EFI_HANDLE EfiImageHandle; diff --git a/xtldr2/volume.c b/xtldr2/volume.c new file mode 100644 index 0000000..8176190 --- /dev/null +++ b/xtldr2/volume.c @@ -0,0 +1,900 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/volume.c + * DESCRIPTION: XTLDR volume support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine closes an EFI volume handle. + * + * @param VolumeHandle + * Specifies a handle of opened volume. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlCloseVolume(IN PEFI_HANDLE VolumeHandle) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + + /* Make sure a handle specified */ + if(VolumeHandle != NULL) + { + /* Close a handle */ + return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL); + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Discovers and enumerates a block devices available to EFI system. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlEnumerateBlockDevices() +{ + PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; + PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; + PEFI_BLOCK_DEVICE_DATA BlockDeviceData; + PEFI_BLOCK_DEVICE BlockDevice; + LIST_ENTRY BlockDevices; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + PEFI_ACPI_HID_DEVICE_PATH AcpiDevice; + PEFI_HARDDRIVE_DEVICE_PATH HDPath; + PEFI_BLOCK_IO_MEDIA Media; + PEFI_GUID PartitionGuid; + ULONG DriveNumber, PartitionNumber; + USHORT DriveType; + ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; + + /* Initialize list entries */ + RtlInitializeListHead(&BlockDevices); + RtlInitializeListHead(&EfiBlockDevices); + + /* Discover EFI block devices and store them in linked list */ + Status = BlpDiscoverEfiBlockDevices(&BlockDevices); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"ERROR: Failed to discover EFI block devices (status code: %lx)\n", Status); + return Status; + } + + /* Identify all discovered devices */ + ListEntry = BlockDevices.Flink; + while(ListEntry != &BlockDevices) + { + /* Take block device from the list */ + BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); + + /* Find last node */ + Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"WARNING: Block device last node not found\n"); + ListEntry = ListEntry->Flink; + continue; + } + + /* Set drive type to 'unknown' by default */ + DriveType = XTBL_BOOT_DEVICE_UNKNOWN; + + /* Check last node type */ + if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP) + { + /* Check for Floppy EISA identifiers */ + AcpiDevice = (PEFI_ACPI_HID_DEVICE_PATH)LastNode; + if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1) + { + /* Floppy drive found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_FLOPPY; + DriveNumber = FDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", + DriveNumber, Media->MediaPresent, Media->ReadOnly); + } + } + else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH) + { + /* Media device path found */ + if(LastNode->SubType == EFI_MEDIA_CDROM_DP) + { + /* Optical drive found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_CDROM; + DriveNumber = CDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", + DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); + } + else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) + { + /* Hard disk partition found */ + Media = BlockDeviceData->BlockIo->Media; + HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode; + DriveType = XTBL_BOOT_DEVICE_HARDDISK; + DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1; + PartitionNumber = HDPath->PartitionNumber; + PartitionGuid = (PEFI_GUID)HDPath->Signature; + + /* Print debug message */ + BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " + L"MBRType: %u, GUID: {%g}, PartSize: %luB)\n", + DriveNumber, PartitionNumber, HDPath->MBRType, + PartitionGuid, HDPath->PartitionSize * Media->BlockSize); + } + else if(LastNode->SubType == EFI_MEDIA_RAMDISK_DP) + { + /* RAM disk found */ + Media = BlockDeviceData->BlockIo->Media; + DriveType = XTBL_BOOT_DEVICE_RAMDISK; + DriveNumber = RDCount++; + PartitionNumber = 0; + + /* Print debug message */ + BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", + DriveNumber, Media->MediaPresent); + } + + if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode)) + { + BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); + continue; + } + } + + /* Make sure the device found has valid type set */ + if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) + { + /* Allocate memory for block device */ + Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); + if(Status != STATUS_EFI_SUCCESS) + { + BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Initialize block device */ + BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); + BlockDevice->DriveType = DriveType; + BlockDevice->DriveNumber = DriveNumber; + BlockDevice->PartitionNumber = PartitionNumber; + BlockDevice->PartitionGuid = PartitionGuid; + + /* Add block device to global list */ + RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); + } + + /* Get next entry from linked list */ + ListEntry = ListEntry->Flink; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Finds an EFI device path for a specified path on a given file system. + * + * @param FsHandle + * The handle of the corresponding file system. + * + * @param FileSystemPath + * Specifies a path on the corresponding file system. + * + * @param DevicePath + * Specifies a pointer to the memory area, where found device path will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) +{ + EFI_STATUS Status; + SIZE_T FsPathLength, DevicePathLength = 0; + PEFI_FILEPATH_DEVICE_PATH FilePath = NULL; + PEFI_DEVICE_PATH_PROTOCOL EndDevicePath; + PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle; + + /* Set local device path handle */ + DevicePathHandle = FsHandle; + + /* Find the end device path node */ + while(TRUE) { + /* Make sure there is a next node */ + if(*(PUSHORT)DevicePathHandle->Length == 0) + { + /* End device path not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Check if end device path node found */ + if(DevicePathHandle->Type == EFI_END_DEVICE_PATH) + { + /* End device path node found */ + break; + } + + /* Get next node */ + DevicePathLength += *(PUSHORT)DevicePathHandle->Length; + DevicePathHandle = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathHandle + *(PUSHORT)DevicePathHandle->Length); + } + + /* Check real path length */ + FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); + + /* Allocate memory pool for device path */ + Status = BlMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), + (PVOID *)DevicePath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set file path */ + RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength); + FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength); + FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH; + FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP; + FilePath->Header.Length[0] = (UCHAR)FsPathLength + FIELD_OFFSET(EFI_FILEPATH_DEVICE_PATH, PathName) + sizeof(WCHAR); + FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8; + + /* Set device path end node */ + RtlCopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR)); + EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1]; + EndDevicePath->Type = EFI_END_DEVICE_PATH; + EndDevicePath->SubType = EFI_END_ENTIRE_DP; + EndDevicePath->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + EndDevicePath->Length[1] = 0; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Finds a volume device path based on the specified ARC name or UUID. + * + * @param SystemPath + * An input string containing ARC/UUID path. + * + * @param DevicePath + * Supplies a pointer to memory region where device path will be stored. + * + * @param Path + * Supplies a pointer to the memory area, where path on device will be saved. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlGetVolumeDevicePath(IN PCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PCHAR *ArcName, + OUT PCHAR *Path) +{ + PEFI_BLOCK_DEVICE Device; + USHORT DriveType; + ULONG DriveNumber; + ULONG PartNumber; + PCHAR Volume; + ULONG PathLength; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + + /* Make sure this is not set */ + *DevicePath = NULL; + + /* Find volume path and its length */ + Volume = SystemPath; + while(*Volume != '/' && *Volume != '\\' && *Volume != '\0') + { + Volume++; + } + PathLength = Volume - SystemPath; + + /* Check if valume path specified */ + if(PathLength == 0) + { + /* No volume path available */ + *Path = SystemPath; + return STATUS_EFI_NOT_FOUND; + } + + /* Check system path format */ + if(SystemPath[0] == '{') + { + if(PathLength == GUID_STRING_LENGTH) + { + /* This is EFI GUID */ + BlDebugPrint(L"EFI/GPT GUID in system path is not supported yet\n"); + return STATUS_EFI_UNSUPPORTED; + } + else if(PathLength == PARTUUID_STRING_LENGTH) + { + /* This is MBR UUID */ + BlDebugPrint(L"MBR partition UUID in system path is not supported yet\n"); + return STATUS_EFI_UNSUPPORTED; + } + else + { + /* Invalid UUID format */ + return STATUS_EFI_INVALID_PARAMETER; + } + } + else + { + /* Defaults to ARC path, dissect it */ + Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); + } + + /* Check if volume path parsed successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to parse system path */ + BlDebugPrint(L"Failed to parse system path: '%s' with status code: %lx\n", SystemPath, Status); + return Status; + } + + /* Look for block device corresponding to dissected ARC path */ + ListEntry = EfiBlockDevices.Flink; + while(ListEntry != &EfiBlockDevices) + { + /* Check if this is the volume we are looking for */ + Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry); + if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber && + Device->PartitionNumber == PartNumber)) + { + /* Found volume */ + *DevicePath = Device->DevicePath; + break; + } + ListEntry = ListEntry->Flink; + } + + /* Check if volume was found */ + if(*DevicePath == NULL) + { + /* Failed to find volume */ + BlDebugPrint(L"Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", + DriveType, DriveNumber, PartNumber); + return STATUS_EFI_NOT_FOUND; + } + + /* return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine opens an EFI volume and corresponding filesystem. + * + * @param DevicePath + * Specifies a device path of the volume to open. If not specifies, uses image protocol by default. + * + * @param DiskHandle + * The handle of the opened disk volume. + * + * @param FsHandle + * The handle of the opened file system. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle) +{ + EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL FileSystemProtocol; + PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; + EFI_STATUS Status; + + /* Check if device path has been passed or not */ + if(DevicePath != NULL) + { + /* Locate the device path */ + Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to locate device path */ + return Status; + } + } + else + { + /* Open the image protocol if no device path specified */ + Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open image protocol */ + return Status; + } + + /* Store disk handle */ + *DiskHandle = ImageProtocol->DeviceHandle; + } + + /* Open the filesystem protocol */ + Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + + /* Check if filesystem protocol opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the filesystem protocol, close volume */ + BlCloseVolume(*DiskHandle); + return Status; + } + + /* Open the corresponding filesystem */ + Status = FileSystemProtocol->OpenVolume(FileSystemProtocol, FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the filesystem, close volume */ + BlCloseVolume(*DiskHandle); + return Status; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Gets a list of block devices from an EFI enabled BIOS. + * + * @param BlockDevices + * Supplies a pointer to a variable to receive a list of EFI block devices. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) +{ + EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; + EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; + PEFI_DEVICE_PATH_PROTOCOL DevicePath; + PEFI_BLOCK_DEVICE_DATA BlockDevice; + UINT_PTR HandlesCount, Index; + PEFI_HANDLE Handles = NULL; + PEFI_BLOCK_IO_PROTOCOL Io; + EFI_STATUS Status; + + /* Locate handles which support the disk I/O interface */ + Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, &IoGuid, NULL, &HandlesCount, &Handles); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to locate handles */ + BlDebugPrint(L"ERROR: Failed to locate block devices handles (status code: %lx)\n", Status); + return Status; + } + + /* Iterate through all handles */ + for(Index = 0; Index < HandlesCount; Index++) + { + /* Print debug message */ + BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); + + /* Open I/O protocol for given handle */ + Io = NULL; + Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], &IoGuid, (PVOID *)&Io, EfiImageHandle, + NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS || Io == NULL) + { + /* Failed to open I/O protocol, skip it */ + BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (status code: %lx)\n", Status); + continue; + } + + /* Check if this is iPXE stub */ + if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) + { + /* Skip stub as it is non-functional */ + BlDebugPrint(L"WARNING: iPXE stub block I/O protocol"); + continue; + } + + /* Check if DevicePath protocol is supported by this handle */ + DevicePath = NULL; + Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath); + if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) + { + /* Device failed to handle DP protocol */ + BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (status code: %lx)\n", Status); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + continue; + } + + /* Allocate memory for block device */ + Status = BlMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); + EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + return Status; + } + + /* Store new block device into a linked list */ + BlockDevice->BlockIo = Io; + BlockDevice->DevicePath = DevicePath; + RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry); + } + + /* Free handles buffer */ + BlMemoryFreePool(Handles); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Dissects a specified ARC name and provides detailed information about corresponding device and on disk path. + * + * @param SystemPath + * Supplies an input ARC path. + * + * @param Path + * Specifies a pointer to variable, where on disk path will be saved. + * + * @param DriveType + * Supplies a pointer to the variable that receives a drive type. + * + * @param DriveNumber + * Supplies a pointer to the variable that receives a drive number. + * + * @param PartNumber + * Supplies a pointer to the variable that receives a parition number if applicable, otherwise stores 0 (zero). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpDissectVolumeArcPath(IN PCHAR SystemPath, + OUT PCHAR *ArcName, + OUT PCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber) +{ + PCHAR ArcPath, LocalArcName; + ULONG ArcLength = 0; + + /* Set default values */ + *DriveType = XTBL_BOOT_DEVICE_UNKNOWN; + *DriveNumber = 0; + *PartNumber = 0; + + /* Look for the ARC path */ + if(RtlCompareStringInsensitive(SystemPath, "ramdisk(0)", 0) == 0) + { + /* This is RAM disk */ + ArcLength = 10; + *DriveType = XTBL_BOOT_DEVICE_RAMDISK; + } + else if(RtlCompareStringInsensitive(SystemPath, "multi(0)disk(0)", 0) == 0) + { + /* This is a multi-disk port */ + ArcLength = 15; + ArcPath = SystemPath + ArcLength; + + /* Check for disk type */ + if(RtlCompareStringInsensitive(ArcPath, "cdrom(", 0) == 0) + { + /* This is an optical drive */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_CDROM; + ArcLength++; + } + else if(RtlCompareStringInsensitive(ArcPath, "fdisk(", 0) == 0) + { + /* This is a floppy drive */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_FLOPPY; + ArcLength++; + } + else if(RtlCompareStringInsensitive(ArcPath, "rdisk(", 0) == 0) + { + /* This is a hard disk */ + ArcLength += 6; + + /* Find drive number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate drive number */ + *DriveNumber *= 10; + *DriveNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + + /* Set proper drive type */ + *DriveType = XTBL_BOOT_DEVICE_HARDDISK; + ArcLength++; + ArcPath = SystemPath + ArcLength; + + /* Look for a partition */ + if(RtlCompareStringInsensitive(ArcPath, "partition(", 0) == 0) + { + /* Partition information found */ + ArcLength += 10; + + /* Find partition number */ + while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') + { + if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') + { + /* Calculate partition number */ + *PartNumber *= 10; + *PartNumber += SystemPath[ArcLength] - '0'; + } + ArcLength++; + } + ArcLength++; + } + } + else + { + /* Unsupported disk type */ + return STATUS_EFI_UNSUPPORTED; + } + } + else + { + /* Unsupported ARC path */ + return STATUS_EFI_UNSUPPORTED; + } + + /* Store the path if possible */ + if(Path) + { + *Path = SystemPath + ArcLength; + } + + /* Store ARC name if possible */ + if(ArcName) + { + BlMemoryAllocatePool(ArcLength, (PVOID *)&LocalArcName); + RtlCopyMemory(LocalArcName, SystemPath, ArcLength); + LocalArcName[ArcLength] = '\0'; + *ArcName = LocalArcName; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine duplicates a device path object. + * + * @param DevicePath + * An input device path that is going to be clonned. + * + * @return Returns a duplicate of input device path. + * + * @since XT 1.0 + */ +XTCDECL +PEFI_DEVICE_PATH_PROTOCOL +BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) +{ + PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; + PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; + EFI_STATUS Status; + UINT Length = 0; + + DevicePathNode = DevicePath; + + /* Get the device path length */ + while(TRUE) + { + Length += *(PUINT16)DevicePath->Length; + if(DevicePathNode->Type == EFI_END_DEVICE_PATH) + { + break; + } + DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUINT16)DevicePath->Length); + } + + /* Check length */ + if(Length == 0) + { + /* Nothing to duplicate */ + return NULL; + } + + /* Allocate memory for the new device path */ + Status = BlMemoryAllocatePool(Length, (PVOID *)&DevicePathClone); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + BlDebugPrint(L"ERROR: Unable to allocate memory pool for device path duplicate\n"); + return NULL; + } + + /* Copy the device path */ + RtlCopyMemory(DevicePathClone, DevicePath, Length); + + /* Return the cloned object */ + return DevicePathClone; +} + +/** + * Attempts to find a last node of the EFI block device. + * + * @param DevicePath + * An input device path. + * + * @param LastNode + * A pointer to the buffer where last node will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) +{ + PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; + + /* Make sure end is not reached yet */ + if(DevicePath->Type == EFI_END_DEVICE_PATH) + { + /* End reached, nothing to do */ + LastNode = NULL; + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Fast forward to the last node */ + EndNode = DevicePath; + while(EndNode->Type != EFI_END_DEVICE_PATH) + { + NextNode = EndNode; + EndNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)EndNode + *(PUSHORT)EndNode->Length); + } + + /* Store last node found */ + *LastNode = NextNode; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine attempts to find a parent device of the provided block device. + * + * @param BlockDevice + * A linked list of discovered block devices. + * + * @param ChildNode + * Block device that is looking for a parent device. + * + * @param ParentNode + * A pointer to memory region where pointer to the parent node will be provided. + * + * @return This routine returns TRUE if parent node has been found, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode) +{ + PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; + PEFI_BLOCK_DEVICE_DATA BlockDeviceData; + UINT ChildLength, ParentLength; + PLIST_ENTRY ListEntry; + + ListEntry = BlockDevices->Flink; + while(ListEntry != BlockDevices) + { + /* Take block device from the list */ + BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); + + ChildDevicePath = ChildNode->DevicePath; + ParentDevicePath = BlockDeviceData->DevicePath; + + /* Iterate nodes */ + while(TRUE) + { + /* Check if the parent device is a match */ + if(ParentDevicePath->Type == EFI_END_DEVICE_PATH) + { + /* Parent device is a match */ + ParentNode = BlockDeviceData; + return TRUE; + } + + /* Get child and parent node lengths */ + ChildLength = *(PUINT16)ChildDevicePath->Length; + ParentLength = *(PUINT16)ParentDevicePath->Length; + + /* Check if lengths match */ + if(ChildLength != ParentLength) + { + /* Lengths do not match, this is not a valid parent */ + break; + } + + /* Move to the next child and parent nodes */ + ChildDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ChildDevicePath + ChildLength); + ParentDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ParentDevicePath + ParentLength); + } + + /* Get next entry from linked list */ + ListEntry = ListEntry->Flink; + } + + /* Apparently not found a parent node */ + return FALSE; +} -- 2.45.1 From 2c132d4ab5531232b3d08075da3c782778ae4a33 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:51:59 +0100 Subject: [PATCH 035/182] Compile volume.c --- xtldr2/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index cda9b16..266edd6 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -17,7 +17,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c - # ${XTLDR_SOURCE_DIR}/volume.c + ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library -- 2.45.1 From 31c8e502c58ca1576e9d7db972322ec387edf5b8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:53:37 +0100 Subject: [PATCH 036/182] Discover and enumerate EFI block devices --- xtldr2/xtldr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 513cca2..1a5dba4 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -68,6 +68,9 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol\n"); } + /* Discover and enumerate EFI block devices */ + BlEnumerateBlockDevices(); + /* Temporary infinite loop */ for(;;); -- 2.45.1 From a413ae852ede20b4f89df310d089dfc2c3102c03 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:54:28 +0100 Subject: [PATCH 037/182] Add missing block devices definitions --- sdk/xtdk/bltypes.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 60d52e5..78ea37f 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -17,6 +17,13 @@ #define XTBL_LOADER_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\" #define XTBL_THEMES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\THEMES\\" +/* EFI XT boot devices */ +#define XTBL_BOOT_DEVICE_UNKNOWN 0x00 +#define XTBL_BOOT_DEVICE_CDROM 0x01 +#define XTBL_BOOT_DEVICE_FLOPPY 0x02 +#define XTBL_BOOT_DEVICE_HARDDISK 0x03 +#define XTBL_BOOT_DEVICE_RAMDISK 0x04 + /* XTLDR Debug Port type definitions */ #define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SERIAL 2 -- 2.45.1 From 3025338e7117ef970a58f4a2c856717c15c11d95 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 15:56:39 +0100 Subject: [PATCH 038/182] Check block devices enumeration status --- xtldr2/xtldr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 1a5dba4..37edbe9 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -69,7 +69,12 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } /* Discover and enumerate EFI block devices */ - BlEnumerateBlockDevices(); + Status = BlEnumerateBlockDevices(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to enumerate block devices */ + BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); + } /* Temporary infinite loop */ for(;;); -- 2.45.1 From a261c688085cac5ce2b4a7e935148fbd89c9dcd6 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:04:09 +0100 Subject: [PATCH 039/182] Add basic volume support to XTLDR protocol --- sdk/xtdk/bltypes.h | 7 +++++++ xtldr2/protocol.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 78ea37f..8093122 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -31,6 +31,7 @@ /* 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 EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); @@ -39,6 +40,7 @@ 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_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); @@ -91,6 +93,11 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_EXIT_BOOT_SERVICES ExitBootServices; PBL_SLEEP_EXECUTION SleepExecution; } Util; + struct + { + PBL_CLOSE_VOLUME Close; + PBL_OPEN_VOLUME Open; + } Volume; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; #endif /* __XTDK_BMTYPES_H */ diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 34aa2bb..2a3d20c 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -102,6 +102,8 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Util.ExitBootServices = BlExitBootServices; LdrProtocol.Util.SleepExecution = BlSleepExecution; + LdrProtocol.Volume.Close = BlCloseVolume; + LdrProtocol.Volume.Open = BlOpenVolume; /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); -- 2.45.1 From 368035c1054d0412ac374fb129cdce9decbca3bd Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:15:17 +0100 Subject: [PATCH 040/182] Compare input parameters, while ignoring differences in case --- xtldr2/config.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index b3f845a..159f907 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -61,7 +61,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) while(Argument != NULL) { /* Check all provided parameters */ - if(RtlCompareWideString(Argument, L"DEFAULT=", 8) == 0) + if(RtlCompareWideStringInsensitive(Argument, L"DEFAULT=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; @@ -72,7 +72,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Default[Length] = '\0'; } - else if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; @@ -87,12 +87,12 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) BlpConfiguration.Debug[Length] = '\0'; } } - else if(RtlCompareWideString(Argument, L"SHELL", 5) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } - else if(RtlCompareWideString(Argument, L"TIMEOUT=", 8) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ Argument += 8; @@ -108,7 +108,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) Argument++; } } - else if(RtlCompareWideString(Argument, L"TUNE=", 5) == 0) + else if(RtlCompareWideStringInsensitive(Argument, L"TUNE=", 5) == 0) { /* Skip to the argument value */ Argument += 5; -- 2.45.1 From 3bd4332573a28cd23b7569b491e4089eddd0e1a0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:17:28 +0100 Subject: [PATCH 041/182] BUGFIX: Do not cut last character --- xtldr2/config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 159f907..45869f5 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -69,7 +69,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) /* Save default OS parameter in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Default); - RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Default[Length] = '\0'; } else if(RtlCompareWideStringInsensitive(Argument, L"DEBUG=", 6) == 0) @@ -83,7 +83,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) { /* Save debug port in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Debug); - RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Debug[Length] = '\0'; } } @@ -116,7 +116,7 @@ BlpUpdateGlobalConfiguration(IN PWCHAR Options) /* Save theme in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Tune); - RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); + RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR))); BlpConfiguration.Tune[Length] = '\0'; } -- 2.45.1 From 089c2213a450567d9cf84885082611cfa0f4b152 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 7 Dec 2023 16:20:40 +0100 Subject: [PATCH 042/182] Compare input parameters, while ignoring differences in case --- xtldr2/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtldr2/debug.c b/xtldr2/debug.c index 87b4a08..668766a 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -84,7 +84,7 @@ BlpInitializeDebugConsole() while(DebugPort != NULL) { /* Check what port is set for debugging */ - if(RtlCompareWideString(DebugPort, L"COM", 3) == 0) + if(RtlCompareWideStringInsensitive(DebugPort, L"COM", 3) == 0) { /* Read COM port number */ DebugPort += 3; @@ -97,7 +97,7 @@ BlpInitializeDebugConsole() } /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlCompareWideString(DebugPort, L":0x", 3) == 0) + if(PortNumber == 0 && RtlCompareWideStringInsensitive(DebugPort, L":0x", 3) == 0) { /* COM port address provided */ DebugPort += 3; @@ -140,7 +140,7 @@ BlpInitializeDebugConsole() /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; } - else if(RtlCompareWideString(DebugPort, L"SCREEN", 5) == 0) + else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN; -- 2.45.1 From 212091811fabf0ae18c22c29f491da537af713ba Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 8 Dec 2023 15:57:44 +0100 Subject: [PATCH 043/182] Implement BlReadFile() routine --- xtldr2/includes/bootman.h | 7 +++ xtldr2/protocol.c | 5 +- xtldr2/volume.c | 119 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 2a1647a..cedf062 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -57,6 +57,13 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); +XTCDECL +EFI_STATUS +BlReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN CONST PWCHAR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize); + XTCDECL VOID BlConsoleClearScreen(); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 2a3d20c..53feebe 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -95,6 +95,9 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Console.EnableCursor = BlConsoleEnableCursor; LdrProtocol.Console.Print = BlConsolePrint; LdrProtocol.Debug.Print = BlDebugPrint; + LdrProtocol.Disk.CloseVolume = BlCloseVolume; + LdrProtocol.Disk.OpenVolume = BlOpenVolume; + LdrProtocol.Disk.ReadFile = BlReadFile; LdrProtocol.Memory.AllocatePages = BlMemoryAllocatePages; LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; LdrProtocol.Memory.FreePages = BlMemoryFreePages; @@ -102,8 +105,6 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Util.ExitBootServices = BlExitBootServices; LdrProtocol.Util.SleepExecution = BlSleepExecution; - LdrProtocol.Volume.Close = BlCloseVolume; - LdrProtocol.Volume.Open = BlOpenVolume; /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); diff --git a/xtldr2/volume.c b/xtldr2/volume.c index 8176190..8b11882 100644 --- a/xtldr2/volume.c +++ b/xtldr2/volume.c @@ -470,6 +470,125 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, return STATUS_EFI_SUCCESS; } +/** + * Reads data from the file. + * + * @param DirHandle + * Supplies a handle of the opened filesystem directory. + * + * @param FileName + * Supplies the name of the file to read. + * + * @param FileData + * Provides a buffer to store the data read from the file. + * + * @param FileSize + * Provides a pointer to the variable to store a size of the buffer. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN CONST PWCHAR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize) +{ + EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; + EFI_PHYSICAL_ADDRESS Address; + PEFI_FILE_HANDLE FileHandle; + PEFI_FILE_INFO FileInfo; + EFI_STATUS Status; + UINT_PTR ReadSize; + SIZE_T Pages; + + Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ, + EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open file */ + return Status; + } + + /* Set required size for getting file information */ + ReadSize = sizeof(EFI_FILE_INFO) + 32; + + /* Allocate necessary amount of memory */ + Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + FileHandle->Close(FileHandle); + return Status; + } + + /* First attempt to get file information */ + FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + if(Status == STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Buffer is too small, but EFI tells the required size, so reallocate */ + BlMemoryFreePool(&FileInfo); + Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + FileHandle->Close(FileHandle); + return Status; + } + + /* Second attempt to get file information */ + Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + } + + /* Check if file information got successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get file information */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + return Status; + } + + /* Store file size and calculate number of pages */ + *FileSize = FileInfo->FileSize; + Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); + + /* Allocate pages */ + Status = BlMemoryAllocatePages(Pages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Pages allocation failure */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + return Status; + } + + /* Calculate number of bytes to read and zero memory*/ + ReadSize = Pages * EFI_PAGE_SIZE; + *FileData = (PCHAR)(UINT_PTR)Address; + RtlZeroMemory(*FileData, ReadSize); + + /* Read data from the file */ + Status = FileHandle->Read(FileHandle, &ReadSize, *FileData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read data */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + BlMemoryFreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); + return Status; + } + + /* Close handle and free memory */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Gets a list of block devices from an EFI enabled BIOS. * -- 2.45.1 From e1be0e56ea47b56379b2cc208e77b230eacab29e Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 8 Dec 2023 15:59:25 +0100 Subject: [PATCH 044/182] Fix build --- sdk/xtdk/bltypes.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 8093122..9a4d9a0 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -42,6 +42,7 @@ typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Mem typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); /* XTLDR Configuration data */ @@ -78,6 +79,12 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_DEBUG_PRINT Print; } Debug; struct + { + PBL_CLOSE_VOLUME CloseVolume; + PBL_OPEN_VOLUME OpenVolume; + PBL_READ_FILE ReadFile; + } Disk; + struct { PBL_ALLOCATE_PAGES AllocatePages; PBL_ALLOCATE_POOL AllocatePool; @@ -93,11 +100,6 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_EXIT_BOOT_SERVICES ExitBootServices; PBL_SLEEP_EXECUTION SleepExecution; } Util; - struct - { - PBL_CLOSE_VOLUME Close; - PBL_OPEN_VOLUME Open; - } Volume; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; #endif /* __XTDK_BMTYPES_H */ -- 2.45.1 From 40e7b29af85af541967a18a24421e6d3b7a6ee04 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 8 Dec 2023 19:29:10 +0100 Subject: [PATCH 045/182] Implement BlpLoadConfigurationFile() routine --- xtldr2/config.c | 57 +++++++++++++++++++++++++++++++++++++++ xtldr2/includes/bootman.h | 6 +++++ 2 files changed, 63 insertions(+) diff --git a/xtldr2/config.c b/xtldr2/config.c index 45869f5..0ff3e73 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -9,6 +9,63 @@ #include +/** + * Loads configuration file from the specified directory on the FS0:/ drive. + * + * @param ConfigDirectory + * Specifies a path to the directory containing the configuration file. + * + * @param ConfigFile + * Specifies the name of the configuration file. + * + * @param ConfigData + * Provides a buffer to store the data read from the configuration file. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData) +{ + PEFI_FILE_HANDLE DirHandle, FsHandle; + EFI_HANDLE DiskHandle; + EFI_STATUS Status; + SIZE_T FileSize; + + /* Open EFI volume */ + Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + return Status; + } + + /* Open specified directory, containing the configuration file and close the FS immediately */ + Status = FsHandle->Open(FsHandle, &DirHandle, ConfigDirectory, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if directory opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + BlCloseVolume(DiskHandle); + return Status; + } + + /* Read configuration file */ + Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); + + /* Close EFI volume */ + BlCloseVolume(DiskHandle); + + /* Return read status */ + return STATUS_EFI_SUCCESS; +} + /** * Parses command line arguments and updates global configuration. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index cedf062..07aa835 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -141,6 +141,12 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, IN PEFI_BLOCK_DEVICE_DATA ChildNode, OUT PEFI_BLOCK_DEVICE_DATA ParentNode); +XTCDECL +EFI_STATUS +BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData); + XTCDECL VOID BlpParseCommandLineOptions(VOID); -- 2.45.1 From 87dceb0ba79b82d109ea8465acb534f7e32757b7 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 8 Dec 2023 22:24:33 +0100 Subject: [PATCH 046/182] Reorganise bootman.h --- xtldr2/includes/bootman.h | 96 +++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 07aa835..c01b55c 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -20,6 +20,28 @@ XTCDECL EFI_STATUS BlCloseVolume(IN PEFI_HANDLE VolumeHandle); +XTCDECL +VOID +BlConsoleClearScreen(); + +XTCDECL +VOID +BlConsoleDisableCursor(); + +XTCDECL +VOID +BlConsoleEnableCursor(); + +XTCDECL +VOID +BlConsolePrint(IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BlDebugPrint(IN PUINT16 Format, + IN ...); + XTCDECL EFI_STATUS BlEnumerateBlockDevices(); @@ -64,28 +86,6 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, OUT PVOID *FileData, OUT PSIZE_T FileSize); -XTCDECL -VOID -BlConsoleClearScreen(); - -XTCDECL -VOID -BlConsoleDisableCursor(); - -XTCDECL -VOID -BlConsoleEnableCursor(); - -XTCDECL -VOID -BlConsolePrint(IN PUINT16 Format, - IN ...); - -XTCDECL -VOID -BlDebugPrint(IN PUINT16 Format, - IN ...); - XTCDECL EFI_STATUS BlMemoryFreePages(IN UINT64 Pages, @@ -113,6 +113,18 @@ XTCDECL EFI_STATUS BlpActivateSerialIOController(); +XTCDECL +VOID +BlpConsoleInitialize(); + +XTCDECL +VOID +BlpConsolePrintChar(IN USHORT Character); + +XTCDECL +VOID +BlpDebugPutChar(IN USHORT Character); + XTCDECL EFI_STATUS BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); @@ -141,32 +153,6 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, IN PEFI_BLOCK_DEVICE_DATA ChildNode, OUT PEFI_BLOCK_DEVICE_DATA ParentNode); -XTCDECL -EFI_STATUS -BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); - -XTCDECL -VOID -BlpParseCommandLineOptions(VOID); - -XTCDECL -VOID -BlpUpdateGlobalConfiguration(IN PWCHAR Options); - -XTCDECL -VOID -BlpConsoleInitialize(); - -XTCDECL -VOID -BlpConsolePrintChar(IN USHORT Character); - -XTCDECL -VOID -BlpDebugPutChar(IN USHORT Character); - XTCDECL EFI_STATUS BlpInitializeDebugConsole(); @@ -181,6 +167,16 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG PortAddress, IN ULONG BaudRate); +XTCDECL +EFI_STATUS +BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData); + +XTCDECL +VOID +BlpParseCommandLineOptions(VOID); + XTCDECL EFI_STATUS BlpRegisterXtLoaderProtocol(); @@ -227,4 +223,8 @@ XTCDECL UINT64 BlpStringReadPadding(IN PUINT16 *Format); +XTCDECL +VOID +BlpUpdateGlobalConfiguration(IN PWCHAR Options); + #endif /* __XTLDR_BOOTMAN_H */ -- 2.45.1 From b57ee630fd8ee9e1c2660fef90c0f5bd0edfff65 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 9 Dec 2023 20:17:08 +0100 Subject: [PATCH 047/182] Implement RtlTrimLeftString(), RtlTrimRightString() and RtlTrimString() routines --- sdk/xtdk/rtlfuncs.h | 12 +++++++ xtoskrnl/rtl/string.c | 80 ++++++++++++++++++++++++++++++++++++++++++ xtoskrnl/xtoskrnl.spec | 3 ++ 3 files changed, 95 insertions(+) diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index 4f275ad..e435a7b 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -131,6 +131,18 @@ RtlTokenizeWideString(IN PWCHAR String, IN CONST PWCHAR Delimiter, IN OUT PWCHAR *SavePtr); +XTCDECL +PCHAR +RtlTrimLeftString(IN CONST PCHAR String); + +XTCDECL +PCHAR +RtlTrimRightString(IN CONST PCHAR String); + +XTCDECL +PCHAR +RtlTrimString(IN CONST PCHAR String); + XTCDECL SIZE_T RtlWideStringLength(IN CONST PWCHAR String, diff --git a/xtoskrnl/rtl/string.c b/xtoskrnl/rtl/string.c index 3716d6b..c277e44 100644 --- a/xtoskrnl/rtl/string.c +++ b/xtoskrnl/rtl/string.c @@ -218,3 +218,83 @@ RtlStringToWideString(OUT PWCHAR Destination, return Length - Count; } + +/** + * Removes certain characters from a beginning of the string. + * + * @param String + * Pointer to the null-terminated string to be trimmed. + * + * @return This routine returns a pointer to the left-trimmed string. + * + * @since XT 1.0 + */ +XTCDECL +PCHAR +RtlTrimLeftString(IN CONST PCHAR String) +{ + PCHAR Start; + + /* Initialize pointer */ + Start = String; + + /* Skip all leading whitespaces */ + while(*Start == ' ' || *Start == '\n' || *Start == '\t' || *Start == '\r' || *Start == '\v' || *Start == '\f') + { + /* Advance to the next character */ + Start++; + } + + /* Return left-trimmed string */ + return Start; +} + +/** + * Removes certain characters from the end of the string. + * + * @param String + * Pointer to the null-terminated string to be trimmed. + * + * @return This routine returns a pointer to the right-trimmed string. + * + * @since XT 1.0 + */ +XTCDECL +PCHAR +RtlTrimRightString(IN CONST PCHAR String) +{ + PCHAR End; + + /* Find end of the string */ + End = String + RtlStringLength(String, 0); + + /* Skip all trailing whitespaces */ + while((End != String) && (*End == ' ' || *End == '\n' || *End == '\t' || *End == '\r' || *End == '\v' || *End == '\f')) + { + /* Move to the previous character */ + End--; + } + + /* Terminate the string */ + *End = 0; + + /* Return right-trimmed string */ + return String; +} + +/** + * Removes certain characters from the beginning and the end of the string. + * + * @param String + * Pointer to the null-terminated string to be trimmed. + * + * @return This routine returns a pointer to the trimmed string. + * + * @since XT 1.0 + */ +XTCDECL +PCHAR +RtlTrimString(IN CONST PCHAR String) +{ + return RtlTrimLeftString(RtlTrimRightString(String)); +} diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index 0864d76..cb5869c 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -40,6 +40,9 @@ @ cdecl RtlCompareWideStringInsensitive(wstr wstr long) @ cdecl RtlConcatenateWideString(wstr wstr long) @ cdecl RtlTokenizeWideString(wstr wstr wstr) +@ cdecl RtlTrimLeftString(str) +@ cdecl RtlTrimRightString(str) +@ cdecl RtlTrimString(str) @ cdecl RtlWideStringLength(wstr long) @ stdcall RtlWriteRegisterByte(ptr long) @ stdcall RtlWriteRegisterLong(ptr long) -- 2.45.1 From a06f32c61d872b2e1f8ba5ec32c3bf017887e615 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 9 Dec 2023 23:45:41 +0100 Subject: [PATCH 048/182] Initial code for reading configuration from a file --- sdk/xtdk/bltypes.h | 18 ++- xtldr2/config.c | 260 +++++++++++++++++++++++++++++++++----- xtldr2/includes/bootman.h | 17 ++- 3 files changed, 258 insertions(+), 37 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 9a4d9a0..ae291a9 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -45,7 +45,7 @@ typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_G typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); -/* XTLDR Configuration data */ +/* XTLDR Configuration */ typedef struct _XTBL_CONFIGURATION { PWCHAR Default; @@ -56,6 +56,22 @@ typedef struct _XTBL_CONFIGURATION PWCHAR Tune; } XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; +/* XTLDR Configuration data */ +typedef struct _XTBL_INI_OPTION +{ + LIST_ENTRY Flink; + PWCHAR Name; + PWCHAR Value; +} XTBL_INI_OPTION, *PXTBL_INI_OPTION; + +/* XTLDR Configuration section */ +typedef struct _XTBL_INI_SECTION +{ + LIST_ENTRY Flink; + LIST_ENTRY Options; + PWCHAR SectionName; +} XTBL_INI_SECTION, *PXTBL_INI_SECTION; + /* XTLDR Status data */ typedef struct _XTBL_STATUS { diff --git a/xtldr2/config.c b/xtldr2/config.c index 0ff3e73..7bdf1c8 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -9,6 +9,234 @@ #include +XTCDECL +EFI_STATUS +BlpLoadConfiguration() +{ + EFI_STATUS Status; + PLIST_ENTRY Configuration; + PCHAR ConfigData; + + /* Initialize configuration pointer */ + Configuration = NULL; + + /* Read data from configuration file */ + Status = BlpReadConfigurationFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load configuration */ + BlDebugPrint(L"Failed to load configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n"); + return Status; + } + + /* Parse configuration data */ + Status = BlpParseConfigurationFile(ConfigData, Configuration); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to parse configuration */ + BlDebugPrint(L"Failed to parse configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n"); + return Status; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Parses command line arguments and updates global configuration. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpParseCommandLine(VOID) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + EFI_STATUS Status; + + /* Handle loaded image protocol */ + Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); + if(Status == STATUS_EFI_SUCCESS) + { + /* Check if launched from UEFI shell */ + if(LoadedImage && LoadedImage->LoadOptions) + { + /* Update global boot loader configuration */ + BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions); + } + } +} + +XTCDECL +EFI_STATUS +BlpParseConfigurationFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration) +{ + SIZE_T SectionLength, KeyLength, ValueLength; + PCHAR InputData, Key, SectionName, Value; + PXTBL_INI_SECTION Section; + PXTBL_INI_OPTION Option; + EFI_STATUS Status; + + /* Initialize pointers */ + InputData = RawConfig; + Section = NULL; + Option = NULL; + SectionName = NULL; + Key = NULL; + Value = NULL; + + /* Analyze configuration data until end of file is reached */ + while(*InputData != 0) + { + if(*InputData == ';' || *InputData == '#') + { + /* Skip comment until end of the line */ + while(*InputData != 0 && *InputData != '\n') + { + /* Advance to the next character */ + InputData++; + } + } + else if(*InputData == ' ' || *InputData == '\t' || *InputData == '\r' || *InputData == '\n') + { + /* Skip whitespaces */ + InputData++; + } + else if(*InputData == '[') + { + /* Skip leading bracket */ + InputData++; + + /* Store section name */ + SectionName = InputData; + + /* Find end of the section name */ + while(*InputData != ']' && *InputData != 0 && *InputData != '\n') + { + /* Advance to the next character */ + InputData++; + } + + /* Check if end of the section name is reached */ + if(*InputData != ']') + { + /* Section name does not end */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Mark end of the section name and advance to the next character */ + *InputData = 0; + InputData++; + + /* Remove leading and trailing spaces from section name */ + SectionName = RtlTrimString(SectionName); + + /* Find length of the section name */ + SectionLength = RtlStringLength(SectionName, 0); + + /* Allocate memory for new section */ + Status = BlMemoryAllocatePool(sizeof(XTBL_INI_SECTION), (PVOID*)&Section); + if(Status == STATUS_EFI_SUCCESS) + { + /* Allocate more memory for section name */ + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); + } + if(Status != STATUS_EFI_SUCCESS) + { + /* Some memory allocation failed */ + return Status; + } + + /* Initialize new section and add it to the list */ + RtlInitializeListHead(&Section->Options); + RtlStringToWideString(Section->SectionName, &SectionName, SectionLength + 1); + RtlInsertTailList(Configuration, &Section->Flink); + } + else + { + /* Store key */ + Key = InputData; + + /* Find end of the key */ + while(*InputData != '=' && *InputData != 0 && *InputData != '\n') + { + /* Advance to the next character */ + InputData++; + } + + /* Check if end of the key is reached */ + if(*InputData != '=') + { + /* Key name does not end */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Mark end of the key and advance to the next character */ + *InputData = 0; + InputData++; + + /* Skip all leading spaces in the value */ + while(*InputData == ' ') + { + /* Advance to the next character */ + InputData++; + } + + /* Store value */ + Value = InputData; + + /* Find end of the value */ + while(*InputData != 0 && *InputData != '\n') + { + /* Advance to the next character */ + InputData++; + } + + /* Mark end of the value and advance to the next character */ + *InputData = 0; + InputData++; + + /* Remove leading and trailing spaces from key and value */ + Key = RtlTrimString(Key); + Value = RtlTrimString(Value); + + /* Find length of the key and its value */ + KeyLength = RtlStringLength(Key, 0); + ValueLength = RtlStringLength(Value, 0); + + /* Allocate memory for new option */ + Status = BlMemoryAllocatePool(sizeof(XTBL_INI_OPTION), (PVOID*)&Option); + if(Status == STATUS_EFI_SUCCESS) + { + /* Allocate more memory for option name */ + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + if(Status == STATUS_EFI_SUCCESS) + { + /* Allocate even more memory for option value */ + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + } + } + if(Status != STATUS_EFI_SUCCESS) + { + /* Some memory allocation failed */ + return Status; + } + + /* Initialize new option and add it to the list */ + RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1); + RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1); + RtlInsertTailList(&Section->Options, &Option->Flink); + } + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Loads configuration file from the specified directory on the FS0:/ drive. * @@ -27,7 +255,7 @@ */ XTCDECL EFI_STATUS -BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, +BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, IN CONST PWCHAR ConfigFile, OUT PCHAR *ConfigData) { @@ -63,35 +291,7 @@ BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, BlCloseVolume(DiskHandle); /* Return read status */ - return STATUS_EFI_SUCCESS; -} - -/** - * Parses command line arguments and updates global configuration. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpParseCommandLineOptions(VOID) -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - EFI_STATUS Status; - - /* Handle loaded image protocol */ - Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); - if(Status == STATUS_EFI_SUCCESS) - { - /* Check if launched from UEFI shell */ - if(LoadedImage && LoadedImage->LoadOptions) - { - /* Update global boot loader configuration */ - BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions); - } - } + return Status; } /** diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index c01b55c..d8ae19b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -168,14 +168,19 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG BaudRate); XTCDECL -EFI_STATUS -BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); +VOID +BlpParseCommandLine(VOID); XTCDECL -VOID -BlpParseCommandLineOptions(VOID); +EFI_STATUS +BlpParseConfigurationFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration); + +XTCDECL +EFI_STATUS +BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData); XTCDECL EFI_STATUS -- 2.45.1 From 6ffedf6302fd0e35fe684be6f97dfbfdbfb5e323 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 9 Dec 2023 23:48:09 +0100 Subject: [PATCH 049/182] Fix build --- xtldr2/xtldr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 37edbe9..84c33da 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -38,7 +38,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse configuration options passed from UEFI shell */ - BlpParseCommandLineOptions(); + BlpParseCommandLine(); /* Attempt to early initialize debug console */ if(DEBUG) -- 2.45.1 From 0cea10ad42f962cc49502cc8e67c088f00f193f5 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 16:31:15 +0100 Subject: [PATCH 050/182] Store all configuration in a linked list, read config from INI file and EFI shell --- sdk/xtdk/bltypes.h | 19 +-- xtldr2/config.c | 344 ++++++++++++++++++++++++++++---------- xtldr2/console.c | 2 +- xtldr2/debug.c | 23 +-- xtldr2/efiutils.c | 2 +- xtldr2/globals.c | 10 +- xtldr2/includes/bootman.h | 29 +++- xtldr2/includes/globals.h | 10 +- xtldr2/xtldr.c | 29 +++- 9 files changed, 344 insertions(+), 124 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index ae291a9..67ba8e0 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -45,32 +45,21 @@ typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_G typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); -/* XTLDR Configuration */ -typedef struct _XTBL_CONFIGURATION -{ - PWCHAR Default; - PWCHAR Debug; - ULONG DebugPort; - BOOLEAN Shell; - ULONG Timeout; - PWCHAR Tune; -} XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; - /* XTLDR Configuration data */ -typedef struct _XTBL_INI_OPTION +typedef struct _XTBL_CONFIG_ENTRY { LIST_ENTRY Flink; PWCHAR Name; PWCHAR Value; -} XTBL_INI_OPTION, *PXTBL_INI_OPTION; +} XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; /* XTLDR Configuration section */ -typedef struct _XTBL_INI_SECTION +typedef struct _XTBL_CONFIG_SECTION { LIST_ENTRY Flink; LIST_ENTRY Options; PWCHAR SectionName; -} XTBL_INI_SECTION, *PXTBL_INI_SECTION; +} XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; /* XTLDR Status data */ typedef struct _XTBL_STATUS diff --git a/xtldr2/config.c b/xtldr2/config.c index 7bdf1c8..9925bcd 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -9,19 +9,120 @@ #include +/** + * Returns a value of the specified configuration key. + * + * @param ConfigName + * Specifies the configuration key to return its value. + * + * @return This routine returns a pointer to the configuration value, or NULL if key was not found. + * + * @since XT 1.0 + */ +XTCDECL +PWCHAR +BlGetConfigValue(IN CONST PWCHAR ConfigName) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigListEntry; + SIZE_T Length; + + /* Get config entry name length */ + Length = RtlWideStringLength(ConfigName, 0); + + /* Iterate through config entries */ + ConfigListEntry = BlpConfig->Flink; + while(ConfigListEntry != BlpConfig) + { + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Check if requested configuration found */ + if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + { + /* Return config value */ + return ConfigEntry->Value; + } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; + } + + /* Config entry not found, return NULL */ + return NULL; +} + +/** + * Updates existing configuration value. + * + * @param ConfigName + * Specifies the configuration key to update. + * + * @param ConfigValue + * Specifies the new configuration value. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlSetConfigValue(IN CONST PWCHAR ConfigName, + IN CONST PWCHAR ConfigValue) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigListEntry; + SIZE_T Length; + + /* Get config entry name length */ + Length = RtlWideStringLength(ConfigName, 0); + + /* Iterate through config entries */ + ConfigListEntry = BlpConfig->Flink; + while(ConfigListEntry != BlpConfig) + { + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Check if requested configuration found */ + if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + { + /* Update config value */ + ConfigEntry->Value = ConfigValue; + + /* Return success */ + return STATUS_EFI_SUCCESS; + } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; + } + + /* Config entry not found */ + return STATUS_EFI_NOT_FOUND; +} + +/** + * Loads and parses XTLDR configuration file. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ XTCDECL EFI_STATUS BlpLoadConfiguration() { + PLIST_ENTRY SectionListEntry; + STATIC LIST_ENTRY Configuration; EFI_STATUS Status; - PLIST_ENTRY Configuration; PCHAR ConfigData; /* Initialize configuration pointer */ - Configuration = NULL; + RtlInitializeListHead(&Configuration); /* Read data from configuration file */ - Status = BlpReadConfigurationFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); + Status = BlpReadConfigFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ @@ -30,7 +131,7 @@ BlpLoadConfiguration() } /* Parse configuration data */ - Status = BlpParseConfigurationFile(ConfigData, Configuration); + Status = BlpParseConfigFile(ConfigData, &Configuration); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ @@ -38,6 +139,31 @@ BlpLoadConfiguration() return Status; } + /* Iterate through config sections */ + SectionListEntry = Configuration.Flink; + while(SectionListEntry != &Configuration) + { + /* Get config section */ + PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink); + + /* Look for global XTLDR configuration section */ + if(RtlCompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0) + { + /* Update global configuration */ + BlpUpdateConfiguration(&Section->Options); + + /* Remove XTLDR section from the list */ + RtlRemoveEntryList(SectionListEntry); + break; + } + + /* Move to the next section */ + SectionListEntry = SectionListEntry->Flink; + } + + /* Update boot menu OS list */ + BlpMenuList = &Configuration; + /* Return success */ return STATUS_EFI_SUCCESS; } @@ -50,12 +176,19 @@ BlpLoadConfiguration() * @since XT 1.0 */ XTCDECL -VOID +EFI_STATUS BlpParseCommandLine(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + PWCHAR Argument, Key, LastArg, Value; + PXTBL_CONFIG_ENTRY Option; EFI_STATUS Status; + SIZE_T KeyLength, ValueLength; + LIST_ENTRY Config; + + /* Initialize configuration list */ + RtlInitializeListHead(&Config); /* Handle loaded image protocol */ Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); @@ -64,21 +197,113 @@ BlpParseCommandLine(VOID) /* Check if launched from UEFI shell */ if(LoadedImage && LoadedImage->LoadOptions) { - /* Update global boot loader configuration */ - BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions); + /* Tokenize provided options */ + Argument = RtlTokenizeWideString(LoadedImage->LoadOptions, L" ", &LastArg); + + /* Iterate over all arguments passed to boot loader */ + while(Argument != NULL) + { + /* Store key name */ + Key = Argument; + + /* Find end of the key */ + while(*Argument != '=' && *Argument != 0 && *Argument != '\n') + { + /* Advance to the next character */ + Argument++; + } + + /* Mark end of the key and advance to the next character */ + *Argument = 0; + Argument++; + + /* Store value */ + Value = Argument; + + /* Find end of the value */ + while(*Argument != 0 && *Argument != '\n') + { + /* Advance to the next character */ + Argument++; + } + + /* Mark end of the value and advance to the next character */ + *Argument = 0; + Argument++; + + /* Get length of the key and its value */ + KeyLength = RtlWideStringLength(Key, 0); + ValueLength = RtlWideStringLength(Value, 0); + + /* Check if argument is valid */ + if(KeyLength == 0 || ValueLength == 0) + { + /* Invalid argument, skip to the next one */ + continue; + } + + /* Allocate memory for new option */ + Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); + if(Status == STATUS_EFI_SUCCESS) + { + /* Allocate more memory for option name */ + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + if(Status == STATUS_EFI_SUCCESS) + { + /* Allocate even more memory for option value */ + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + } + } + if(Status != STATUS_EFI_SUCCESS) + { + /* Some memory allocation failed */ + return Status; + } + + /* Set entry name and value */ + RtlCopyMemory(Option->Name, Key, (KeyLength * sizeof(WCHAR))); + RtlCopyMemory(Option->Value, Value, (ValueLength * sizeof(WCHAR))); + Option->Name[KeyLength] = 0; + Option->Value[ValueLength] = 0; + + /* Add entry to the list */ + RtlInsertTailList(&Config, &Option->Flink); + + /* Take next argument */ + Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); + } + + /* Update global configuration */ + BlpUpdateConfiguration(&Config); } } + + /* Return success */ + return STATUS_EFI_SUCCESS; } +/** + * Parses configuration INI file. + * + * @param RawConfig + * Suplies a pointer to configuration INI file to be parsed. + * + * @param Configuration + * Supplies a pointer to memory region where parsed configuration will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ XTCDECL EFI_STATUS -BlpParseConfigurationFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration) +BlpParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration) { SIZE_T SectionLength, KeyLength, ValueLength; PCHAR InputData, Key, SectionName, Value; - PXTBL_INI_SECTION Section; - PXTBL_INI_OPTION Option; + PXTBL_CONFIG_SECTION Section; + PXTBL_CONFIG_ENTRY Option; EFI_STATUS Status; /* Initialize pointers */ @@ -139,7 +364,7 @@ BlpParseConfigurationFile(IN CONST PCHAR RawConfig, SectionLength = RtlStringLength(SectionName, 0); /* Allocate memory for new section */ - Status = BlMemoryAllocatePool(sizeof(XTBL_INI_SECTION), (PVOID*)&Section); + Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for section name */ @@ -209,7 +434,7 @@ BlpParseConfigurationFile(IN CONST PCHAR RawConfig, ValueLength = RtlStringLength(Value, 0); /* Allocate memory for new option */ - Status = BlMemoryAllocatePool(sizeof(XTBL_INI_OPTION), (PVOID*)&Option); + Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for option name */ @@ -255,9 +480,9 @@ BlpParseConfigurationFile(IN CONST PCHAR RawConfig, */ XTCDECL EFI_STATUS -BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData) +BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData) { PEFI_FILE_HANDLE DirHandle, FsHandle; EFI_HANDLE DiskHandle; @@ -295,10 +520,10 @@ BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, } /** - * Updates XTLDR configuration based on provided options. + * Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten. * - * @param Options - * Supplies a formatted list of options to be processed and stored in global configuration. + * @param NewConfig + * Supplies a pointer to a linked list containing new configuration entries. * * @return This routine does not return any value. * @@ -306,78 +531,29 @@ BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, */ XTCDECL VOID -BlpUpdateGlobalConfiguration(IN PWCHAR Options) +BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) { - PWCHAR Argument, LastArg; - SIZE_T Length; + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigListEntry, NextListEntry; - /* Tokenize provided options */ - Argument = RtlTokenizeWideString(Options, L" ", &LastArg); - - /* Iterate over all arguments passed to boot loader */ - while(Argument != NULL) + /* Iterate through new config entries */ + ConfigListEntry = NewConfig->Flink; + while(ConfigListEntry != NewConfig) { - /* Check all provided parameters */ - if(RtlCompareWideStringInsensitive(Argument, L"DEFAULT=", 8) == 0) - { - /* Skip to the argument value and calculate argument length */ - Argument += 8; - Length = RtlWideStringLength(Argument, 0); + /* Get new config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - /* Save default OS parameter in global configuration */ - BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Default); - RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR))); - BlpConfiguration.Default[Length] = '\0'; - } - else if(RtlCompareWideStringInsensitive(Argument, L"DEBUG=", 6) == 0) - { - /* Skip to the argument value */ - Argument += 6; - Length = RtlWideStringLength(Argument, 0); + /* Get next config entry */ + NextListEntry = ConfigListEntry->Flink; - /* 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))); - BlpConfiguration.Debug[Length] = '\0'; - } - } - else if(RtlCompareWideStringInsensitive(Argument, L"SHELL", 5) == 0) + /* Make sure config entry does not exist yet */ + if(BlGetConfigValue(ConfigEntry->Name) == NULL) { - /* Force shell mode */ - BlpConfiguration.Shell = TRUE; - } - else if(RtlCompareWideStringInsensitive(Argument, L"TIMEOUT=", 8) == 0) - { - /* Skip to the argument value */ - Argument += 8; - - /* Zero the timeout */ - BlpConfiguration.Timeout = 0; - - /* Read the timeout value and store it in global configuration */ - while(*Argument >= '0' && *Argument <= '9') - { - BlpConfiguration.Timeout *= 10; - BlpConfiguration.Timeout += *Argument - '0'; - Argument++; - } - } - else if(RtlCompareWideStringInsensitive(Argument, L"TUNE=", 5) == 0) - { - /* Skip to the argument value */ - Argument += 5; - Length = RtlWideStringLength(Argument, 0); - - /* Save theme in global configuration */ - BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Tune); - RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR))); - BlpConfiguration.Tune[Length] = '\0'; + /* Remove new config entry from input list and put it into global config list */ + RtlInsertTailList(BlpConfig, &ConfigEntry->Flink); } - /* Take next argument */ - Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); + /* Move to the next new config entry */ + ConfigListEntry = NextListEntry; } } diff --git a/xtldr2/console.c b/xtldr2/console.c index 08f2341..d8a7b8e 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -102,7 +102,7 @@ BlConsolePrint(IN PUINT16 Format, */ XTCDECL VOID -BlpConsoleInitialize() +BlpInitializeConsole() { /* Clear console buffers */ EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); diff --git a/xtldr2/debug.c b/xtldr2/debug.c index 668766a..b431723 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -36,14 +36,14 @@ BlDebugPrint(IN PUINT16 Format, VA_START(Arguments, Format); /* Check if serial debug port is enabled */ - if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpSerialPort.Flags & COMPORT_FLAG_INIT)) + if((BlpDebugPort & 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)) + if((BlpDebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) { /* Format and print the string to the screen */ BlpStringPrint(BlpConsolePrintChar, Format, Arguments); @@ -66,7 +66,7 @@ EFI_STATUS BlpInitializeDebugConsole() { ULONG PortAddress, PortNumber, BaudRate; - PWCHAR DebugPort, LastPort; + PWCHAR DebugConfiguration, DebugPort, LastPort; EFI_STATUS Status; /* Set default serial port options */ @@ -74,11 +74,14 @@ BlpInitializeDebugConsole() PortNumber = 0; BaudRate = 0; - /* Make sure any debug options are provided */ - if(BlpConfiguration.Debug) + /* Get debug configuration */ + DebugConfiguration = BlGetConfigValue(L"DEBUG"); + + /* Make sure any debug options are provided and debug console is not initialized yet */ + if(DebugConfiguration && BlpDebugPort == 0) { /* Find all debug ports */ - DebugPort = RtlTokenizeWideString(BlpConfiguration.Debug, L";", &LastPort); + DebugPort = RtlTokenizeWideString(DebugConfiguration, L";", &LastPort); /* Iterate over all debug ports */ while(DebugPort != NULL) @@ -138,12 +141,12 @@ BlpInitializeDebugConsole() } /* Enable debug port */ - BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL; + BlpDebugPort |= XTBL_DEBUGPORT_SERIAL; } else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ - BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN; + BlpDebugPort |= XTBL_DEBUGPORT_SCREEN; } else { @@ -158,14 +161,14 @@ BlpInitializeDebugConsole() } /* Check if serial debug port is enabled */ - if(BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) + if(BlpDebugPort & 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; + BlpDebugPort &= ~XTBL_DEBUGPORT_SERIAL; return Status; } } diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 104db69..bc41df4 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -78,5 +78,5 @@ BlpInitializeEfiBootLoader() BlpStatus.SystemTable = EfiSystemTable; /* Initialize console */ - BlpConsoleInitialize(); + BlpInitializeConsole(); } diff --git a/xtldr2/globals.c b/xtldr2/globals.c index ae67696..1d38120 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -9,12 +9,18 @@ #include -/* XT Boot Loader configuration data */ -XTBL_CONFIGURATION BlpConfiguration = {0}; +/* XT Boot Loader configuration list */ +PLIST_ENTRY BlpConfig = NULL; + +/* XT Boot Loader debug port configuration */ +ULONG BlpDebugPort = 0; /* XT Boot Loader hex table */ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; +/* XT Boot Loader menu list */ +PLIST_ENTRY BlpMenuList = NULL; + /* Serial port configuration */ CPPORT BlpSerialPort; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index d8ae19b..73d0658 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -56,6 +56,10 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, IN CONST PWCHAR FileSystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); +XTCDECL +PWCHAR +BlGetConfigValue(IN CONST PWCHAR ConfigName); + XTCDECL EFI_STATUS BlGetVolumeDevicePath(IN PCHAR SystemPath, @@ -100,6 +104,11 @@ EFI_STATUS BlOpenXtProtocol(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +XTCDECL +EFI_STATUS +BlSetConfigValue(IN CONST PWCHAR ConfigName, + IN CONST PWCHAR ConfigValue); + XTCDECL VOID BlSleepExecution(IN ULONG_PTR Milliseconds); @@ -115,7 +124,7 @@ BlpActivateSerialIOController(); XTCDECL VOID -BlpConsoleInitialize(); +BlpInitializeConsole(); XTCDECL VOID @@ -168,19 +177,23 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG BaudRate); XTCDECL -VOID +EFI_STATUS +BlpLoadConfiguration(); + +XTCDECL +EFI_STATUS BlpParseCommandLine(VOID); XTCDECL EFI_STATUS -BlpParseConfigurationFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration); +BlpParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration); XTCDECL EFI_STATUS -BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); +BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData); XTCDECL EFI_STATUS @@ -230,6 +243,6 @@ BlpStringReadPadding(IN PUINT16 *Format); XTCDECL VOID -BlpUpdateGlobalConfiguration(IN PWCHAR Options); +BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig); #endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index c43b052..1db2504 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -12,12 +12,18 @@ #include -/* XT Boot Loader configuration data */ -EXTERN XTBL_CONFIGURATION BlpConfiguration; +/* XT Boot Loader configuration list */ +EXTERN PLIST_ENTRY BlpConfig; + +/* XT Boot Loader debug port configuration */ +EXTERN ULONG BlpDebugPort; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; +/* XT Boot Loader menu list */ +EXTERN PLIST_ENTRY BlpMenuList; + /* Serial port configuration */ EXTERN CPPORT BlpSerialPort; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 84c33da..06d5096 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -38,7 +38,13 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse configuration options passed from UEFI shell */ - BlpParseCommandLine(); + Status = BlpParseCommandLine(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to parse command line options */ + BlConsolePrint(L"ERROR: Failed to parse command line options\n"); + BlSleepExecution(3000); + } /* Attempt to early initialize debug console */ if(DEBUG) @@ -52,6 +58,27 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } } + /* Load XTLDR configuration file */ + Status = BlpLoadConfiguration(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load/parse config file */ + BlConsolePrint(L"ERROR: Failed to load configuration file\n"); + BlSleepExecution(3000); + } + + /* Reinitialize debug console if it was not initialized earlier */ + 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) -- 2.45.1 From 02cc0cd522e842fe1c440a66bbf16ffe212892e9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 16:58:08 +0100 Subject: [PATCH 051/182] Implement BlConsoleWrite() routine --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/console.c | 17 +++++++++++++++++ xtldr2/includes/bootman.h | 4 ++++ xtldr2/protocol.c | 1 + 4 files changed, 24 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 67ba8e0..d78b9cf 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -36,6 +36,7 @@ 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_CONSOLE_WRITE)(IN PUSHORT String); 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); @@ -77,6 +78,7 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_CONSOLE_CLEAR_SCREEN ClearScreen; PBL_CONSOLE_DISABLE_CURSOR DisableCursor; PBL_CONSOLE_ENABLE_CURSOR EnableCursor; + PBL_CONSOLE_WRITE Write; PBL_CONSOLE_PRINT Print; } Console; struct diff --git a/xtldr2/console.c b/xtldr2/console.c index d8a7b8e..782810f 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -93,6 +93,23 @@ BlConsolePrint(IN PUINT16 Format, VA_END(Arguments); } +/** + * Displays the string on the device at the current cursor location. + * + * @param String + * The string to be displayed. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlConsoleWrite(IN PUSHORT String) +{ + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); +} + /** * This routine initializes the EFI console. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 73d0658..d8ebedb 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -37,6 +37,10 @@ VOID BlConsolePrint(IN PUINT16 Format, IN ...); +XTCDECL +VOID +BlConsoleWrite(IN PUSHORT String); + XTCDECL VOID BlDebugPrint(IN PUINT16 Format, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 53feebe..069818f 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -94,6 +94,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Console.DisableCursor = BlConsoleDisableCursor; LdrProtocol.Console.EnableCursor = BlConsoleEnableCursor; LdrProtocol.Console.Print = BlConsolePrint; + LdrProtocol.Console.Write = BlConsoleWrite; LdrProtocol.Debug.Print = BlDebugPrint; LdrProtocol.Disk.CloseVolume = BlCloseVolume; LdrProtocol.Disk.OpenVolume = BlOpenVolume; -- 2.45.1 From 9aa2efe17f5b6747c7739f846381f3a43835a130 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 17:37:37 +0100 Subject: [PATCH 052/182] Implement BlConsoleQueryMode() and BlSetCursorPosition() --- sdk/xtdk/bltypes.h | 6 +++++- xtldr2/console.c | 42 +++++++++++++++++++++++++++++++++++++++ xtldr2/includes/bootman.h | 10 ++++++++++ xtldr2/protocol.c | 2 ++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index d78b9cf..bb8267f 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -36,6 +36,8 @@ 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_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); +typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); @@ -78,8 +80,10 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_CONSOLE_CLEAR_SCREEN ClearScreen; PBL_CONSOLE_DISABLE_CURSOR DisableCursor; PBL_CONSOLE_ENABLE_CURSOR EnableCursor; - PBL_CONSOLE_WRITE Write; PBL_CONSOLE_PRINT Print; + PBL_CONSOLE_QUERY_MODE QueryMode; + PBL_CONSOLE_SET_CURSOR_POSITION SetCursorPosition; + PBL_CONSOLE_WRITE Write; } Console; struct { diff --git a/xtldr2/console.c b/xtldr2/console.c index 782810f..6caf0bc 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -93,6 +93,48 @@ BlConsolePrint(IN PUINT16 Format, VA_END(Arguments); } +/** + * Queries information concerning the output device’s supported text mode. + * + * @param ResX + * Supplies a buffer to receive the horizontal resolution. + * + * @param ResY + * Supplies a buffer to receive the vertical resolution. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlConsoleQueryMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY) +{ + EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); +} + +/** + * Sets new coordinates of the console cursor position. + * + * @param PosX + * Specifies the new X coordinate of the cursor. + * + * @param PosY + * Specifies the new Y coordinate of the cursor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlSetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY) +{ + EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); +} + /** * Displays the string on the device at the current cursor location. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index d8ebedb..ffdf282 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -37,6 +37,11 @@ VOID BlConsolePrint(IN PUINT16 Format, IN ...); +XTCDECL +VOID +BlConsoleQueryMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY); + XTCDECL VOID BlConsoleWrite(IN PUSHORT String); @@ -113,6 +118,11 @@ EFI_STATUS BlSetConfigValue(IN CONST PWCHAR ConfigName, IN CONST PWCHAR ConfigValue); +XTCDECL +VOID +BlSetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY); + XTCDECL VOID BlSleepExecution(IN ULONG_PTR Milliseconds); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 069818f..7dfb459 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -94,6 +94,8 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Console.DisableCursor = BlConsoleDisableCursor; LdrProtocol.Console.EnableCursor = BlConsoleEnableCursor; LdrProtocol.Console.Print = BlConsolePrint; + LdrProtocol.Console.QueryMode = BlConsoleQueryMode; + LdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; LdrProtocol.Console.Write = BlConsoleWrite; LdrProtocol.Debug.Print = BlDebugPrint; LdrProtocol.Disk.CloseVolume = BlCloseVolume; -- 2.45.1 From a0794231742b7d54d059e745a7f92fa6f7854973 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 17:41:34 +0100 Subject: [PATCH 053/182] Do not use static linked list --- xtldr2/config.c | 12 ++++++------ xtldr2/globals.c | 3 +++ xtldr2/includes/globals.h | 3 +++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 9925bcd..e7e0a3e 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -114,12 +114,12 @@ EFI_STATUS BlpLoadConfiguration() { PLIST_ENTRY SectionListEntry; - STATIC LIST_ENTRY Configuration; + // STATIC LIST_ENTRY BlpConfiguration; EFI_STATUS Status; PCHAR ConfigData; /* Initialize configuration pointer */ - RtlInitializeListHead(&Configuration); + RtlInitializeListHead(&BlpConfiguration); /* Read data from configuration file */ Status = BlpReadConfigFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); @@ -131,7 +131,7 @@ BlpLoadConfiguration() } /* Parse configuration data */ - Status = BlpParseConfigFile(ConfigData, &Configuration); + Status = BlpParseConfigFile(ConfigData, &BlpConfiguration); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ @@ -140,8 +140,8 @@ BlpLoadConfiguration() } /* Iterate through config sections */ - SectionListEntry = Configuration.Flink; - while(SectionListEntry != &Configuration) + SectionListEntry = BlpConfiguration.Flink; + while(SectionListEntry != &BlpConfiguration) { /* Get config section */ PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink); @@ -162,7 +162,7 @@ BlpLoadConfiguration() } /* Update boot menu OS list */ - BlpMenuList = &Configuration; + BlpMenuList = &BlpConfiguration; /* Return success */ return STATUS_EFI_SUCCESS; diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 1d38120..9fe0c5c 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -12,6 +12,9 @@ /* XT Boot Loader configuration list */ PLIST_ENTRY BlpConfig = NULL; +/* XT Boot Loader loaded configuration */ +LIST_ENTRY BlpConfiguration; + /* XT Boot Loader debug port configuration */ ULONG BlpDebugPort = 0; diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 1db2504..0b9074a 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -15,6 +15,9 @@ /* XT Boot Loader configuration list */ EXTERN PLIST_ENTRY BlpConfig; +/* XT Boot Loader loaded configuration */ +EXTERN LIST_ENTRY BlpConfiguration; + /* XT Boot Loader debug port configuration */ EXTERN ULONG BlpDebugPort; -- 2.45.1 From 2434a018c43a387c731d581b5c8d3dbb45f23bdc Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 17:45:19 +0100 Subject: [PATCH 054/182] Reorder routines --- xtldr2/console.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/xtldr2/console.c b/xtldr2/console.c index 6caf0bc..66b5ded 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -152,27 +152,6 @@ BlConsoleWrite(IN PUSHORT String) EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); } -/** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpInitializeConsole() -{ - /* 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. * @@ -194,3 +173,24 @@ BlpConsolePrintChar(IN USHORT Character) Buffer[1] = 0; EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); } + +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpInitializeConsole() +{ + /* 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(); +} -- 2.45.1 From 155ce1e36616dd7b371fb377086f5c686fcb09b9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 23:35:58 +0100 Subject: [PATCH 055/182] Implement BlSetConsoleAttributes() routine --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/console.c | 51 ++++++++++++++++++++++++++------------- xtldr2/includes/bootman.h | 4 +++ xtldr2/protocol.c | 1 + 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index bb8267f..e60d398 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -37,6 +37,7 @@ typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_PRINT)(IN PUINT16 Format, IN ...); typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); +typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); @@ -82,6 +83,7 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_CONSOLE_ENABLE_CURSOR EnableCursor; PBL_CONSOLE_PRINT Print; PBL_CONSOLE_QUERY_MODE QueryMode; + PBL_CONSOLE_SET_ATTRIBUTES SetAttributes; PBL_CONSOLE_SET_CURSOR_POSITION SetCursorPosition; PBL_CONSOLE_WRITE Write; } Console; diff --git a/xtldr2/console.c b/xtldr2/console.c index 66b5ded..5273f5f 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -114,6 +114,40 @@ BlConsoleQueryMode(OUT PUINT_PTR ResX, EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); } +/** + * Displays the string on the device at the current cursor location. + * + * @param String + * The string to be displayed. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlConsoleWrite(IN PUSHORT String) +{ + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); +} + +/** + * Sets the foreground and background colors. + * + * @param Attribute + * Specifies the foreground and background colors (bits 0..3 are fg, and bits 4..6 are bg color). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlSetConsoleAttributes(IN ULONGLONG Attributes) +{ + EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); +} + /** * Sets new coordinates of the console cursor position. * @@ -135,23 +169,6 @@ BlSetCursorPosition(IN ULONGLONG PosX, EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); } -/** - * Displays the string on the device at the current cursor location. - * - * @param String - * The string to be displayed. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlConsoleWrite(IN PUSHORT String) -{ - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); -} - /** * Writes a character to the default EFI console. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index ffdf282..9a16e58 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -118,6 +118,10 @@ EFI_STATUS BlSetConfigValue(IN CONST PWCHAR ConfigName, IN CONST PWCHAR ConfigValue); +XTCDECL +VOID +BlSetConsoleAttributes(IN ULONGLONG Attributes); + XTCDECL VOID BlSetCursorPosition(IN ULONGLONG PosX, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 7dfb459..941e6dc 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -95,6 +95,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Console.EnableCursor = BlConsoleEnableCursor; LdrProtocol.Console.Print = BlConsolePrint; LdrProtocol.Console.QueryMode = BlConsoleQueryMode; + LdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; LdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; LdrProtocol.Console.Write = BlConsoleWrite; LdrProtocol.Debug.Print = BlDebugPrint; -- 2.45.1 From ced6909d82d706980fb71956c29b5009b8bea381 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 11 Dec 2023 23:44:59 +0100 Subject: [PATCH 056/182] Add EFI TUI definitions --- sdk/xtdk/xtuefi.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sdk/xtdk/xtuefi.h b/sdk/xtdk/xtuefi.h index 8bd8c17..cdff717 100644 --- a/sdk/xtdk/xtuefi.h +++ b/sdk/xtdk/xtuefi.h @@ -227,6 +227,46 @@ /* EFI list of failed CPUs termination */ #define EFI_PROCESSOR_END_OF_LIST 0xFFFFFFFF +/* EFI text background color definitions */ +#define EFI_TEXT_BGCOLOR_BLACK 0x00 +#define EFI_TEXT_BGCOLOR_BLUE 0x10 +#define EFI_TEXT_BGCOLOR_GREEN 0x20 +#define EFI_TEXT_BGCOLOR_CYAN 0x30 +#define EFI_TEXT_BGCOLOR_RED 0x40 +#define EFI_TEXT_BGCOLOR_MAGENTA 0x50 +#define EFI_TEXT_BGCOLOR_BROWN 0x60 +#define EFI_TEXT_BGCOLOR_LIGHTGRAY 0x70 + +/* EFI text foreground color definitions */ +#define EFI_TEXT_FGCOLOR_BLACK 0x00 +#define EFI_TEXT_FGCOLOR_BLUE 0x01 +#define EFI_TEXT_FGCOLOR_GREEN 0x02 +#define EFI_TEXT_FGCOLOR_CYAN 0x03 +#define EFI_TEXT_FGCOLOR_RED 0x04 +#define EFI_TEXT_FGCOLOR_MAGENTA 0x05 +#define EFI_TEXT_FGCOLOR_BROWN 0x06 +#define EFI_TEXT_FGCOLOR_LIGHTGRAY 0x07 +#define EFI_TEXT_FGCOLOR_DARKGRAY 0x08 +#define EFI_TEXT_FGCOLOR_LIGHTBLUE 0x09 +#define EFI_TEXT_FGCOLOR_LIGHTGREEN 0x0A +#define EFI_TEXT_FGCOLOR_LIGHTCYAN 0x0B +#define EFI_TEXT_FGCOLOR_LIGHTRED 0x0C +#define EFI_TEXT_FGCOLOR_LIGHTMAGENTA 0x0D +#define EFI_TEXT_FGCOLOR_YELLOW 0x0E +#define EFI_TEXT_FGCOLOR_WHITE 0x0F + +/* EFI text box character definitions */ +#define EFI_TEXT_BOX_HORIZONTAL 0x2500 +#define EFI_TEXT_BOX_VERTICAL 0x2502 +#define EFI_TEXT_BOX_DOWN_RIGHT 0x250C +#define EFI_TEXT_BOX_DOWN_LEFT 0x2510 +#define EFI_TEXT_BOX_UP_RIGHT 0x2518 +#define EFI_TEXT_BOX_UP_LEFT 0x2514 +#define EFI_TEXT_BOX_VERTICAL_RIGHT 0x251C +#define EFI_TEXT_BOX_VERTICAL_LEFT 0x2524 +#define EFI_TEXT_BOX_FULL_BLOCK 0x2588 +#define EFI_TEXT_BOX_LIGHT_BLOCK 0x2591 + /* EFI protocols GUIDs */ #define EFI_BLOCK_IO_PROTOCOL_GUID {0x964E5B21, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}} #define EFI_BLOCK_IO2_PROTOCOL_GUID {0xA77B2472, 0xE282, 0x4E9F, {0xA2, 0x45, 0xC2, 0xC0, 0xE2, 0x7B, 0xBC, 0xC1}} -- 2.45.1 From ff7ff904990e66e1e0314e97e86e22950b3040f1 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 12 Dec 2023 18:35:35 +0100 Subject: [PATCH 057/182] Implement BlGetSecureBootStatus() and do some refactoring --- xtldr2/config.c | 10 +++++----- xtldr2/console.c | 2 +- xtldr2/debug.c | 36 ++++++++++++++++++------------------ xtldr2/efiutils.c | 39 +++++++++++++++++++++++++++++++++++---- xtldr2/globals.c | 8 +------- xtldr2/includes/bootman.h | 4 ++++ xtldr2/includes/globals.h | 8 +------- xtldr2/protocol.c | 1 + 8 files changed, 66 insertions(+), 42 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index e7e0a3e..dfc0c7b 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -119,7 +119,7 @@ BlpLoadConfiguration() PCHAR ConfigData; /* Initialize configuration pointer */ - RtlInitializeListHead(&BlpConfiguration); + RtlInitializeListHead(&BlpConfigSections); /* Read data from configuration file */ Status = BlpReadConfigFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); @@ -131,7 +131,7 @@ BlpLoadConfiguration() } /* Parse configuration data */ - Status = BlpParseConfigFile(ConfigData, &BlpConfiguration); + Status = BlpParseConfigFile(ConfigData, &BlpConfigSections); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ @@ -140,8 +140,8 @@ BlpLoadConfiguration() } /* Iterate through config sections */ - SectionListEntry = BlpConfiguration.Flink; - while(SectionListEntry != &BlpConfiguration) + SectionListEntry = BlpConfigSections.Flink; + while(SectionListEntry != &BlpConfigSections) { /* Get config section */ PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink); @@ -162,7 +162,7 @@ BlpLoadConfiguration() } /* Update boot menu OS list */ - BlpMenuList = &BlpConfiguration; + BlpMenuList = &BlpConfigSections; /* Return success */ return STATUS_EFI_SUCCESS; diff --git a/xtldr2/console.c b/xtldr2/console.c index 5273f5f..1a5e974 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -82,7 +82,7 @@ BlConsolePrint(IN PUINT16 Format, if(RtlCompareWideString(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)) + if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) { /* Format and print the string to the serial console */ BlpStringPrint(BlpDebugPutChar, Format, Arguments); diff --git a/xtldr2/debug.c b/xtldr2/debug.c index b431723..221c649 100644 --- a/xtldr2/debug.c +++ b/xtldr2/debug.c @@ -36,14 +36,14 @@ BlDebugPrint(IN PUINT16 Format, VA_START(Arguments, Format); /* Check if serial debug port is enabled */ - if((BlpDebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpSerialPort.Flags & COMPORT_FLAG_INIT)) + if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.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((BlpDebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) + if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) { /* Format and print the string to the screen */ BlpStringPrint(BlpConsolePrintChar, Format, Arguments); @@ -78,7 +78,7 @@ BlpInitializeDebugConsole() DebugConfiguration = BlGetConfigValue(L"DEBUG"); /* Make sure any debug options are provided and debug console is not initialized yet */ - if(DebugConfiguration && BlpDebugPort == 0) + if(DebugConfiguration && BlpStatus.DebugPort == 0) { /* Find all debug ports */ DebugPort = RtlTokenizeWideString(DebugConfiguration, L";", &LastPort); @@ -141,12 +141,12 @@ BlpInitializeDebugConsole() } /* Enable debug port */ - BlpDebugPort |= XTBL_DEBUGPORT_SERIAL; + BlpStatus.DebugPort |= XTBL_DEBUGPORT_SERIAL; } else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0) { /* Enable debug port */ - BlpDebugPort |= XTBL_DEBUGPORT_SCREEN; + BlpStatus.DebugPort |= XTBL_DEBUGPORT_SCREEN; } else { @@ -158,18 +158,18 @@ BlpInitializeDebugConsole() /* Take next debug port */ DebugPort = RtlTokenizeWideString(NULL, L";", &LastPort); } - } - /* Check if serial debug port is enabled */ - if(BlpDebugPort & XTBL_DEBUGPORT_SERIAL) - { - /* Try to initialize COM port */ - Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); - if(Status != STATUS_EFI_SUCCESS) + /* Check if serial debug port is enabled */ + if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) { - /* Remove serial debug port, as COM port initialization failed and return */ - BlpDebugPort &= ~XTBL_DEBUGPORT_SERIAL; - return Status; + /* 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 */ + BlpStatus.DebugPort &= ~XTBL_DEBUGPORT_SERIAL; + return Status; + } } } @@ -213,7 +213,7 @@ BlpInitializeSerialPort(IN ULONG PortNumber, } /* Initialize COM port */ - Status = HlInitializeComPort(&BlpSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); + Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); /* Port not found under supplied address */ if(Status == STATUS_NOT_FOUND && PortAddress) @@ -224,7 +224,7 @@ BlpInitializeSerialPort(IN ULONG PortNumber, { /* 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); + Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); } } @@ -259,5 +259,5 @@ BlpDebugPutChar(IN USHORT Character) Buffer[0] = Character; Buffer[1] = 0; - HlComPortPutByte(&BlpSerialPort, Buffer[0]); + HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]); } diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index bc41df4..b385b53 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -26,11 +26,11 @@ BlExitBootServices(IN UINT_PTR MapKey) EFI_STATUS Status; /* Attempt to exit boot services */ - Status = EfiSystemTable->BootServices->ExitBootServices(BlpStatus.ImageHandle, MapKey); + Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey); if(Status != STATUS_EFI_SUCCESS) { /* Retry as UEFI spec says to do it twice */ - Status = EfiSystemTable->BootServices->ExitBootServices(BlpStatus.ImageHandle, MapKey); + Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey); } /* Make sure boot services were successfully exited */ @@ -44,6 +44,39 @@ BlExitBootServices(IN UINT_PTR MapKey) return Status; } +/** + * Checks whether SecureBoot is enabled or not. + * + * @return Numeric representation of SecureBoot status (0 = Disabled, >0 = Enabled, <0 SetupMode). + * + * @since XT 1.0 + */ +XTCDECL +INT_PTR +BlGetSecureBootStatus() +{ + EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; + INT_PTR SecureBootStatus = 0; + UCHAR VarValue = 0; + UINT_PTR Size; + + Size = sizeof(VarValue); + if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid, + NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) + { + SecureBootStatus = (INT_PTR)VarValue; + + if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid, + NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0) + { + SecureBootStatus = -1; + } + } + + /* Return SecureBoot status */ + return SecureBootStatus; +} + /** * Puts the system to sleep for the specified number of milliseconds. * @@ -74,8 +107,6 @@ BlpInitializeEfiBootLoader() { /* Set current XTLDR status */ BlpStatus.BootServices = TRUE; - BlpStatus.ImageHandle = EfiImageHandle; - BlpStatus.SystemTable = EfiSystemTable; /* Initialize console */ BlpInitializeConsole(); diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 9fe0c5c..bbcc200 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -13,10 +13,7 @@ PLIST_ENTRY BlpConfig = NULL; /* XT Boot Loader loaded configuration */ -LIST_ENTRY BlpConfiguration; - -/* XT Boot Loader debug port configuration */ -ULONG BlpDebugPort = 0; +LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; @@ -24,9 +21,6 @@ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; /* XT Boot Loader menu list */ PLIST_ENTRY BlpMenuList = NULL; -/* Serial port configuration */ -CPPORT BlpSerialPort; - /* XT Boot Loader status data */ XTBL_STATUS BlpStatus = {0}; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 9a16e58..0cef47f 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -69,6 +69,10 @@ XTCDECL PWCHAR BlGetConfigValue(IN CONST PWCHAR ConfigName); +XTCDECL +INT_PTR +BlGetSecureBootStatus(); + XTCDECL EFI_STATUS BlGetVolumeDevicePath(IN PCHAR SystemPath, diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 0b9074a..b913e9e 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -16,10 +16,7 @@ EXTERN PLIST_ENTRY BlpConfig; /* XT Boot Loader loaded configuration */ -EXTERN LIST_ENTRY BlpConfiguration; - -/* XT Boot Loader debug port configuration */ -EXTERN ULONG BlpDebugPort; +EXTERN LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; @@ -27,9 +24,6 @@ EXTERN PUINT16 BlpHexTable; /* XT Boot Loader menu list */ EXTERN PLIST_ENTRY BlpMenuList; -/* Serial port configuration */ -EXTERN CPPORT BlpSerialPort; - /* XT Boot Loader status data */ EXTERN XTBL_STATUS BlpStatus; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 941e6dc..73e50ec 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -108,6 +108,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.FreePool = BlMemoryFreePool; LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Util.ExitBootServices = BlExitBootServices; + LdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; LdrProtocol.Util.SleepExecution = BlSleepExecution; /* Register XTLDR loader protocol */ -- 2.45.1 From 616be9d9dd86cbbef9d0bae2581b0b84b7d6d340 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 12 Dec 2023 18:53:14 +0100 Subject: [PATCH 058/182] Fix build --- sdk/xtdk/bltypes.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index e60d398..30f6e44 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -11,10 +11,12 @@ #include #include +#include /* XTLDR directories */ #define XTBL_LOADER_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\" +#define XTBL_MODULES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\MODULES\\" #define XTBL_THEMES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\THEMES\\" /* EFI XT boot devices */ @@ -44,6 +46,7 @@ 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 INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); @@ -69,8 +72,8 @@ typedef struct _XTBL_CONFIG_SECTION typedef struct _XTBL_STATUS { BOOLEAN BootServices; - EFI_HANDLE ImageHandle; - PEFI_SYSTEM_TABLE SystemTable; + ULONG DebugPort; + CPPORT SerialPort; } XTBL_STATUS, *PXTBL_STATUS; /* XTLDR Loader protocol */ @@ -111,6 +114,7 @@ typedef struct _XTBL_LOADER_PROTOCOL struct { PBL_EXIT_BOOT_SERVICES ExitBootServices; + PBL_GET_SECURE_BOOT_STATUS GetSecureBootStatus; PBL_SLEEP_EXECUTION SleepExecution; } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; -- 2.45.1 From e3a4460dbc76fe632975f54b7ec26c88056ebab6 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 09:59:27 +0100 Subject: [PATCH 059/182] Initial Text User Interface (TUI) support --- xtldr2/textui.c | 704 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 704 insertions(+) create mode 100644 xtldr2/textui.c diff --git a/xtldr2/textui.c b/xtldr2/textui.c new file mode 100644 index 0000000..4aa61b6 --- /dev/null +++ b/xtldr2/textui.c @@ -0,0 +1,704 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/textui.c + * DESCRIPTION: Text console User Interface (TUI) support for XT Boot Loader + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* TUI dialog box attributes */ +#define TUI_DIALOG_GENERIC_BOX 1 +#define TUI_DIALOG_ERROR_BOX 2 +#define TUI_DIALOG_ACTIVE_BUTTON 4 +#define TUI_DIALOG_INACTIVE_BUTTON 8 +#define TUI_DIALOG_ACTIVE_INPUT_FIELD 16 +#define TUI_DIALOG_INACTIVE_INPUT_FIELD 32 +#define TUI_DIALOG_PROGRESS_BAR 64 + +#define TUI_MAX_DIALOG_WIDTH 100 + +typedef struct _XTBL_DIALOG_HANDLE +{ + UCHAR Attributes; + UINT_PTR ResX; + UINT_PTR ResY; + UINT_PTR PosX; + UINT_PTR PosY; + UINT_PTR Width; + UINT_PTR Height; +} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; + +XTCDECL +VOID +BlpDetermineDialogBoxSize(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message) +{ + UINT_PTR Width, Height, LineLength; + SIZE_T Index, MessageLength; + UCHAR Attributes; + ULONG Mask; + + /* Set minimum dialog window size */ + Height = 4; + Width = 36; + + /* Zero line length */ + LineLength = 0; + + /* Adjust window height according to enabled components */ + Mask = 1; + Attributes = Handle->Attributes; + while(Mask) + { + /* Check enabled components that affect dialog window size */ + switch(Attributes & Mask) + { + case TUI_DIALOG_ACTIVE_BUTTON: + case TUI_DIALOG_INACTIVE_BUTTON: + Height += 1; + break; + case TUI_DIALOG_ACTIVE_INPUT_FIELD: + case TUI_DIALOG_INACTIVE_INPUT_FIELD: + case TUI_DIALOG_PROGRESS_BAR: + Height += 2; + break; + } + + /* Update component attributes mask */ + Attributes &= ~Mask; + Mask <<= 1; + } + + /* Check if input field is active */ + if(Handle->Attributes & (TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_INPUT_FIELD)) + { + /* Set maximum dialog window width to fit input field */ + Width = TUI_MAX_DIALOG_WIDTH; + } + + /* Get message length and count dialog window dimensions */ + MessageLength = RtlWideStringLength(Message, 0); + for(Index = 0; Index < MessageLength; Index++) + { + /* Check if this is multiline message */ + if(Message[Index] == L'\n' || Index == MessageLength - 1) + { + /* Check if this line exceeds current dialog window width */ + if(LineLength > Width) + { + /* Update dialog window width */ + Width = LineLength; + } + /* Increase dialog window height to fit next line */ + Height++; + LineLength = 0; + } + else + { + /* Increase dialog window width to fit next character */ + LineLength++; + } + } + + /* Add more space to dialog window to fit side borders */ + Width += 4; + + /* Get console resolution */ + BlConsoleQueryMode(&Handle->ResX, &Handle->ResY); + + /* Make sure dialog window fits in the buffer */ + if(Width > TUI_MAX_DIALOG_WIDTH) + { + /* Set maximum dialog window width */ + Width = TUI_MAX_DIALOG_WIDTH; + } + + /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ + if(Width > (Handle->ResX - 2)) + { + /* Set maximum dialog window width */ + Width = Handle->ResX - 2; + } + + /* Make sure dialog window fits on the screen (Y axis)*/ + if(Height > (Handle->ResY - 2)) + { + /* Set maximum dialog window height */ + Height = Handle->ResY - 2; + } + + /* Set dialog window final dimensions */ + Handle->PosX = (Handle->ResX - Width) / 2; + Handle->PosY = (Handle->ResY - Height) / 2; + Handle->Width = Width; + Handle->Height = Height; +} + +XTCDECL +VOID +BlpDrawDialogBox(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Caption, + IN PWCHAR Message) +{ + WCHAR BoxLine[TUI_MAX_DIALOG_WIDTH]; + PWCHAR MsgLine, LastMsgLine; + UINT_PTR Line, PosX, PosY; + SIZE_T CaptionLength; + UCHAR DialogColor; + + /* Set dialog colors */ + if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + { + /* Error dialog with red background and brown button */ + DialogColor = EFI_TEXT_BGCOLOR_RED; + } + else + { + /* Generic dialog with blue background and cyan button */ + DialogColor = EFI_TEXT_BGCOLOR_BLUE; + } + + /* Get caption length */ + CaptionLength = RtlWideStringLength(Caption, 0); + + /* Set dialog box colors */ + BlSetConsoleAttributes(DialogColor | 0x0F); + + /* Iterate through dialog box lines */ + for(PosY = Handle->PosY; PosY < Handle->PosY + Handle->Height; PosY++) + { + /* Set cursor position in the appropriate place */ + BlSetCursorPosition(Handle->PosX, PosY); + + /* Draw dialog box */ + if(PosY == Handle->PosY) + { + /* Draw top line of the dialog box, starting from the left corner */ + BoxLine[0] = EFI_TEXT_BOX_DOWN_RIGHT; + BoxLine[1] = EFI_TEXT_BOX_VERTICAL_LEFT; + + /* Fill caption area with spaces */ + for(PosX = 2; PosX < CaptionLength + 4; PosX++) + { + BoxLine[PosX] = ' '; + } + + /* End caption area with vertical line */ + BoxLine[CaptionLength + 4] = EFI_TEXT_BOX_VERTICAL_RIGHT; + + /* Draw bottom line */ + for(PosX = CaptionLength + 5; PosX < Handle->Width - 1; PosX++) + { + BoxLine[PosX] = EFI_TEXT_BOX_HORIZONTAL; + } + + /* End with top right corner */ + BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_DOWN_LEFT; + } + else if(PosY == Handle->PosY + Handle->Height - 1) + { + /* Draw bottom line of the dialog box, starting from the left corner */ + BoxLine[0] = EFI_TEXT_BOX_UP_LEFT; + + /* Fill bottom with horizontal line */ + for(PosX = 1; PosX < Handle->Width - 1; PosX++) + { + BoxLine[PosX] = EFI_TEXT_BOX_HORIZONTAL; + } + + /* End with bottom right corner */ + BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_UP_RIGHT; + } + else + { + /* Draw the middle of the dialog box */ + BoxLine[0] = EFI_TEXT_BOX_VERTICAL; + + /* Fill dialog box with spaces */ + for(PosX = 1; PosX < Handle->Width - 1; PosX++) + { + BoxLine[PosX] = ' '; + } + + /* End with vertical line */ + BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_VERTICAL; + } + + /* Add null terminator to the end of the line */ + BoxLine[Handle->Width] = 0; + + /* Write the line to the console */ + BlConsoleWrite(BoxLine); + } + + /* Write dialog box caption */ + BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); + BlConsolePrint(L"%S", Caption); + + /* Tokenize dialog box message */ + MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); + + /* Iterate through message lines */ + Line = 0; + while(MsgLine) + { + /* Write line in the dialog box */ + BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); + BlConsolePrint(L"%S", MsgLine); + + /* Get next line */ + MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); + Line++; + } +} + +XTCDECL +VOID +BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) +{ + ULONG ButtonColor, TextColor; + + /* Set dialog button colors */ + if(Handle->Attributes & TUI_DIALOG_ACTIVE_BUTTON) + { + /* This is an active button */ + if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + { + /* This is an error dialog box */ + ButtonColor = EFI_TEXT_BGCOLOR_BROWN; + TextColor = EFI_TEXT_FGCOLOR_WHITE; + } + else + { + /* This is a generic dialog box */ + ButtonColor = EFI_TEXT_BGCOLOR_CYAN; + TextColor = EFI_TEXT_FGCOLOR_WHITE; + } + } + else + { + /* This is an inactive button */ + ButtonColor = EFI_TEXT_BGCOLOR_LIGHTGRAY; + TextColor = EFI_TEXT_FGCOLOR_BLACK; + } + + /* Disable cursor and draw dialog button */ + BlConsoleDisableCursor(); + BlSetConsoleAttributes(ButtonColor | TextColor); + BlSetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); + BlConsolePrint(L"[ OK ]"); +} + +XTCDECL +VOID +BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText) +{ + WCHAR InputField[TUI_MAX_DIALOG_WIDTH]; + ULONG InputColor, TextColor; + UINT_PTR Index, Position; + + /* Set dialog button colors */ + if(Handle->Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + /* This is an active input field */ + if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + { + /* This is an error dialog box */ + InputColor = EFI_TEXT_BGCOLOR_BROWN; + TextColor = EFI_TEXT_FGCOLOR_WHITE; + } + else + { + /* This is a generic dialog box */ + InputColor = EFI_TEXT_BGCOLOR_CYAN; + TextColor = EFI_TEXT_FGCOLOR_WHITE; + } + } + else + { + /* This is an inactive input field */ + InputColor = EFI_TEXT_BGCOLOR_LIGHTGRAY; + TextColor = EFI_TEXT_FGCOLOR_BLACK; + } + + /* Set progress bar color and position */ + BlSetConsoleAttributes(InputColor | TextColor); + Position = (Handle->Attributes & (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; + BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + + /* Draw input field */ + for(Index = 0; Index < Handle->Width - 8; Index++) + { + /* Fill input field with spaces */ + InputField[Index] = L' '; + } + + /* Disable cursor and write input field to console */ + BlConsoleDisableCursor(); + BlConsoleWrite(InputField); + + /* Write input field text */ + BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + BlConsoleWrite(InputFieldText); + + /* Check if this is an active input field */ + if(Handle->Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + /* Enable cursor for active input field */ + BlConsoleEnableCursor(); + } +} + +XTCDECL +VOID +BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage) +{ + UINT_PTR Index, ProgressLength, ProgressBarLength; + WCHAR ProgressBar[TUI_MAX_DIALOG_WIDTH]; + UINT_PTR Position; + + /* Determine progress bar length and calculate progress */ + ProgressBarLength = Handle->Width - 8; + ProgressLength = (ProgressBarLength * Percentage) / 100; + + /* Set progress bar color and position */ + BlSetConsoleAttributes(EFI_TEXT_FGCOLOR_YELLOW); + Position = (Handle->Attributes & (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; + BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + + /* Draw progress bar */ + for(Index = 0; Index < ProgressBarLength; Index++) + { + /* Fill progress bar */ + if(Index < ProgressLength) + { + /* Fill with full block */ + ProgressBar[Index] = EFI_TEXT_BOX_FULL_BLOCK; + } + else + { + /* Fill with light block */ + ProgressBar[Index] = EFI_TEXT_BOX_LIGHT_BLOCK; + } + } + + /* Terminate progress bar string */ + ProgressBar[Index] = 0; + + /* Disable cursor and write progress bar to console */ + BlConsoleDisableCursor(); + BlConsoleWrite(ProgressBar); +} + + + + + +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message) +{ + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlConsoleDisableCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlConsoleClearScreen(); +} + +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message) +{ + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlConsoleDisableCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlConsoleClearScreen(); +} + +XTCDECL +VOID +BlDisplayInputDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN PWCHAR InputFieldBuffer) +{ + XTBL_DIALOG_HANDLE Handle; + SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlConsoleDisableCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw inactive button */ + BlpDrawDialogButton(&Handle); + + /* Draw active input field */ + BlpDrawDialogInputField(&Handle, InputFieldBuffer); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Determine input field length */ + InputFieldLength = RtlWideStringLength(InputFieldBuffer, 0); + if(InputFieldLength > Handle.Width - 8) + { + InputFieldLength = Handle.Width - 8; + } + + /* Start at first character */ + TextPosition = 0; + BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); + + /* Wait until ENTER or ESC key is pressed */ + while(TRUE) + { + /* Wait for key press and read key stroke */ + EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + + /* Check key press scan code */ + if(Key.ScanCode == 0x17) + { + /* ESC key pressed, return */ + break; + } + else if(Key.UnicodeChar == 0x09) + { + /* TAB key pressed, toggle input field and button */ + Handle.Attributes ^= (TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_INPUT_FIELD); + Handle.Attributes ^= (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON); + } + else if(Key.ScanCode == 0x03) + { + /* RIGHT key pressed, move cursor forward */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition < InputFieldLength) + { + TextPosition++; + } + } + else if(Key.ScanCode == 0x04) + { + /* LEFT key pressed, move cursor back */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition > 0) + { + TextPosition--; + } + } + else if(Key.ScanCode == 0x05) + { + /* HOME key pressed, move cursor to the beginning */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + TextPosition = 0; + } + } + else if(Key.ScanCode == 0x06) + { + /* END key pressed, move cursor to the end */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + TextPosition = InputFieldLength; + } + } + else if(Key.ScanCode == 0x08) + { + /* DELETE key pressed, delete character */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + if(InputFieldLength > 0 && TextPosition < InputFieldLength) + { + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, InputFieldLength - TextPosition); + InputFieldLength--; + InputFieldBuffer[InputFieldLength] = 0; + } + } + } + else if(Key.UnicodeChar == 0x08) + { + /* BACKSPACE key pressed, delete character */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) + { + TextPosition--; + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, InputFieldLength - TextPosition); + InputFieldLength--; + InputFieldBuffer[InputFieldLength] = 0; + } + } + } + else if(Key.UnicodeChar == 0x0D) + { + /* ENTER key pressed */ + } + else + { + /* Other key pressed, add character to the buffer */ + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && Key.UnicodeChar != 0) + { + if(InputFieldLength < Handle.Width - 8 - 1 && TextPosition < Handle.Width - 8 - 1) + { + RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, InputFieldLength - TextPosition); + InputFieldBuffer[TextPosition] = Key.UnicodeChar; + TextPosition++; + InputFieldLength++; + InputFieldBuffer[InputFieldLength] = 0; + } + } + } + + if(TextPosition > (Handle.Width - 8)) + { + TextIndex = TextPosition - (Handle.Width - 8); + TextCursorPosition = Handle.Width - 8; + } + else + { + TextIndex = 0; + TextCursorPosition = TextPosition; + } + + /* Redraw input field and button */ + BlpDrawDialogButton(&Handle); + BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); + + if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + { + BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); + } + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlConsoleClearScreen(); +} + +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + XTBL_DIALOG_HANDLE Handle; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlConsoleDisableCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogProgressBar(&Handle, Percentage); + + /* Return dialog handle */ + return Handle; +} + +// TODO: Common routine for printing text on dialog window +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + SIZE_T Index, Length; + + /* Check if message needs an update */ + if(Message != NULL) + { + /* Determine message length */ + Length = RtlWideStringLength(Message, 0); + + /* Update message in the dialog box */ + BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2); + BlConsolePrint(L"%S", Message); + + if(Length < Handle->Width - 4) + { + for(Index = Length; Index < Handle->Width - 4; Index++) + { + BlConsolePrint(L" "); + } + } + } + + /* Update progress bar */ + BlpDrawDialogProgressBar(Handle, Percentage); +} -- 2.45.1 From c649087c3ed468a6be8931865e143e18b82a8970 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 10:12:23 +0100 Subject: [PATCH 060/182] Fix progress bar colors --- xtldr2/textui.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 4aa61b6..1cc3fe2 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -23,6 +23,8 @@ typedef struct _XTBL_DIALOG_HANDLE { UCHAR Attributes; + UCHAR DialogColor; + UCHAR TextColor; UINT_PTR ResX; UINT_PTR ResY; UINT_PTR PosX; @@ -147,25 +149,26 @@ BlpDrawDialogBox(IN PXTBL_DIALOG_HANDLE Handle, PWCHAR MsgLine, LastMsgLine; UINT_PTR Line, PosX, PosY; SIZE_T CaptionLength; - UCHAR DialogColor; /* Set dialog colors */ if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) { /* Error dialog with red background and brown button */ - DialogColor = EFI_TEXT_BGCOLOR_RED; + Handle->DialogColor = EFI_TEXT_BGCOLOR_RED; + Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE; } else { /* Generic dialog with blue background and cyan button */ - DialogColor = EFI_TEXT_BGCOLOR_BLUE; + Handle->DialogColor = EFI_TEXT_BGCOLOR_BLUE; + Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE; } /* Get caption length */ CaptionLength = RtlWideStringLength(Caption, 0); /* Set dialog box colors */ - BlSetConsoleAttributes(DialogColor | 0x0F); + BlSetConsoleAttributes(Handle->DialogColor | 0x0F); /* Iterate through dialog box lines */ for(PosY = Handle->PosY; PosY < Handle->PosY + Handle->Height; PosY++) @@ -688,6 +691,7 @@ BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, /* Update message in the dialog box */ BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2); + BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); BlConsolePrint(L"%S", Message); if(Length < Handle->Width - 4) -- 2.45.1 From ea33166efa4b39277b11d65dec06e46e39269f6d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 10:13:37 +0100 Subject: [PATCH 061/182] Compile XTLDR TUI --- xtldr2/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 266edd6..e6a8237 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/string.c + ${XTLDR_SOURCE_DIR}/textui.c ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) -- 2.45.1 From 83e555043a23b2e8396bfde0349238a4815d9ac1 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 11:06:56 +0100 Subject: [PATCH 062/182] Add documentation to private TUI-related routines --- xtldr2/textui.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 1cc3fe2..2959e47 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -33,9 +33,22 @@ typedef struct _XTBL_DIALOG_HANDLE UINT_PTR Height; } XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; +/** + * Determines dialog box size based on enabled components and message length. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a pointer to the message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -BlpDetermineDialogBoxSize(IN PXTBL_DIALOG_HANDLE Handle, +BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message) { UINT_PTR Width, Height, LineLength; @@ -139,9 +152,25 @@ BlpDetermineDialogBoxSize(IN PXTBL_DIALOG_HANDLE Handle, Handle->Height = Height; } +/** + * Draws dialog box with caption and message. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Caption + * Specifies a caption string put on the dialog box. + * + * @param Message + * Specifies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -BlpDrawDialogBox(IN PXTBL_DIALOG_HANDLE Handle, +BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Caption, IN PWCHAR Message) { @@ -258,6 +287,16 @@ BlpDrawDialogBox(IN PXTBL_DIALOG_HANDLE Handle, } } +/** + * Draws an active or inactive button in the dialog box, depending on the attributes. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) @@ -295,6 +334,19 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) BlConsolePrint(L"[ OK ]"); } +/** + * Draws an active or inactive input field in the dialog box, depending on the attributes. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param InputFieldText + * Supplies a pointer to the wide char string that will be displayed in the input field. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, @@ -356,6 +408,19 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } } +/** + * Draws a progress bar component in the dialog box. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Percentage + * Specifies the percentage progress of the progress bar. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, -- 2.45.1 From 74cac842a5620bffb29ee292b7f96dbc67f1a42d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 12:44:18 +0100 Subject: [PATCH 063/182] Implement more wrappers and refactoring --- sdk/xtdk/bltypes.h | 6 +++ xtldr2/console.c | 83 +++++++++++++++++++++++++++------------ xtldr2/efiutils.c | 25 ++++++++++++ xtldr2/includes/bootman.h | 48 ++++++++++++++-------- xtldr2/protocol.c | 11 ++++-- xtldr2/textui.c | 56 +++++++++++++++----------- 6 files changed, 160 insertions(+), 69 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 30f6e44..6954fb7 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -39,6 +39,8 @@ typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_PRINT)(IN PUINT16 Format, IN ...); typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); +typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); +typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)(); typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); @@ -51,6 +53,7 @@ typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, O typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); +typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); /* XTLDR Configuration data */ typedef struct _XTBL_CONFIG_ENTRY @@ -86,6 +89,8 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_CONSOLE_ENABLE_CURSOR EnableCursor; PBL_CONSOLE_PRINT Print; PBL_CONSOLE_QUERY_MODE QueryMode; + PBL_CONSOLE_READ_KEY_STROKE ReadKeyStroke; + PBL_CONSOLE_RESET_INPUT_BUFFER ResetInputBuffer; PBL_CONSOLE_SET_ATTRIBUTES SetAttributes; PBL_CONSOLE_SET_CURSOR_POSITION SetCursorPosition; PBL_CONSOLE_WRITE Write; @@ -116,6 +121,7 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_EXIT_BOOT_SERVICES ExitBootServices; PBL_GET_SECURE_BOOT_STATUS GetSecureBootStatus; PBL_SLEEP_EXECUTION SleepExecution; + PBL_WAIT_FOR_EFI_EVENT WaitForEfiEvent; } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; diff --git a/xtldr2/console.c b/xtldr2/console.c index 1a5e974..1e7a277 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -18,7 +18,7 @@ */ XTCDECL VOID -BlConsoleClearScreen() +BlClearConsoleScreen() { /* Clear screen */ EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); @@ -33,7 +33,7 @@ BlConsoleClearScreen() */ XTCDECL VOID -BlConsoleDisableCursor() +BlDisableConsoleCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); } @@ -47,7 +47,7 @@ BlConsoleDisableCursor() */ XTCDECL VOID -BlConsoleEnableCursor() +BlEnableConsoleCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); } @@ -93,27 +93,6 @@ BlConsolePrint(IN PUINT16 Format, VA_END(Arguments); } -/** - * Queries information concerning the output device’s supported text mode. - * - * @param ResX - * Supplies a buffer to receive the horizontal resolution. - * - * @param ResY - * Supplies a buffer to receive the vertical resolution. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlConsoleQueryMode(OUT PUINT_PTR ResX, - OUT PUINT_PTR ResY) -{ - EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); -} - /** * Displays the string on the device at the current cursor location. * @@ -131,6 +110,58 @@ BlConsoleWrite(IN PUSHORT String) EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); } +/** + * Queries information concerning the output device’s supported text mode. + * + * @param ResX + * Supplies a buffer to receive the horizontal resolution. + * + * @param ResY + * Supplies a buffer to receive the vertical resolution. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlQueryConsoleMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY) +{ + EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); +} + +/** + * Reads a keystroke from the input device. + * + * @param Key + * Supplies a pointer to the EFI_INPUT_KEY structure that will receive the keystroke. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) +{ + EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); +} + +/** + * Resets the console input device and clears its input buffer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlResetConsoleInputBuffer() +{ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); +} + /** * Sets the foreground and background colors. * @@ -208,6 +239,6 @@ BlpInitializeConsole() EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); /* Clear screen and enable cursor */ - BlConsoleClearScreen(); - BlConsoleEnableCursor(); + BlClearConsoleScreen(); + BlEnableConsoleCursor(); } diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index b385b53..28bdf7f 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -94,6 +94,31 @@ BlSleepExecution(IN ULONG_PTR Milliseconds) EfiSystemTable->BootServices->Stall(Milliseconds * 1000); } +/** + * Waits for one or more EFI events. + * + * @param NumberOfEvents + * Supplies the number of events to wait for. + * + * @param Event + * Supplies the array of events to wait for. + * + * @param Index + * Receives the index of the event that was signaled. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index) +{ + return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); +} + /** * Initializes EFI Boot Loader (XTLDR). * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 0cef47f..c4ef222 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -16,32 +16,19 @@ typedef VOID (BMPRINTCHAR)(IN USHORT Character); /* XTLDR routines forward references */ +XTCDECL +VOID +BlClearConsoleScreen(); + XTCDECL EFI_STATUS BlCloseVolume(IN PEFI_HANDLE VolumeHandle); -XTCDECL -VOID -BlConsoleClearScreen(); - -XTCDECL -VOID -BlConsoleDisableCursor(); - -XTCDECL -VOID -BlConsoleEnableCursor(); - XTCDECL VOID BlConsolePrint(IN PUINT16 Format, IN ...); -XTCDECL -VOID -BlConsoleQueryMode(OUT PUINT_PTR ResX, - OUT PUINT_PTR ResY); - XTCDECL VOID BlConsoleWrite(IN PUSHORT String); @@ -51,6 +38,14 @@ VOID BlDebugPrint(IN PUINT16 Format, IN ...); +XTCDECL +VOID +BlDisableConsoleCursor(); + +XTCDECL +VOID +BlEnableConsoleCursor(); + XTCDECL EFI_STATUS BlEnumerateBlockDevices(); @@ -96,6 +91,11 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); +XTCDECL +VOID +BlQueryConsoleMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY); + XTCDECL EFI_STATUS BlReadFile(IN PEFI_FILE_HANDLE DirHandle, @@ -103,6 +103,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, OUT PVOID *FileData, OUT PSIZE_T FileSize); +XTCDECL +VOID +BlReadKeyStroke(OUT PEFI_INPUT_KEY Key); + +XTCDECL +VOID +BlResetConsoleInputBuffer(); + XTCDECL EFI_STATUS BlMemoryFreePages(IN UINT64 Pages, @@ -140,6 +148,12 @@ EFI_STATUS BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); +XTCDECL +EFI_STATUS +BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index); + XTCDECL EFI_STATUS BlpActivateSerialIOController(); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 73e50ec..2ac749a 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -90,11 +90,13 @@ BlpRegisterXtLoaderProtocol() 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.ClearScreen = BlClearConsoleScreen; + LdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; + LdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; LdrProtocol.Console.Print = BlConsolePrint; - LdrProtocol.Console.QueryMode = BlConsoleQueryMode; + LdrProtocol.Console.QueryMode = BlQueryConsoleMode; + LdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; + LdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; LdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; LdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; LdrProtocol.Console.Write = BlConsoleWrite; @@ -110,6 +112,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Util.ExitBootServices = BlExitBootServices; LdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; LdrProtocol.Util.SleepExecution = BlSleepExecution; + LdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 2959e47..ef9fa97 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -122,7 +122,7 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, Width += 4; /* Get console resolution */ - BlConsoleQueryMode(&Handle->ResX, &Handle->ResY); + BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); /* Make sure dialog window fits in the buffer */ if(Width > TUI_MAX_DIALOG_WIDTH) @@ -328,7 +328,7 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) } /* Disable cursor and draw dialog button */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlSetConsoleAttributes(ButtonColor | TextColor); BlSetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); BlConsolePrint(L"[ OK ]"); @@ -393,7 +393,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } /* Disable cursor and write input field to console */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlConsoleWrite(InputField); /* Write input field text */ @@ -404,7 +404,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, if(Handle->Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) { /* Enable cursor for active input field */ - BlConsoleEnableCursor(); + BlEnableConsoleCursor(); } } @@ -459,14 +459,26 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, ProgressBar[Index] = 0; /* Disable cursor and write progress bar to console */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlConsoleWrite(ProgressBar); } - +/** + * Displays a red error dialog box with the specified caption and message. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlDisplayErrorDialog(IN PWCHAR Caption, @@ -483,7 +495,7 @@ BlDisplayErrorDialog(IN PWCHAR Caption, BlpDetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlpDrawDialogBox(&Handle, Caption, Message); /* Draw active button */ @@ -497,14 +509,14 @@ BlDisplayErrorDialog(IN PWCHAR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); } /* Clear screen to remove dialog box */ BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsoleClearScreen(); + BlClearConsoleScreen(); } XTCDECL @@ -523,7 +535,7 @@ BlDisplayInfoDialog(IN PWCHAR Caption, BlpDetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlpDrawDialogBox(&Handle, Caption, Message); /* Draw active button */ @@ -537,14 +549,14 @@ BlDisplayInfoDialog(IN PWCHAR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); } /* Clear screen to remove dialog box */ BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsoleClearScreen(); + BlClearConsoleScreen(); } XTCDECL @@ -565,7 +577,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlpDetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlpDrawDialogBox(&Handle, Caption, Message); /* Draw inactive button */ @@ -593,9 +605,9 @@ BlDisplayInputDialog(IN PWCHAR Caption, while(TRUE) { /* Wait for key press and read key stroke */ - EfiSystemTable->BootServices->WaitForEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, &Key); - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); /* Check key press scan code */ if(Key.ScanCode == 0x17) @@ -711,7 +723,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, /* Clear screen to remove dialog box */ BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsoleClearScreen(); + BlClearConsoleScreen(); } XTCDECL @@ -729,7 +741,7 @@ BlDisplayProgressDialog(IN PWCHAR Caption, BlpDetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlConsoleDisableCursor(); + BlDisableConsoleCursor(); BlpDrawDialogBox(&Handle, Caption, Message); /* Draw active button */ -- 2.45.1 From 451a84a20f6efb84aa0cdf6f225b2c0b02249d69 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 13:41:35 +0100 Subject: [PATCH 064/182] Almost complete TUI --- sdk/xtdk/bltypes.h | 22 +- xtldr2/includes/bootman.h | 52 +++++ xtldr2/textui.c | 412 ++++++++++++++++++++++---------------- 3 files changed, 305 insertions(+), 181 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 6954fb7..5615a6b 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: sdk/xtdk/bmtypes.h + * FILE: sdk/xtdk/bltypes.h * DESCRIPTION: XT Boot Manager structures definitions * DEVELOPERS: Rafal Kupiec */ -#ifndef __XTDK_BMTYPES_H -#define __XTDK_BMTYPES_H +#ifndef __XTDK_BLTYPES_H +#define __XTDK_BLTYPES_H #include #include @@ -71,6 +71,20 @@ typedef struct _XTBL_CONFIG_SECTION PWCHAR SectionName; } XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; +/* XTLDR Dialog handle data */ +typedef struct _XTBL_DIALOG_HANDLE +{ + UCHAR Attributes; + UCHAR DialogColor; + UCHAR TextColor; + UINT_PTR ResX; + UINT_PTR ResY; + UINT_PTR PosX; + UINT_PTR PosY; + UINT_PTR Width; + UINT_PTR Height; +} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; + /* XTLDR Status data */ typedef struct _XTBL_STATUS { @@ -125,4 +139,4 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; -#endif /* __XTDK_BMTYPES_H */ +#endif /* __XTDK_BLTYPES_H */ diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index c4ef222..6e727bc 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -42,6 +42,22 @@ XTCDECL VOID BlDisableConsoleCursor(); +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage); + XTCDECL VOID BlEnableConsoleCursor(); @@ -148,6 +164,12 @@ EFI_STATUS BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage); + XTCDECL EFI_STATUS BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, @@ -170,6 +192,11 @@ XTCDECL VOID BlpDebugPutChar(IN USHORT Character); +XTCDECL +VOID +BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + XTCDECL EFI_STATUS BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); @@ -183,6 +210,31 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, OUT PULONG DriveNumber, OUT PULONG PartNumber); +XTCDECL +VOID +BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle); + +XTCDECL +VOID +BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText); + +XTCDECL +VOID +BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage); + XTCDECL PEFI_DEVICE_PATH_PROTOCOL BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); diff --git a/xtldr2/textui.c b/xtldr2/textui.c index ef9fa97..88360d2 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -20,18 +20,185 @@ #define TUI_MAX_DIALOG_WIDTH 100 -typedef struct _XTBL_DIALOG_HANDLE +/** + * Displays a red error dialog box with the specified caption and message. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message) { - UCHAR Attributes; - UCHAR DialogColor; - UCHAR TextColor; - UINT_PTR ResX; - UINT_PTR ResY; - UINT_PTR PosX; - UINT_PTR PosY; - UINT_PTR Width; - UINT_PTR Height; -} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); +} + +/** + * Displays a blue informational dialog box with the specified caption and message. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message) +{ + XTBL_DIALOG_HANDLE Handle; + EFI_INPUT_KEY Key; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogButton(&Handle); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Wait until ENTER or ESC key is pressed */ + while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) + { + /* Wait for key press and read key stroke */ + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); +} + +/** + * Displays a blue informational dialog box with the specified caption and message and a progress bar. + * + * @param Caption + * Supplies a caption string put on the dialog box. + * + * @param Message + * Supplies a message string put on the dialog box. + * + * @param Percentage + * Specifies the percentage progress of the progress bar. + * + * @return This routine returns a dialog box handle needed to update the progress bar. + * + * @since XT 1.0 + */ +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + XTBL_DIALOG_HANDLE Handle; + + /* Set dialog window attributes */ + Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw active button */ + BlpDrawDialogProgressBar(&Handle, Percentage); + + /* Return dialog handle */ + return Handle; +} + +/** + * Updates the progress bar on the dialog box. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a new message that will be put on the dialog box, while updating the progress bar. + * + * @param Percentage + * Specifies the new percentage progress of the progress bar. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage) +{ + /* Check if message needs an update */ + if(Message != NULL) + { + /* Update a message on the dialog box */ + BlpDrawDialogMessage(Handle, Message); + } + + /* Update progress bar */ + BlpDrawDialogProgressBar(Handle, Percentage); +} /** * Determines dialog box size based on enabled components and message length. @@ -175,9 +342,8 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message) { WCHAR BoxLine[TUI_MAX_DIALOG_WIDTH]; - PWCHAR MsgLine, LastMsgLine; - UINT_PTR Line, PosX, PosY; SIZE_T CaptionLength; + UINT_PTR PosX, PosY; /* Set dialog colors */ if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) @@ -270,21 +436,8 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); BlConsolePrint(L"%S", Caption); - /* Tokenize dialog box message */ - MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); - - /* Iterate through message lines */ - Line = 0; - while(MsgLine) - { - /* Write line in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); - BlConsolePrint(L"%S", MsgLine); - - /* Get next line */ - MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); - Line++; - } + /* Write a message on the dialog box */ + BlpDrawDialogMessage(Handle, Message); } /** @@ -408,6 +561,59 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } } +/** + * Draws a message on the dialog box specified by the handle. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a message that will be displayed on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message) +{ + PWCHAR MsgLine, LastMsgLine; + SIZE_T Index, Length; + ULONG Line; + + /* Tokenize dialog box message */ + MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); + + /* Iterate through message lines */ + Line = 0; + while(MsgLine) + { + /* Determine line length */ + Length = RtlWideStringLength(Message, 0); + + /* Write line in the dialog box */ + BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); + BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); + BlConsolePrint(L"%S", MsgLine); + + /* Check if message line is shorter than the dialog box working area */ + if(Length < Handle->Width - 4) + { + /* Fill the rest of the line with spaces */ + for(Index = Length; Index < Handle->Width - 4; Index++) + { + BlConsolePrint(L" "); + } + } + + /* Get next line */ + MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); + Line++; + } +} + /** * Draws a progress bar component in the dialog box. * @@ -466,99 +672,9 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, -/** - * Displays a red error dialog box with the specified caption and message. - * - * @param Caption - * Supplies a caption string put on the dialog box. - * - * @param Message - * Supplies a message string put on the dialog box. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlDisplayErrorDialog(IN PWCHAR Caption, - IN PWCHAR Message) -{ - XTBL_DIALOG_HANDLE Handle; - EFI_INPUT_KEY Key; - UINT_PTR Index; - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogButton(&Handle); - - /* Initialize key stroke */ - Key.ScanCode = 0; - Key.UnicodeChar = 0; - - /* Wait until ENTER or ESC key is pressed */ - while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) - { - /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); - } - - /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); -} - -XTCDECL -VOID -BlDisplayInfoDialog(IN PWCHAR Caption, - IN PWCHAR Message) -{ - XTBL_DIALOG_HANDLE Handle; - EFI_INPUT_KEY Key; - UINT_PTR Index; - - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogButton(&Handle); - - /* Initialize key stroke */ - Key.ScanCode = 0; - Key.UnicodeChar = 0; - - /* Wait until ENTER or ESC key is pressed */ - while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) - { - /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); - } - - /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); -} +// TODO: FIX, this is completely broken XTCDECL VOID BlDisplayInputDialog(IN PWCHAR Caption, @@ -725,61 +841,3 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); BlClearConsoleScreen(); } - -XTCDECL -XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN UCHAR Percentage) -{ - XTBL_DIALOG_HANDLE Handle; - - /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw active button */ - BlpDrawDialogProgressBar(&Handle, Percentage); - - /* Return dialog handle */ - return Handle; -} - -// TODO: Common routine for printing text on dialog window -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message, - IN UCHAR Percentage) -{ - SIZE_T Index, Length; - - /* Check if message needs an update */ - if(Message != NULL) - { - /* Determine message length */ - Length = RtlWideStringLength(Message, 0); - - /* Update message in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2); - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlConsolePrint(L"%S", Message); - - if(Length < Handle->Width - 4) - { - for(Index = Length; Index < Handle->Width - 4; Index++) - { - BlConsolePrint(L" "); - } - } - } - - /* Update progress bar */ - BlpDrawDialogProgressBar(Handle, Percentage); -} -- 2.45.1 From 297b201f337f327e9e88fcf70cbc198c15e15672 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 14:01:07 +0100 Subject: [PATCH 065/182] Move definitions to proper header --- sdk/xtdk/bltypes.h | 12 +++++++ xtldr2/textui.c | 79 ++++++++++++++++++++-------------------------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 5615a6b..09e20c8 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -30,6 +30,18 @@ #define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SERIAL 2 +/* TUI dialog box attributes */ +#define XTBL_TUI_DIALOG_GENERIC_BOX 1 +#define XTBL_TUI_DIALOG_ERROR_BOX 2 +#define XTBL_TUI_DIALOG_ACTIVE_BUTTON 4 +#define XTBL_TUI_DIALOG_INACTIVE_BUTTON 8 +#define XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD 16 +#define XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD 32 +#define XTBL_TUI_DIALOG_PROGRESS_BAR 64 + +/* TUI dialog box maximum width */ +#define XTBL_TUI_MAX_DIALOG_WIDTH 100 + /* 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); diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 88360d2..3901af1 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -9,17 +9,6 @@ #include -/* TUI dialog box attributes */ -#define TUI_DIALOG_GENERIC_BOX 1 -#define TUI_DIALOG_ERROR_BOX 2 -#define TUI_DIALOG_ACTIVE_BUTTON 4 -#define TUI_DIALOG_INACTIVE_BUTTON 8 -#define TUI_DIALOG_ACTIVE_INPUT_FIELD 16 -#define TUI_DIALOG_INACTIVE_INPUT_FIELD 32 -#define TUI_DIALOG_PROGRESS_BAR 64 - -#define TUI_MAX_DIALOG_WIDTH 100 - /** * Displays a red error dialog box with the specified caption and message. * @@ -43,7 +32,7 @@ BlDisplayErrorDialog(IN PWCHAR Caption, UINT_PTR Index; /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_ERROR_BOX | TUI_DIALOG_ACTIVE_BUTTON; + Handle.Attributes = XTBL_TUI_DIALOG_ERROR_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ BlpDetermineDialogBoxSize(&Handle, Message); @@ -96,7 +85,7 @@ BlDisplayInfoDialog(IN PWCHAR Caption, UINT_PTR Index; /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_BUTTON; + Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ BlpDetermineDialogBoxSize(&Handle, Message); @@ -151,7 +140,7 @@ BlDisplayProgressDialog(IN PWCHAR Caption, XTBL_DIALOG_HANDLE Handle; /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_PROGRESS_BAR; + Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_PROGRESS_BAR; /* Determine dialog window size and position */ BlpDetermineDialogBoxSize(&Handle, Message); @@ -238,13 +227,13 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, /* Check enabled components that affect dialog window size */ switch(Attributes & Mask) { - case TUI_DIALOG_ACTIVE_BUTTON: - case TUI_DIALOG_INACTIVE_BUTTON: + case XTBL_TUI_DIALOG_ACTIVE_BUTTON: + case XTBL_TUI_DIALOG_INACTIVE_BUTTON: Height += 1; break; - case TUI_DIALOG_ACTIVE_INPUT_FIELD: - case TUI_DIALOG_INACTIVE_INPUT_FIELD: - case TUI_DIALOG_PROGRESS_BAR: + case XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD: + case XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD: + case XTBL_TUI_DIALOG_PROGRESS_BAR: Height += 2; break; } @@ -255,10 +244,10 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, } /* Check if input field is active */ - if(Handle->Attributes & (TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_INPUT_FIELD)) + if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD)) { /* Set maximum dialog window width to fit input field */ - Width = TUI_MAX_DIALOG_WIDTH; + Width = XTBL_TUI_MAX_DIALOG_WIDTH; } /* Get message length and count dialog window dimensions */ @@ -292,10 +281,10 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); /* Make sure dialog window fits in the buffer */ - if(Width > TUI_MAX_DIALOG_WIDTH) + if(Width > XTBL_TUI_MAX_DIALOG_WIDTH) { /* Set maximum dialog window width */ - Width = TUI_MAX_DIALOG_WIDTH; + Width = XTBL_TUI_MAX_DIALOG_WIDTH; } /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ @@ -341,12 +330,12 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Caption, IN PWCHAR Message) { - WCHAR BoxLine[TUI_MAX_DIALOG_WIDTH]; + WCHAR BoxLine[XTBL_TUI_MAX_DIALOG_WIDTH]; SIZE_T CaptionLength; UINT_PTR PosX, PosY; /* Set dialog colors */ - if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX) { /* Error dialog with red background and brown button */ Handle->DialogColor = EFI_TEXT_BGCOLOR_RED; @@ -457,10 +446,10 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) ULONG ButtonColor, TextColor; /* Set dialog button colors */ - if(Handle->Attributes & TUI_DIALOG_ACTIVE_BUTTON) + if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_BUTTON) { /* This is an active button */ - if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX) { /* This is an error dialog box */ ButtonColor = EFI_TEXT_BGCOLOR_BROWN; @@ -505,15 +494,15 @@ VOID BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR InputFieldText) { - WCHAR InputField[TUI_MAX_DIALOG_WIDTH]; + WCHAR InputField[XTBL_TUI_MAX_DIALOG_WIDTH]; ULONG InputColor, TextColor; UINT_PTR Index, Position; /* Set dialog button colors */ - if(Handle->Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { /* This is an active input field */ - if(Handle->Attributes & TUI_DIALOG_ERROR_BOX) + if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX) { /* This is an error dialog box */ InputColor = EFI_TEXT_BGCOLOR_BROWN; @@ -535,7 +524,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, /* Set progress bar color and position */ BlSetConsoleAttributes(InputColor | TextColor); - Position = (Handle->Attributes & (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; + Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw input field */ @@ -554,7 +543,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, BlConsoleWrite(InputFieldText); /* Check if this is an active input field */ - if(Handle->Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { /* Enable cursor for active input field */ BlEnableConsoleCursor(); @@ -633,7 +622,7 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, IN UCHAR Percentage) { UINT_PTR Index, ProgressLength, ProgressBarLength; - WCHAR ProgressBar[TUI_MAX_DIALOG_WIDTH]; + WCHAR ProgressBar[XTBL_TUI_MAX_DIALOG_WIDTH]; UINT_PTR Position; /* Determine progress bar length and calculate progress */ @@ -642,7 +631,7 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, /* Set progress bar color and position */ BlSetConsoleAttributes(EFI_TEXT_FGCOLOR_YELLOW); - Position = (Handle->Attributes & (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; + Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw progress bar */ @@ -687,7 +676,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, UINT_PTR Index; /* Set dialog window attributes */ - Handle.Attributes = TUI_DIALOG_GENERIC_BOX | TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_BUTTON; + Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_BUTTON; /* Determine dialog window size and position */ BlpDetermineDialogBoxSize(&Handle, Message); @@ -734,13 +723,13 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.UnicodeChar == 0x09) { /* TAB key pressed, toggle input field and button */ - Handle.Attributes ^= (TUI_DIALOG_ACTIVE_INPUT_FIELD | TUI_DIALOG_INACTIVE_INPUT_FIELD); - Handle.Attributes ^= (TUI_DIALOG_ACTIVE_BUTTON | TUI_DIALOG_INACTIVE_BUTTON); + Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD); + Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON); } else if(Key.ScanCode == 0x03) { /* RIGHT key pressed, move cursor forward */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition < InputFieldLength) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition < InputFieldLength) { TextPosition++; } @@ -748,7 +737,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x04) { /* LEFT key pressed, move cursor back */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition > 0) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition > 0) { TextPosition--; } @@ -756,7 +745,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x05) { /* HOME key pressed, move cursor to the beginning */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { TextPosition = 0; } @@ -764,7 +753,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x06) { /* END key pressed, move cursor to the end */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { TextPosition = InputFieldLength; } @@ -772,7 +761,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x08) { /* DELETE key pressed, delete character */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { if(InputFieldLength > 0 && TextPosition < InputFieldLength) { @@ -785,7 +774,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.UnicodeChar == 0x08) { /* BACKSPACE key pressed, delete character */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) { @@ -803,7 +792,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else { /* Other key pressed, add character to the buffer */ - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD && Key.UnicodeChar != 0) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && Key.UnicodeChar != 0) { if(InputFieldLength < Handle.Width - 8 - 1 && TextPosition < Handle.Width - 8 - 1) { @@ -831,7 +820,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlpDrawDialogButton(&Handle); BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); - if(Handle.Attributes & TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) { BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); } -- 2.45.1 From d8a260795ea705c262ba42294d26d3908078a40a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 16 Dec 2023 22:45:40 +0100 Subject: [PATCH 066/182] Always take a sizeof(WCHAR) into account when moving memory --- xtldr2/textui.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 3901af1..b1cc398 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -765,7 +765,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, { if(InputFieldLength > 0 && TextPosition < InputFieldLength) { - RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, InputFieldLength - TextPosition); + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR)); InputFieldLength--; InputFieldBuffer[InputFieldLength] = 0; } @@ -779,7 +779,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) { TextPosition--; - RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, InputFieldLength - TextPosition); + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR)); InputFieldLength--; InputFieldBuffer[InputFieldLength] = 0; } @@ -796,7 +796,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, { if(InputFieldLength < Handle.Width - 8 - 1 && TextPosition < Handle.Width - 8 - 1) { - RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, InputFieldLength - TextPosition); + RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR)); InputFieldBuffer[TextPosition] = Key.UnicodeChar; TextPosition++; InputFieldLength++; -- 2.45.1 From 6f0895689eab24c7edb0ba6443a18a47dbbef425 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 17 Dec 2023 11:53:08 +0100 Subject: [PATCH 067/182] Add XTLDR structures forward references --- sdk/xtdk/xtstruct.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index e60aa84..30f30dc 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -264,6 +264,11 @@ typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRM typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32; typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64; +typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; +typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; +typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; +typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS; +typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; /* Unions forward references */ typedef union _EFI_DEV_PATH EFI_DEV_PATH, *PEFI_DEV_PATH; -- 2.45.1 From e0932feac80a5b9f6d41343c14506fe410bbb881 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 17 Dec 2023 11:55:16 +0100 Subject: [PATCH 068/182] Import TUI into loader protocol --- sdk/xtdk/bltypes.h | 13 ++++++++++++- xtldr2/protocol.c | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 09e20c8..1feb9fd 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -42,7 +42,7 @@ /* TUI dialog box maximum width */ #define XTBL_TUI_MAX_DIALOG_WIDTH 100 -/* Loader protocol routine pointers */ +/* Boot 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 EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); @@ -65,6 +65,10 @@ typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, O typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); +typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); +typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); +typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage); +typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage); typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); /* XTLDR Configuration data */ @@ -143,6 +147,13 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_OPEN_XT_PROTOCOL Open; } Protocol; struct + { + PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog; + PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog; + PBL_TUI_DISPLAY_PROGRESS_DIALOG DisplayProgressDialog; + PBL_TUI_UPDATE_PROGRESS_BAR UpdateProgressBar; + } Tui; + struct { PBL_EXIT_BOOT_SERVICES ExitBootServices; PBL_GET_SECURE_BOOT_STATUS GetSecureBootStatus; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 2ac749a..b1ebd77 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -109,6 +109,10 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; LdrProtocol.Protocol.Open = BlOpenXtProtocol; + LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; + LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; + LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; + LdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; LdrProtocol.Util.ExitBootServices = BlExitBootServices; LdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; LdrProtocol.Util.SleepExecution = BlSleepExecution; -- 2.45.1 From a45b8c62db52ad1b33e5dc6de138cfdd667ed0d0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 17 Dec 2023 12:08:13 +0100 Subject: [PATCH 069/182] Rename some TUI definitions --- sdk/xtdk/bltypes.h | 4 ++-- xtldr2/textui.c | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 1feb9fd..838a298 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -35,8 +35,8 @@ #define XTBL_TUI_DIALOG_ERROR_BOX 2 #define XTBL_TUI_DIALOG_ACTIVE_BUTTON 4 #define XTBL_TUI_DIALOG_INACTIVE_BUTTON 8 -#define XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD 16 -#define XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD 32 +#define XTBL_TUI_DIALOG_ACTIVE_INPUT 16 +#define XTBL_TUI_DIALOG_INACTIVE_INPUT 32 #define XTBL_TUI_DIALOG_PROGRESS_BAR 64 /* TUI dialog box maximum width */ diff --git a/xtldr2/textui.c b/xtldr2/textui.c index b1cc398..1db83db 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -231,8 +231,8 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, case XTBL_TUI_DIALOG_INACTIVE_BUTTON: Height += 1; break; - case XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD: - case XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD: + case XTBL_TUI_DIALOG_ACTIVE_INPUT: + case XTBL_TUI_DIALOG_INACTIVE_INPUT: case XTBL_TUI_DIALOG_PROGRESS_BAR: Height += 2; break; @@ -244,7 +244,7 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, } /* Check if input field is active */ - if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD)) + if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT)) { /* Set maximum dialog window width to fit input field */ Width = XTBL_TUI_MAX_DIALOG_WIDTH; @@ -499,7 +499,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, UINT_PTR Index, Position; /* Set dialog button colors */ - if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { /* This is an active input field */ if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX) @@ -543,7 +543,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, BlConsoleWrite(InputFieldText); /* Check if this is an active input field */ - if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { /* Enable cursor for active input field */ BlEnableConsoleCursor(); @@ -676,7 +676,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, UINT_PTR Index; /* Set dialog window attributes */ - Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_BUTTON; + Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON; /* Determine dialog window size and position */ BlpDetermineDialogBoxSize(&Handle, Message); @@ -723,13 +723,13 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.UnicodeChar == 0x09) { /* TAB key pressed, toggle input field and button */ - Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD | XTBL_TUI_DIALOG_INACTIVE_INPUT_FIELD); + Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT); Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON); } else if(Key.ScanCode == 0x03) { /* RIGHT key pressed, move cursor forward */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition < InputFieldLength) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength) { TextPosition++; } @@ -737,7 +737,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x04) { /* LEFT key pressed, move cursor back */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && TextPosition > 0) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0) { TextPosition--; } @@ -745,7 +745,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x05) { /* HOME key pressed, move cursor to the beginning */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { TextPosition = 0; } @@ -753,7 +753,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x06) { /* END key pressed, move cursor to the end */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { TextPosition = InputFieldLength; } @@ -761,7 +761,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.ScanCode == 0x08) { /* DELETE key pressed, delete character */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { if(InputFieldLength > 0 && TextPosition < InputFieldLength) { @@ -774,7 +774,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else if(Key.UnicodeChar == 0x08) { /* BACKSPACE key pressed, delete character */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) { @@ -792,7 +792,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, else { /* Other key pressed, add character to the buffer */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD && Key.UnicodeChar != 0) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) { if(InputFieldLength < Handle.Width - 8 - 1 && TextPosition < Handle.Width - 8 - 1) { @@ -820,7 +820,7 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlpDrawDialogButton(&Handle); BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT_FIELD) + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); } -- 2.45.1 From ceee294df7b32b524fe766b37c362db2847a7bdc Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 17 Dec 2023 16:41:54 +0100 Subject: [PATCH 070/182] Update XTLDR API --- sdk/xtdk/bltypes.h | 2 +- xtldr2/protocol.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 838a298..5574831 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -144,7 +144,7 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { - PBL_OPEN_XT_PROTOCOL Open; + PBL_OPEN_XT_PROTOCOL OpenProtocol; } Protocol; struct { diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index b1ebd77..f17349d 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -108,7 +108,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; - LdrProtocol.Protocol.Open = BlOpenXtProtocol; + LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; -- 2.45.1 From c2d40e30115a79df73cac4e7c09969d26c3c6433 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 17 Dec 2023 23:45:01 +0100 Subject: [PATCH 071/182] Do not print caption, nor message on the dialog box if not needed --- xtldr2/textui.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 1db83db..7fbf35d 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -341,16 +341,13 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, Handle->DialogColor = EFI_TEXT_BGCOLOR_RED; Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE; } - else + else if(Handle->Attributes & XTBL_TUI_DIALOG_GENERIC_BOX) { /* Generic dialog with blue background and cyan button */ Handle->DialogColor = EFI_TEXT_BGCOLOR_BLUE; Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE; } - /* Get caption length */ - CaptionLength = RtlWideStringLength(Caption, 0); - /* Set dialog box colors */ BlSetConsoleAttributes(Handle->DialogColor | 0x0F); @@ -365,16 +362,30 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, { /* Draw top line of the dialog box, starting from the left corner */ BoxLine[0] = EFI_TEXT_BOX_DOWN_RIGHT; - BoxLine[1] = EFI_TEXT_BOX_VERTICAL_LEFT; - /* Fill caption area with spaces */ - for(PosX = 2; PosX < CaptionLength + 4; PosX++) + /* Check if there is a caption for this dialog */ + if(Caption != NULL) { - BoxLine[PosX] = ' '; - } + /* Get caption length */ + CaptionLength = RtlWideStringLength(Caption, 0); - /* End caption area with vertical line */ - BoxLine[CaptionLength + 4] = EFI_TEXT_BOX_VERTICAL_RIGHT; + /* Start caption area with vertical line */ + BoxLine[1] = EFI_TEXT_BOX_VERTICAL_LEFT; + + /* Fill caption area with spaces */ + for(PosX = 2; PosX < CaptionLength + 4; PosX++) + { + BoxLine[PosX] = ' '; + } + + /* End caption area with vertical line */ + BoxLine[CaptionLength + 4] = EFI_TEXT_BOX_VERTICAL_RIGHT; + } + else + { + /* No caption, -4 because of left and right vertical lines and corresponding spaces */ + CaptionLength = -4; + } /* Draw bottom line */ for(PosX = CaptionLength + 5; PosX < Handle->Width - 1; PosX++) @@ -421,12 +432,20 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BlConsoleWrite(BoxLine); } + /* Make sure there is a caption to print */ + if(Caption != NULL) + { /* Write dialog box caption */ - BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); - BlConsolePrint(L"%S", Caption); + BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); + BlConsolePrint(L"%S", Caption); + } - /* Write a message on the dialog box */ - BlpDrawDialogMessage(Handle, Message); + /* Make sure there is a message to print */ + if(Message != NULL) + { + /* Write a message on the dialog box */ + BlpDrawDialogMessage(Handle, Message); + } } /** -- 2.45.1 From fbcf952dadad0492a087067166f1caaee5c2b0ef Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 18:49:49 +0100 Subject: [PATCH 072/182] Remove leading and trialing quotes from config values --- xtldr2/config.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xtldr2/config.c b/xtldr2/config.c index dfc0c7b..0f5243f 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -451,6 +451,18 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, return Status; } + /* Remove leading quotes from the value */ + if(*Value == '"' || *Value == '\'') + { + Value++; + } + + /* Remove trailing quotes from the value */ + if(Value[ValueLength - 2] == '"' || Value[ValueLength - 2] == '\'') + { + Value[ValueLength - 2] = 0; + } + /* Initialize new option and add it to the list */ RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1); RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1); -- 2.45.1 From ebf95ba90a03025b00349f40e270635f1c3fe7f8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 23:21:31 +0100 Subject: [PATCH 073/182] Remove unused, commented out variable --- xtldr2/config.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 0f5243f..28d9927 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -114,7 +114,6 @@ EFI_STATUS BlpLoadConfiguration() { PLIST_ENTRY SectionListEntry; - // STATIC LIST_ENTRY BlpConfiguration; EFI_STATUS Status; PCHAR ConfigData; -- 2.45.1 From 6983b2eeacf3973e75e81eb1369dcc832a91b3e9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 23:22:54 +0100 Subject: [PATCH 074/182] Make a use of TUI dialogs to inform user about errors --- xtldr2/xtldr.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 06d5096..1ea99b4 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -42,8 +42,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse command line options */ - BlConsolePrint(L"ERROR: Failed to parse command line options\n"); - BlSleepExecution(3000); + BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); } /* Attempt to early initialize debug console */ @@ -53,8 +52,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Initialization failed, notify user on stdout */ - BlConsolePrint(L"ERROR: Failed to initialize debug console\n"); - BlSleepExecution(3000); + BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); } } @@ -63,8 +61,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to load/parse config file */ - BlConsolePrint(L"ERROR: Failed to load configuration file\n"); - BlSleepExecution(3000); + BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file."); } /* Reinitialize debug console if it was not initialized earlier */ @@ -74,8 +71,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Initialization failed, notify user on stdout */ - BlConsolePrint(L"ERROR: Failed to initialize debug console\n"); - BlSleepExecution(3000); + BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); } } @@ -92,7 +88,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to register loader protocol */ - BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol\n"); + BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol\n"); } /* Discover and enumerate EFI block devices */ @@ -103,9 +99,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); } - /* Temporary infinite loop */ - for(;;); - /* This point should be never reached, if this happen return error code */ return STATUS_EFI_LOAD_ERROR; } -- 2.45.1 From a7781c4b0bc7d05c6e41618db2245dd08c2bcd4d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 23:27:49 +0100 Subject: [PATCH 075/182] Implement BlInitializeBootMenuList() --- sdk/xtdk/bltypes.h | 25 +++++++---- sdk/xtdk/xtstruct.h | 1 + xtldr2/includes/bootman.h | 6 +++ xtldr2/protocol.c | 1 + xtldr2/xtldr.c | 87 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 8 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 5574831..f28f763 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -45,6 +45,7 @@ /* Boot 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_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); @@ -71,6 +72,13 @@ typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage); typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); +/* Boot menu list structure */ +typedef struct _XTBL_BOOTMENU_ITEM +{ + PWCHAR EntryName; + PLIST_ENTRY Options; +} XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; + /* XTLDR Configuration data */ typedef struct _XTBL_CONFIG_ENTRY { @@ -101,14 +109,6 @@ typedef struct _XTBL_DIALOG_HANDLE UINT_PTR Height; } XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; -/* XTLDR Status data */ -typedef struct _XTBL_STATUS -{ - BOOLEAN BootServices; - ULONG DebugPort; - CPPORT SerialPort; -} XTBL_STATUS, *PXTBL_STATUS; - /* XTLDR Loader protocol */ typedef struct _XTBL_LOADER_PROTOCOL { @@ -144,6 +144,7 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { + PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeBootMenuList; PBL_OPEN_XT_PROTOCOL OpenProtocol; } Protocol; struct @@ -162,4 +163,12 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; +/* XTLDR Status data */ +typedef struct _XTBL_STATUS +{ + BOOLEAN BootServices; + ULONG DebugPort; + CPPORT SerialPort; +} XTBL_STATUS, *PXTBL_STATUS; + #endif /* __XTDK_BLTYPES_H */ diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index 30f30dc..b005bfd 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -264,6 +264,7 @@ typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRM typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32; typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64; +typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 6e727bc..b1173d8 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -91,6 +91,12 @@ BlGetVolumeDevicePath(IN PCHAR SystemPath, OUT PCHAR *ArcName, OUT PCHAR *Path); +XTCDECL +VOID +BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index f17349d..e7f133e 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -109,6 +109,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; + LdrProtocol.Protocol.InitializeBootMenuList = BlInitializeBootMenuList; LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 1ea99b4..3bb9bf6 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,6 +9,93 @@ #include +/** + * Initializes a list of operating systems for XTLDR boot menu. + * + * @param MenuEntries + * Supplies a pointer to memory area where operating systems list will be stored. + * + * @param EntriesCount + * Supplies a pointer to memory area where number of menu entries will be stored. + * + * @param DefaultId + * Supplies a pointer to memory area where ID of default menu entry will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId) +{ + PWCHAR DefaultMenuEntry, MenuEntryName; + PLIST_ENTRY MenuEntrySectionList, MenuEntryList; + PXTBL_CONFIG_SECTION MenuEntrySection; + PXTBL_CONFIG_ENTRY MenuEntryOption; + PXTBL_BOOTMENU_ITEM OsList; + ULONG DefaultOS, NumberOfEntries; + + /* Set default values */ + DefaultOS = 0; + NumberOfEntries = 0; + OsList = NULL; + + /* Get default menu entry from configuration */ + DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); + + /* Iterate through all menu sections */ + MenuEntrySectionList = BlpMenuList->Flink; + while(MenuEntrySectionList != BlpMenuList) + { + /* NULLify menu entry name */ + MenuEntryName = NULL; + + /* Get menu section */ + MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); + + /* Check if this is the default menu entry */ + if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0) + { + /* Set default OS ID */ + DefaultOS = NumberOfEntries; + } + + /* Iterate through all entry parameters */ + MenuEntryList = MenuEntrySection->Options.Flink; + while(MenuEntryList != &MenuEntrySection->Options) + { + /* Get menu entry parameter */ + MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); + + /* Check if this is the menu entry display name */ + if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) + { + /* Set menu entry display name */ + MenuEntryName = MenuEntryOption->Value; + } + + /* Get next parameter for this menu entry */ + MenuEntryList = MenuEntryList->Flink; + } + + /* Add OS to the boot menu list */ + OsList[NumberOfEntries].EntryName = MenuEntryName; + OsList[NumberOfEntries].Options = &MenuEntrySection->Options; + + /* Get next menu entry */ + MenuEntrySectionList = MenuEntrySectionList->Flink; + NumberOfEntries++; + } + + /* Set return values */ + *DefaultId = DefaultOS; + *EntriesCount = NumberOfEntries; + MenuEntries = OsList; +} + /** * This routine is the entry point of the XT EFI boot loader. * -- 2.45.1 From 019fdab193a0f2d9037eccf4c681dc9c11c77db7 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 23:35:36 +0100 Subject: [PATCH 076/182] Implement boot menu skeleton --- xtldr2/includes/bootman.h | 11 ++++ xtldr2/textui.c | 111 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index b1173d8..c08f963 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -216,6 +216,17 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, OUT PULONG DriveNumber, OUT PULONG PartNumber); +XTCDECL +VOID +BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle); + +XTCDECL +VOID +BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted); + XTCDECL VOID BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 7fbf35d..a1aa660 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -308,6 +308,117 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, Handle->Height = Height; } +/** + * Draws a text UI-based boot menu. + * + * @param Handle + * Supplies a pointer to the boot menu handle. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) +{ + /* Query console screen resolution */ + BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); + + /* Set boot menu parameters */ + Handle->Attributes = 0; + Handle->DialogColor = EFI_TEXT_BGCOLOR_BLACK; + Handle->TextColor = EFI_TEXT_FGCOLOR_LIGHTGRAY; + Handle->PosX = 3; + Handle->PosY = 3; + Handle->Width = Handle->ResX - 6; + Handle->Height = Handle->ResY - 10; + + /* Clear screen and disable cursor */ + BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); + BlClearConsoleScreen(); + BlDisableConsoleCursor(); + + /* Check if debugging enabled */ + if(DEBUG) + { + /* Print debug version of XTLDR banner */ + BlSetCursorPosition((Handle->ResX - 44) / 2, 1); + BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", + XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH); + } + else + { + /* Print standard XTLDR banner */ + BlSetCursorPosition((Handle->ResX - 22) / 2, 1); + BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); + } + + /* Draw empty dialog box for boot menu */ + BlpDrawDialogBox(Handle, NULL, NULL); + + /* Print help message below the boot menu */ + BlSetCursorPosition(0, Handle->PosY + Handle->Height); + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" + " Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\n" + " Additional help available after pressing F1 key."); +} + +/** + * Draws boot menu entry at the specified position. + * + * @param Handle + * Supplies a pointer to the boot menu handle. + * + * @param MenuEntry + * Supplies a pointer to the buffer containing a menu entry name. + * + * @param Position + * Specifies entry position on the list in the boot menu. + * + * @param Highlighted + * Specifies whether this entry should be highlighted or not. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted) +{ + UINT Index; + + /* Check whether this entry should be highlighted */ + if(Highlighted) + { + /* Highlight this entry */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); + } + else + { + /* Set default colors */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + } + + /* Move cursor to the right position */ + BlSetCursorPosition(5, 4 + Position); + + /* Clear menu entry */ + for(Index = 0; Index < Handle->Width - 4; Index++) + { + BlConsolePrint(L" "); + } + + /* Print menu entry */ + BlSetCursorPosition(5, 4 + Position); + BlConsolePrint(L"%S\n", MenuEntry); +} + /** * Draws dialog box with caption and message. * -- 2.45.1 From edcce638be296361c3a0bf1e6d3ed6913c322d1e Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 18 Dec 2023 23:37:06 +0100 Subject: [PATCH 077/182] Add separate definitions for XTLDR version --- sdk/cmake/version.cmake | 4 ++++ sdk/cmake/version/xtver.h.cmake | 3 +++ 2 files changed, 7 insertions(+) diff --git a/sdk/cmake/version.cmake b/sdk/cmake/version.cmake index 141814a..9d57776 100644 --- a/sdk/cmake/version.cmake +++ b/sdk/cmake/version.cmake @@ -9,6 +9,10 @@ set(XTOS_COMPATIBLE_MINOR "3") set(XTOS_COMPATIBLE_VERSION "0x0603") set(XTOS_COMPATIBLE_BUILD "9600") +# Set XTLDR version +set(XTLDR_VERSION_MAJOR "0") +set(XTLDR_VERSION_MINOR "1") + # Set common XTOS version variables string(TIMESTAMP XTOS_VERSION_YEAR %Y) string(TIMESTAMP XTOS_VERSION_DATE "%Y%m%d") diff --git a/sdk/cmake/version/xtver.h.cmake b/sdk/cmake/version/xtver.h.cmake index 3172604..1e34126 100644 --- a/sdk/cmake/version/xtver.h.cmake +++ b/sdk/cmake/version/xtver.h.cmake @@ -29,4 +29,7 @@ #define XTOS_COMPILER_NAME "@CMAKE_C_COMPILER_ID@" #define XTOS_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@" +#define XTLDR_VERSION_MAJOR @XTLDR_VERSION_MAJOR@ +#define XTLDR_VERSION_MINOR @XTLDR_VERSION_MINOR@ + #endif /* __XTGEN_XTVER_H */ -- 2.45.1 From a7c345a9b2c603598705b53d7297cf3156f5b583 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 19 Dec 2023 19:50:14 +0100 Subject: [PATCH 078/182] Semi-functional code for displaying boot menu --- xtldr2/textui.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++ xtldr2/xtldr.c | 10 +++ 2 files changed, 199 insertions(+) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index a1aa660..f55ed93 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -960,3 +960,192 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); BlClearConsoleScreen(); } + + + + + + +XTCDECL +VOID +BlDisplayBootMenu() +{ + XTBL_DIALOG_HANDLE Handle; + PXTBL_BOOTMENU_ITEM MenuEntries = NULL; + ULONG Index, NumberOfEntries, HighligtedEntryId; + UINT_PTR EventIndex; + EFI_EVENT Events[2]; + EFI_INPUT_KEY Key; + EFI_EVENT TimerEvent; + EFI_STATUS Status; + LONG TimeOut; + PWCHAR TimeOutString; + + /* Initialize boot menu list */ + BlInitializeBootMenuList(MenuEntries, &NumberOfEntries, &HighligtedEntryId); + + /* Get timeout from the configuration */ + TimeOutString = NULL; //BlGetConfigValue(L"TIMEOUT"); + TimeOut = -1; + + /* Check if timeout is specified */ + if(TimeOutString != NULL) + { + /* Convert timeout string to number */ + TimeOut = 0; + while(*TimeOutString >= '0' && *TimeOutString <= '9') + { + TimeOut *= 10; + TimeOut += *TimeOutString - '0'; + TimeOutString++; + } + } + + /* Infinite boot menu loop */ + while(TRUE) + { + /* Draw boot menu */ + BlpDrawBootMenu(&Handle); + + /* Check if there is anything to show in the boot menu */ + if(NumberOfEntries > 0) { + /* Iterate through all menu entries */ + for(Index = 0; Index < NumberOfEntries; Index++) + { + /* Draw menu entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[Index].EntryName, Index, Index == HighligtedEntryId); + } + } + else + { + /* No menu entries found, show error message */ + BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); + + /* Exit into XTLDR shell */ + return; + } + + /* Create a timer event for controlling the timeout of the boot menu */ + Status = EfiSystemTable->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, NULL, NULL, &TimerEvent); + if(Status == STATUS_EFI_SUCCESS) + { + /* Setup new EFI timer */ + Status = EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000); + } + + /* Check is EFI timer was successfully created */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Timer creation failed, disable the timer */ + TimeOut = -1; + } + + /* Initialize EFI events */ + Events[0] = EfiSystemTable->ConIn->WaitForKey; + Events[1] = TimerEvent; + + /* Infinite boot menu event loop */ + while(TRUE) + { + /* Wait for EFI event */ + BlWaitForEfiEvent(2, Events, &EventIndex); + + /* Check which event was received */ + if(EventIndex == 0) + { + /* Key pressed, check if timer is still active */ + if(TimeOut != -1) + { + /* Disable the timer */ + TimeOut = -1; + + /* Cancel timer event */ + EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); + + /* Remove the timer message */ + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L" ", TimeOut); + } + + /* Read key stroke */ + BlReadKeyStroke(&Key); + + if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) + { + /* ENTER or RightArrow key pressed, boot the highlighted OS */ + BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ..."); + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.ScanCode == 0x01) + { + /* UpArrow key pressed, go to previous entry if possible */ + if(HighligtedEntryId > 0) + { + /* Highlight previous entry */ + HighligtedEntryId--; + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, HighligtedEntryId + 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE); + } + } + else if(Key.ScanCode == 0x02) + { + /* DownArrow key pressed, go to next entry if possible */ + if(HighligtedEntryId < NumberOfEntries - 1) + { + /* Highlight next entry */ + HighligtedEntryId++; + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, HighligtedEntryId - 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE); + } + } + else if(Key.ScanCode == 0x0B) + { + /* F1 key pressed, show help */ + BlDisplayInfoDialog(L"XTLDR", L"XTLDR Boot Loader Help"); + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.UnicodeChar == 0x65) + { + /* 'e' key pressed, edit the highlighted entry */ + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.UnicodeChar == 0x73) + { + /* 's' key pressed, exit into XTLDR shell */ + return; + } + } + else + { + /* Timer tick, check if time out expired */ + if(TimeOut > 0) + { + /* Update a message and decrease timeout value */ + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds. ", TimeOut); + TimeOut--; + } + else if(TimeOut == 0) + { + /* Time out expired, update a message */ + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"Booting '%S' now... ", + MenuEntries[HighligtedEntryId].EntryName); + + /* Disable the timer just in case booting OS fails */ + TimeOut = -1; + + /* Boot the highlighted (default) OS */ + BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ..."); + break; + } + } + } + } +} diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 3bb9bf6..0be8f71 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,6 +9,10 @@ #include +XTCDECL +VOID +BlDisplayBootMenu(); + /** * Initializes a list of operating systems for XTLDR boot menu. * @@ -186,6 +190,12 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); } + for(;;) + { + /* Display boot menu */ + BlDisplayBootMenu(); + } + /* This point should be never reached, if this happen return error code */ return STATUS_EFI_LOAD_ERROR; } -- 2.45.1 From 093ef010c84f465efd36ae0b410c6ba1d5ff1c83 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 20 Dec 2023 15:54:11 +0100 Subject: [PATCH 079/182] Add more debugging --- xtldr2/efiutils.c | 26 ++++++++++++++++++++++++++ xtldr2/xtldr.c | 3 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 28bdf7f..d6124f3 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -130,9 +130,35 @@ XTCDECL VOID BlpInitializeEfiBootLoader() { + EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + EFI_STATUS Status; + /* Set current XTLDR status */ BlpStatus.BootServices = TRUE; /* Initialize console */ BlpInitializeConsole(); + + /* Print XTLDR version */ + BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + + /* Check if debug is enabled */ + if(DEBUG) + { + Status = BlOpenXtProtocol((PVOID *)&LoadedImage, &LipGuid); + + /* Print useful debug information */ + BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" + L"Pointer Size : %d\n" + L"Image Base Address: 0x%lx\n" + L"Image Base Size : 0x%lx\n" + L"Image Revision : 0x%lx\n" + L"--------------------------------------\n", + sizeof(PVOID), + LoadedImage->ImageBase, + LoadedImage->ImageSize, + LoadedImage->Revision); + BlSleepExecution(5000); + } } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 0be8f71..956b4eb 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -124,9 +124,8 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; - /* Initialize XTLDR and early print XTLDR version */ + /* Initialize XTLDR and */ BlpInitializeEfiBootLoader(); - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse configuration options passed from UEFI shell */ Status = BlpParseCommandLine(); -- 2.45.1 From 782e6e3987be6d579ba7d28dadd9f358fd47d773 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 21 Dec 2023 20:02:02 +0100 Subject: [PATCH 080/182] Make sure config list is not empty before trying to access it --- xtldr2/config.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 28d9927..7a34cf1 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -30,22 +30,26 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName) /* Get config entry name length */ Length = RtlWideStringLength(ConfigName, 0); - /* Iterate through config entries */ - ConfigListEntry = BlpConfig->Flink; - while(ConfigListEntry != BlpConfig) + /* Make sure config list is not empty */ + if(BlpConfig != NULL) { - /* Get config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Check if requested configuration found */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + /* Iterate through config entries */ + ConfigListEntry = BlpConfig->Flink; + while(ConfigListEntry != BlpConfig) { - /* Return config value */ - return ConfigEntry->Value; - } + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - /* Move to the next config entry */ - ConfigListEntry = ConfigListEntry->Flink; + /* Check if requested configuration found */ + if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + { + /* Return config value */ + return ConfigEntry->Value; + } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; + } } /* Config entry not found, return NULL */ -- 2.45.1 From 5ee6377080d9740d9fa74f4bff398c988865e2be Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 21 Dec 2023 22:57:11 +0100 Subject: [PATCH 081/182] Implement BlSetConsoleMode() and forcibly set mode to 80x25 to avoid offscreen --- xtldr2/console.c | 25 +++++++++++++++++++++++++ xtldr2/includes/bootman.h | 22 +++++++++++++--------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/xtldr2/console.c b/xtldr2/console.c index 1e7a277..0703d8a 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -179,6 +179,23 @@ BlSetConsoleAttributes(IN ULONGLONG Attributes) EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); } +/** + * Sets the output console device to the requested mode. + * + * @param Mode + * Supplies a text mode number to set. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlSetConsoleMode(IN ULONGLONG Mode) +{ + return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode); +} + /** * Sets new coordinates of the console cursor position. * @@ -238,6 +255,14 @@ BlpInitializeConsole() EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might + * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ + if(EfiSystemTable->ConOut->Mode->Mode != 0) + { + /* Set console mode to 0, which is standard, 80x25 text mode */ + BlSetConsoleMode(0); + } + /* Clear screen and enable cursor */ BlClearConsoleScreen(); BlEnableConsoleCursor(); diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index c08f963..e81566a 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -107,6 +107,15 @@ EFI_STATUS BlMemoryAllocatePool(IN UINT_PTR Size, OUT PVOID *Memory); +XTCDECL +EFI_STATUS +BlMemoryFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory); + +XTCDECL +EFI_STATUS +BlMemoryFreePool(IN PVOID Memory); + XTCDECL EFI_STATUS BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, @@ -133,15 +142,6 @@ XTCDECL VOID BlResetConsoleInputBuffer(); -XTCDECL -EFI_STATUS -BlMemoryFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlMemoryFreePool(IN PVOID Memory); - XTCDECL EFI_STATUS BlOpenXtProtocol(OUT PVOID *ProtocolHandler, @@ -156,6 +156,10 @@ XTCDECL VOID BlSetConsoleAttributes(IN ULONGLONG Attributes); +XTCDECL +EFI_STATUS +BlSetConsoleMode(IN ULONGLONG Mode); + XTCDECL VOID BlSetCursorPosition(IN ULONGLONG PosX, -- 2.45.1 From 16a2565ad94a7b5fb7da96cac8470c2534b06233 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 22 Dec 2023 12:15:24 +0100 Subject: [PATCH 082/182] Get timeout value from configuration --- xtldr2/textui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index f55ed93..eccfa32 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -985,7 +985,7 @@ BlDisplayBootMenu() BlInitializeBootMenuList(MenuEntries, &NumberOfEntries, &HighligtedEntryId); /* Get timeout from the configuration */ - TimeOutString = NULL; //BlGetConfigValue(L"TIMEOUT"); + TimeOutString = BlGetConfigValue(L"TIMEOUT"); TimeOut = -1; /* Check if timeout is specified */ -- 2.45.1 From 32042ef643bca462fdfd516509e0334c94d51fc8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 22 Dec 2023 22:37:33 +0100 Subject: [PATCH 083/182] Initialize XTLDR configuration list and check if EFI LoadedImage protocol opened successfully --- xtldr2/config.c | 2 +- xtldr2/efiutils.c | 32 +++++++++++++++++++------------- xtldr2/globals.c | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index 7a34cf1..c6c8958 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -564,7 +564,7 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) /* Make sure config entry does not exist yet */ if(BlGetConfigValue(ConfigEntry->Name) == NULL) { - /* Remove new config entry from input list and put it into global config list */ + /* Put new config entry into global config list */ RtlInsertTailList(BlpConfig, &ConfigEntry->Flink); } diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index d6124f3..c61b606 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -143,22 +143,28 @@ BlpInitializeEfiBootLoader() /* Print XTLDR version */ BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + /* Initialize XTLDR configuration list */ + RtlInitializeListHead(BlpConfig); + /* Check if debug is enabled */ if(DEBUG) { + /* Attempt to open EFI LoadedImage protocol */ Status = BlOpenXtProtocol((PVOID *)&LoadedImage, &LipGuid); - - /* Print useful debug information */ - BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" - L"Pointer Size : %d\n" - L"Image Base Address: 0x%lx\n" - L"Image Base Size : 0x%lx\n" - L"Image Revision : 0x%lx\n" - L"--------------------------------------\n", - sizeof(PVOID), - LoadedImage->ImageBase, - LoadedImage->ImageSize, - LoadedImage->Revision); - BlSleepExecution(5000); + if(Status == STATUS_EFI_SUCCESS) + { + /* Protocol opened successfully, print useful debug information */ + BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" + L"Pointer Size : %d\n" + L"Image Base Address: 0x%lx\n" + L"Image Base Size : 0x%lx\n" + L"Image Revision : 0x%lx\n" + L"--------------------------------------\n", + sizeof(PVOID), + LoadedImage->ImageBase, + LoadedImage->ImageSize, + LoadedImage->Revision); + BlSleepExecution(3000); + } } } diff --git a/xtldr2/globals.c b/xtldr2/globals.c index bbcc200..7292295 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -10,7 +10,7 @@ /* XT Boot Loader configuration list */ -PLIST_ENTRY BlpConfig = NULL; +PLIST_ENTRY BlpConfig; /* XT Boot Loader loaded configuration */ LIST_ENTRY BlpConfigSections; -- 2.45.1 From 113a46ef102371b3e02ee28df32d20ac65188c4c Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 22 Dec 2023 23:36:09 +0100 Subject: [PATCH 084/182] Fix XTLDR configuration --- xtldr2/config.c | 39 ++++++++++++++++++--------------------- xtldr2/efiutils.c | 2 +- xtldr2/globals.c | 2 +- xtldr2/includes/globals.h | 2 +- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index c6c8958..b03c91a 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -30,26 +30,22 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName) /* Get config entry name length */ Length = RtlWideStringLength(ConfigName, 0); - /* Make sure config list is not empty */ - if(BlpConfig != NULL) + /* Iterate through config entries */ + ConfigListEntry = BlpConfig.Flink; + while(ConfigListEntry != &BlpConfig) { - /* Iterate through config entries */ - ConfigListEntry = BlpConfig->Flink; - while(ConfigListEntry != BlpConfig) + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Check if requested configuration found */ + if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) { - /* Get config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Check if requested configuration found */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) - { - /* Return config value */ - return ConfigEntry->Value; - } - - /* Move to the next config entry */ - ConfigListEntry = ConfigListEntry->Flink; + /* Return config value */ + return ConfigEntry->Value; } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; } /* Config entry not found, return NULL */ @@ -82,8 +78,8 @@ BlSetConfigValue(IN CONST PWCHAR ConfigName, Length = RtlWideStringLength(ConfigName, 0); /* Iterate through config entries */ - ConfigListEntry = BlpConfig->Flink; - while(ConfigListEntry != BlpConfig) + ConfigListEntry = BlpConfig.Flink; + while(ConfigListEntry != &BlpConfig) { /* Get config entry */ ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); @@ -564,8 +560,9 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) /* Make sure config entry does not exist yet */ if(BlGetConfigValue(ConfigEntry->Name) == NULL) { - /* Put new config entry into global config list */ - RtlInsertTailList(BlpConfig, &ConfigEntry->Flink); + /* Remove new config entry from input list and put it into global config list */ + RtlRemoveEntryList(&ConfigEntry->Flink); + RtlInsertTailList(&BlpConfig, &ConfigEntry->Flink); } /* Move to the next new config entry */ diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index c61b606..411cdcb 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -144,7 +144,7 @@ BlpInitializeEfiBootLoader() BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Initialize XTLDR configuration list */ - RtlInitializeListHead(BlpConfig); + RtlInitializeListHead(&BlpConfig); /* Check if debug is enabled */ if(DEBUG) diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 7292295..4b2a3b9 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -10,7 +10,7 @@ /* XT Boot Loader configuration list */ -PLIST_ENTRY BlpConfig; +LIST_ENTRY BlpConfig; /* XT Boot Loader loaded configuration */ LIST_ENTRY BlpConfigSections; diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index b913e9e..dcdc804 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -13,7 +13,7 @@ /* XT Boot Loader configuration list */ -EXTERN PLIST_ENTRY BlpConfig; +EXTERN LIST_ENTRY BlpConfig; /* XT Boot Loader loaded configuration */ EXTERN LIST_ENTRY BlpConfigSections; -- 2.45.1 From ec861c629691b5ca37fa05473c6ef4121fec7f1d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 09:45:11 +0100 Subject: [PATCH 085/182] Add ability to jump between first and last menu entry with PageUp/PageDown keys --- xtldr2/textui.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index eccfa32..fa2fb93 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1100,6 +1100,28 @@ BlDisplayBootMenu() BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE); } } + else if(Key.ScanCode == 0x09) + { + /* PageUp key pressed, go to top entry */ + if(HighligtedEntryId != 0) + { + /* Highlight first entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[0].EntryName, 0, TRUE); + HighligtedEntryId = 0; + } + } + else if(Key.ScanCode == 0x0A) + { + /* PageDown key pressed, go to bottom entry */ + if(HighligtedEntryId != NumberOfEntries - 1) + { + /* Highlight last entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName, NumberOfEntries - 1, TRUE); + HighligtedEntryId = NumberOfEntries - 1; + } + } else if(Key.ScanCode == 0x0B) { /* F1 key pressed, show help */ @@ -1111,6 +1133,7 @@ BlDisplayBootMenu() else if(Key.UnicodeChar == 0x65) { /* 'e' key pressed, edit the highlighted entry */ + BlDisplayErrorDialog(L"XTLDR", L"Editing boot menu entries is not implemented yet!"); /* Break from boot menu event loop to redraw whole boot menu */ break; -- 2.45.1 From 10aaf7e24e94ed2533c57433506a13258bb91aa8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 10:01:28 +0100 Subject: [PATCH 086/182] Implement BlClearConsoleLine() routine --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/console.c | 28 ++++++++++++++++++++++++++++ xtldr2/includes/bootman.h | 4 ++++ xtldr2/protocol.c | 1 + 4 files changed, 35 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index f28f763..7cdf24a 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -47,6 +47,7 @@ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRE typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); +typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); @@ -114,6 +115,7 @@ typedef struct _XTBL_LOADER_PROTOCOL { struct { + PBL_CLEAR_CONSOLE_LINE ClearLine; PBL_CONSOLE_CLEAR_SCREEN ClearScreen; PBL_CONSOLE_DISABLE_CURSOR DisableCursor; PBL_CONSOLE_ENABLE_CURSOR EnableCursor; diff --git a/xtldr2/console.c b/xtldr2/console.c index 0703d8a..e41b8ce 100644 --- a/xtldr2/console.c +++ b/xtldr2/console.c @@ -9,6 +9,34 @@ #include +/** + * Clears a specified line on the UEFI text console. + * + * @param LineNo + * Supplies a line number to clear. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlClearConsoleLine(IN ULONGLONG LineNo) +{ + UINT_PTR Index, ResX, ResY; + + /* Query console mode */ + BlQueryConsoleMode(&ResX, &ResY); + + /* Set cursor position and clear line */ + BlSetCursorPosition(0, LineNo); + for(Index = 0; Index < ResX; Index++) + { + /* Clear line */ + BlConsoleWrite(L" "); + } +} + /** * This routine clears the UEFI console screen. * diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index e81566a..6655df5 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -16,6 +16,10 @@ typedef VOID (BMPRINTCHAR)(IN USHORT Character); /* XTLDR routines forward references */ +XTCDECL +VOID +BlClearConsoleLine(IN ULONGLONG LineNo); + XTCDECL VOID BlClearConsoleScreen(); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index e7f133e..8b1b5fd 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -90,6 +90,7 @@ BlpRegisterXtLoaderProtocol() EFI_HANDLE Handle = NULL; /* Set all routines available via loader protocol */ + LdrProtocol.Console.ClearLine = BlClearConsoleLine; LdrProtocol.Console.ClearScreen = BlClearConsoleScreen; LdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; LdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; -- 2.45.1 From 0c5f2d18b67f66ef2652299a2b62fadccb11fd94 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 10:14:42 +0100 Subject: [PATCH 087/182] Quick fixes and improvements to BlDisplayBootMenu() --- xtldr2/textui.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index fa2fb93..14dd121 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1063,8 +1063,7 @@ BlDisplayBootMenu() EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); /* Remove the timer message */ - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L" ", TimeOut); + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); } /* Read key stroke */ @@ -1073,6 +1072,12 @@ BlDisplayBootMenu() if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) { /* ENTER or RightArrow key pressed, boot the highlighted OS */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName); + + /* Boot the highlighted (chosen) OS */ BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ..."); /* Break from boot menu event loop to redraw whole boot menu */ @@ -1150,16 +1155,17 @@ BlDisplayBootMenu() if(TimeOut > 0) { /* Update a message and decrease timeout value */ + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds. ", TimeOut); + BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); TimeOut--; } else if(TimeOut == 0) { /* Time out expired, update a message */ + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now... ", - MenuEntries[HighligtedEntryId].EntryName); + BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName); /* Disable the timer just in case booting OS fails */ TimeOut = -1; -- 2.45.1 From 57b6037dd6619de25ca8f20db822d8544095b308 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 10:17:56 +0100 Subject: [PATCH 088/182] Formatting --- xtldr2/textui.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 14dd121..f08c2e8 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1090,8 +1090,10 @@ BlDisplayBootMenu() { /* Highlight previous entry */ HighligtedEntryId--; - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, HighligtedEntryId + 1, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, + HighligtedEntryId + 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, TRUE); } } else if(Key.ScanCode == 0x02) @@ -1101,8 +1103,10 @@ BlDisplayBootMenu() { /* Highlight next entry */ HighligtedEntryId++; - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, HighligtedEntryId - 1, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, + HighligtedEntryId - 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, TRUE); } } else if(Key.ScanCode == 0x09) @@ -1111,8 +1115,11 @@ BlDisplayBootMenu() if(HighligtedEntryId != 0) { /* Highlight first entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, FALSE); BlpDrawBootMenuEntry(&Handle, MenuEntries[0].EntryName, 0, TRUE); + + /* Update highlighted entry ID */ HighligtedEntryId = 0; } } @@ -1122,8 +1129,12 @@ BlDisplayBootMenu() if(HighligtedEntryId != NumberOfEntries - 1) { /* Highlight last entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName, NumberOfEntries - 1, TRUE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName, + NumberOfEntries - 1, TRUE); + + /* Update highlighted entry ID */ HighligtedEntryId = NumberOfEntries - 1; } } -- 2.45.1 From ea5365dcfd91f8cbdd223a92947d13d1900bdbe2 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 10:43:00 +0100 Subject: [PATCH 089/182] Add a way to define custom boot menu handler --- sdk/xtdk/bltypes.h | 4 ++++ xtldr2/includes/bootman.h | 12 ++++++++---- xtldr2/protocol.c | 21 ++++++++++++++++++++- xtldr2/xtldr.c | 12 ++++++++++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 7cdf24a..65f47a2 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -66,12 +66,14 @@ typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); +typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage); typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage); typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); +typedef VOID (*PBL_XT_BOOT_MENU)(); /* Boot menu list structure */ typedef struct _XTBL_BOOTMENU_ITEM @@ -148,6 +150,7 @@ typedef struct _XTBL_LOADER_PROTOCOL { PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeBootMenuList; PBL_OPEN_XT_PROTOCOL OpenProtocol; + PBL_REGISTER_XT_BOOT_MENU RegisterBootMenu; } Protocol; struct { @@ -168,6 +171,7 @@ typedef struct _XTBL_LOADER_PROTOCOL /* XTLDR Status data */ typedef struct _XTBL_STATUS { + PBL_XT_BOOT_MENU BootMenu; BOOLEAN BootServices; ULONG DebugPort; CPPORT SerialPort; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 6655df5..52ec0b6 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -126,6 +126,11 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); +XTCDECL +EFI_STATUS +BlOpenXtProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); + XTCDECL VOID BlQueryConsoleMode(OUT PUINT_PTR ResX, @@ -144,12 +149,11 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key); XTCDECL VOID -BlResetConsoleInputBuffer(); +BlRegisterBootMenu(PVOID BootMenuRoutine); XTCDECL -EFI_STATUS -BlOpenXtProtocol(OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); +VOID +BlResetConsoleInputBuffer(); XTCDECL EFI_STATUS diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 8b1b5fd..02793ce 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -74,6 +74,24 @@ BlOpenXtProtocol(OUT PVOID *ProtocolHandler, return STATUS_EFI_SUCCESS; } +/** + * Registers a boot menu callback routine, that will be used to display alternative boot menu. + * + * @param BootMenuRoutine + * Supplies a pointer to the boot menu callback routine. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlRegisterBootMenu(PVOID BootMenuRoutine) +{ + /* Set boot menu routine */ + BlpStatus.BootMenu = BootMenuRoutine; +} + /** * This routine registers XTLDR protocol for further usage by modules. * @@ -109,8 +127,9 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; - LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; LdrProtocol.Protocol.InitializeBootMenuList = BlInitializeBootMenuList; + LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; + LdrProtocol.Protocol.RegisterBootMenu = BlRegisterBootMenu; LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 956b4eb..ee896bc 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -191,8 +191,16 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, for(;;) { - /* Display boot menu */ - BlDisplayBootMenu(); + if(BlpStatus.BootMenu != NULL) + { + /* Display alternative boot menu */ + BlpStatus.BootMenu(); + } + else + { + /* Display default boot menu */ + BlDisplayBootMenu(); + } } /* This point should be never reached, if this happen return error code */ -- 2.45.1 From c5b6aa108d6c61da34a5409a2342243e984ad31d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 10:47:37 +0100 Subject: [PATCH 090/182] Cleanup --- xtldr2/includes/bootman.h | 4 ++++ xtldr2/xtldr.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 52ec0b6..b45f494 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -46,6 +46,10 @@ XTCDECL VOID BlDisableConsoleCursor(); +XTCDECL +VOID +BlDisplayBootMenu(); + XTCDECL VOID BlDisplayErrorDialog(IN PWCHAR Caption, diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index ee896bc..581771d 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,10 +9,6 @@ #include -XTCDECL -VOID -BlDisplayBootMenu(); - /** * Initializes a list of operating systems for XTLDR boot menu. * -- 2.45.1 From 4b683eb2cd47e91656c60e79dfb53614324e6b89 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 22:11:00 +0100 Subject: [PATCH 091/182] Prevent inverted colors --- xtldr2/textui.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index f08c2e8..51dfd1a 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1166,6 +1166,7 @@ BlDisplayBootMenu() if(TimeOut > 0) { /* Update a message and decrease timeout value */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); @@ -1174,6 +1175,7 @@ BlDisplayBootMenu() else if(TimeOut == 0) { /* Time out expired, update a message */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName); -- 2.45.1 From aa534ef0113f8321c0f46630604a205a166c79d6 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 22:23:17 +0100 Subject: [PATCH 092/182] If any of this occur, return error status code --- xtldr2/xtldr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 581771d..79e91af 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -175,6 +175,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, { /* Failed to register loader protocol */ BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol\n"); + return Status; } /* Discover and enumerate EFI block devices */ @@ -183,6 +184,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, { /* Failed to enumerate block devices */ BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); + return Status; } for(;;) -- 2.45.1 From e99afaba418284c0a270eceda42e09edd2e67336 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 23:11:15 +0100 Subject: [PATCH 093/182] Do not hardcode path to config file, and move it to the right directory --- bootdata/xtldr/CMakeLists.txt | 2 +- sdk/xtdk/bltypes.h | 6 +++--- xtldr2/config.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bootdata/xtldr/CMakeLists.txt b/bootdata/xtldr/CMakeLists.txt index 3bf097a..9dcfcfb 100644 --- a/bootdata/xtldr/CMakeLists.txt +++ b/bootdata/xtldr/CMakeLists.txt @@ -1 +1 @@ -set_install_file(xtldr.ini efi/boot) +set_install_file(xtldr.ini efi/boot/xtldr) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 65f47a2..3452655 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -15,9 +15,9 @@ /* XTLDR directories */ -#define XTBL_LOADER_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\" -#define XTBL_MODULES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\MODULES\\" -#define XTBL_THEMES_DIRECTORY L"\\EFI\\BOOT\\XTLDR\\THEMES\\" +#define XTBL_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\" +#define XTBL_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\MODULES\\" +#define XTBL_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\THEMES\\" /* EFI XT boot devices */ #define XTBL_BOOT_DEVICE_UNKNOWN 0x00 diff --git a/xtldr2/config.c b/xtldr2/config.c index b03c91a..65f74fc 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -121,7 +121,7 @@ BlpLoadConfiguration() RtlInitializeListHead(&BlpConfigSections); /* Read data from configuration file */ - Status = BlpReadConfigFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData); + Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ -- 2.45.1 From 4ca81575fa63d87482cf494caeec518c351e9443 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 23 Dec 2023 23:15:59 +0100 Subject: [PATCH 094/182] Update XTLDR config file --- bootdata/xtldr/xtldr.ini | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bootdata/xtldr/xtldr.ini b/bootdata/xtldr/xtldr.ini index 8bd454f..9b59049 100644 --- a/bootdata/xtldr/xtldr.ini +++ b/bootdata/xtldr/xtldr.ini @@ -6,12 +6,14 @@ # 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 +# Modules - supplies a list of modules that will be loaded in orded to extend XTLDR functionality # 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 # # Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type # of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored # by the XT Boot Loader. The available options are: +# BootModules - supplies a list of additional modules that will be loaded just before invoking the boot protocol # SystemName - sets a long operating system name that will be shown on the boot menu # SystemType - specifies an OS type from a predefined list of supported boot protocols # SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1) @@ -21,14 +23,16 @@ # Parameters - specifies extra boot options for the kernel [XTLDR] -Tune=400 880 2 988 2 783 2 392 2 587 3 Debug=COM1,115200 -Timeout=30 Default=ExectOS +Modules=beep +Timeout=30 +Tune=400 880 2 988 2 783 2 392 2 587 3 [ExectOS] SystemName="ExectOS Operating System" SystemType=XTOS +BootModules=pecoff xtos SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS KernelFile=xtoskrnl.exe Parameters=DEBUG DEBUGPORT=COM1,115200 @@ -44,6 +48,7 @@ Parameters=/NOGUIBOOT /MININT [Linux] SystemName="GNU/Linux" SystemType=LINUX +BootModules=elf linux SystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot KernelFile=vmlinuz InitrdFile=initramfs.cpio.gz -- 2.45.1 From e686b6f342562dc05afdda8b03064e235c000696 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 29 Dec 2023 20:46:25 +0100 Subject: [PATCH 095/182] Add SEGMENT macro for specifying a segment in which the object will be allocated --- sdk/xtdk/xtdefs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/xtdk/xtdefs.h b/sdk/xtdk/xtdefs.h index b4e5be7..6f5aeae 100644 --- a/sdk/xtdk/xtdefs.h +++ b/sdk/xtdk/xtdefs.h @@ -40,9 +40,10 @@ #define MAXLONG 0x7FFFFFFF #define MAXULONG 0xFFFFFFFF -/* Preprocessor macros for defining a structure alignment and packing */ +/* Preprocessor macros for defining a structure alignment, packing and segment */ #define ALIGN(x) __attribute__((aligned(x))) #define PACK __attribute__((packed)) +#define SEGMENT(segment) __attribute__((section(segment))) /* Macro for calculating size of an array */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) -- 2.45.1 From ea32946bbd23f18eda9d0948673ea6c2f42ef303 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 00:57:01 +0100 Subject: [PATCH 096/182] Initial modules support --- sdk/xtdk/bltypes.h | 9 + xtldr2/CMakeLists.txt | 3 + xtldr2/efiutils.c | 3 +- xtldr2/globals.c | 3 + xtldr2/includes/globals.h | 3 + xtldr2/modules/CMakeLists.txt | 2 + xtldr2/modules/dummy/CMakeLists.txt | 26 +++ xtldr2/modules/dummy/dummy.c | 36 ++++ xtldr2/modules/dummy2/CMakeLists.txt | 26 +++ xtldr2/modules/dummy2/dummy2.c | 34 +++ xtldr2/textui.c | 25 ++- xtldr2/xtldr.c | 303 +++++++++++++++++++++++++++ 12 files changed, 468 insertions(+), 5 deletions(-) create mode 100644 xtldr2/modules/CMakeLists.txt create mode 100644 xtldr2/modules/dummy/CMakeLists.txt create mode 100644 xtldr2/modules/dummy/dummy.c create mode 100644 xtldr2/modules/dummy2/CMakeLists.txt create mode 100644 xtldr2/modules/dummy2/dummy2.c diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 3452655..f42ffc9 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -168,6 +168,15 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; +/* XTLDR Module information data */ +typedef struct _XTBL_MODULE_INFO +{ + LIST_ENTRY Flink; + PWCHAR ModuleName; + PWCHAR ModuleDescription; + WCHAR Dependencies[1024]; +} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; + /* XTLDR Status data */ typedef struct _XTBL_STATUS { diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index e6a8237..2527989 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -1,6 +1,9 @@ # XT Boot Manager PROJECT(XTLDR) +# Build XTLDR modules +add_subdirectory(modules) + # Specify include directories include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 411cdcb..4b3733c 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -143,8 +143,9 @@ BlpInitializeEfiBootLoader() /* Print XTLDR version */ BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - /* Initialize XTLDR configuration list */ + /* Initialize XTLDR configuration and loaded modules lists */ RtlInitializeListHead(&BlpConfig); + RtlInitializeListHead(&BlpLoadedModules); /* Check if debug is enabled */ if(DEBUG) diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 4b2a3b9..431c828 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -18,6 +18,9 @@ LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; +/* XT Boot Loader loaded modules list */ +LIST_ENTRY BlpLoadedModules; + /* XT Boot Loader menu list */ PLIST_ENTRY BlpMenuList = NULL; diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index dcdc804..5fe9363 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -21,6 +21,9 @@ EXTERN LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; +/* XT Boot Loader loaded modules list */ +EXTERN LIST_ENTRY BlpLoadedModules; + /* XT Boot Loader menu list */ EXTERN PLIST_ENTRY BlpMenuList; diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt new file mode 100644 index 0000000..5a3e917 --- /dev/null +++ b/xtldr2/modules/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(dummy) +add_subdirectory(dummy2) diff --git a/xtldr2/modules/dummy/CMakeLists.txt b/xtldr2/modules/dummy/CMakeLists.txt new file mode 100644 index 0000000..2108502 --- /dev/null +++ b/xtldr2/modules/dummy/CMakeLists.txt @@ -0,0 +1,26 @@ +# XT Boot Loader +PROJECT(XTLDR_DUMMY) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_SOURCE_DIR}/includes + ${XTLDR_DUMMY_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_DUMMY_SOURCE + ${XTLDR_DUMMY_SOURCE_DIR}/dummy.c) + +# Link bootloader executable +add_executable(dummy ${XTLDR_DUMMY_SOURCE}) + +# Add linker libraries +target_link_libraries(dummy libxtldr libxtos) + +# Set proper binary name and install target +set_target_properties(dummy PROPERTIES SUFFIX .efi) +set_install_target(dummy efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(dummy "XtLdrModuleMain") +set_subsystem(dummy efi_boot_service_driver) diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c new file mode 100644 index 0000000..0a78fde --- /dev/null +++ b/xtldr2/modules/dummy/dummy.c @@ -0,0 +1,36 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/dummy/dummy.c + * DESCRIPTION: Dummy XTLDR module + * DEVELOPERS: Rafal Kupiec + */ + +#include + +#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8] +#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[] + +XTBL_MODDEP = {L"dummy2", L"dummy2"}; +XTBL_MODINFO = L"Dummy XTLDR module"; + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr2/modules/dummy2/CMakeLists.txt b/xtldr2/modules/dummy2/CMakeLists.txt new file mode 100644 index 0000000..b4e0328 --- /dev/null +++ b/xtldr2/modules/dummy2/CMakeLists.txt @@ -0,0 +1,26 @@ +# XT Boot Loader +PROJECT(XTLDR_DUMMY2) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_SOURCE_DIR}/includes + ${XTLDR_DUMMY2_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_DUMMY2_SOURCE + ${XTLDR_DUMMY2_SOURCE_DIR}/dummy2.c) + +# Link bootloader executable +add_executable(dummy2 ${XTLDR_DUMMY2_SOURCE}) + +# Add linker libraries +target_link_libraries(dummy2 libxtldr libxtos) + +# Set proper binary name and install target +set_target_properties(dummy2 PROPERTIES SUFFIX .efi) +set_install_target(dummy2 efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(dummy2 "XtLdrModuleMain") +set_subsystem(dummy2 efi_boot_service_driver) diff --git a/xtldr2/modules/dummy2/dummy2.c b/xtldr2/modules/dummy2/dummy2.c new file mode 100644 index 0000000..f9a184a --- /dev/null +++ b/xtldr2/modules/dummy2/dummy2.c @@ -0,0 +1,34 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/dummy/dummy.c + * DESCRIPTION: Dummy XTLDR module + * DEVELOPERS: Rafal Kupiec + */ + +#include + +#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8] + +//XTBL_MODDEP = {L""}; + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 51dfd1a..01fb4a1 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -963,6 +963,9 @@ BlDisplayInputDialog(IN PWCHAR Caption, +XTCDECL +EFI_STATUS +BlInvokeBootProtocol(IN PLIST_ENTRY Options); @@ -1075,10 +1078,17 @@ BlDisplayBootMenu() BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); /* Boot the highlighted (chosen) OS */ - BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ..."); + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + if(Status != STATUS_SUCCESS) + { + /* Failed to boot OS */ + BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + MenuEntries[HighligtedEntryId].EntryName, Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + } /* Break from boot menu event loop to redraw whole boot menu */ break; @@ -1178,13 +1188,20 @@ BlDisplayBootMenu() BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...", MenuEntries[HighligtedEntryId].EntryName); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); /* Disable the timer just in case booting OS fails */ TimeOut = -1; /* Boot the highlighted (default) OS */ - BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ..."); + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + if(Status != STATUS_SUCCESS) + { + /* Failed to boot OS */ + BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + MenuEntries[HighligtedEntryId].EntryName, Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + } break; } } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 79e91af..dcc5109 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,6 +9,14 @@ #include +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR Module); + +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList); + /** * Initializes a list of operating systems for XTLDR boot menu. * @@ -96,6 +104,266 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, MenuEntries = OsList; } +/** + * Loads all necessary modules and invokes boot protocol. + * + * @param OptionsList + * Supplies a pointer to list of options associated with chosen boot menu entry. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) +{ + PWCHAR ModulesList, ProtocolName; + PLIST_ENTRY OptionsListEntry; + PXTBL_CONFIG_ENTRY Option; + EFI_STATUS Status; + + /* Set default values */ + ModulesList = NULL; + ProtocolName = NULL; + + /* Iterate through all options provided by boot menu entry */ + OptionsListEntry = OptionsList->Flink; + while(OptionsListEntry != OptionsList) + { + /* Get option */ + Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Look for boot protocol and modules list */ + if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) + { + /* Boot protocol found */ + ProtocolName = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) + { + /* Set protocol name */ + ModulesList = Option->Value; + } + + /* Move to the next option entry */ + OptionsListEntry = OptionsListEntry->Flink; + } + + /* Load all necessary modules */ + Status = BlLoadModules(ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load modules, print error message and return status code */ + BlDebugPrint(L"Failed to load XTLDR modules\n"); + return Status; + } + for(;;); + + /* This point should never be reached */ + return STATUS_EFI_SUCCESS; +} + +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList) +{ + PWCHAR LastModule, Module; + EFI_STATUS Status; + + if(ModulesList != NULL) + { + /* Tokenize provided list of modules */ + Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); + + /* Iterate over all arguments passed to boot loader */ + while(Module != NULL) + { + Status = BlLoadModule(Module); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and return status code */ + BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status); + // return Status; + } + + /* Take next module from the list */ + Module = RtlTokenizeWideString(NULL, L" ", &LastModule); + } + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName) +{ + EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; + PEFI_FILE_HANDLE DirHandle, FsHandle; + EFI_HANDLE DiskHandle, ModuleHandle; + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_DOS_HEADER DosHeader; + PPECOFF_IMAGE_PE_HEADER PeHeader; + PLIST_ENTRY ModuleListEntry; + WCHAR ModuleFileName[1024]; + USHORT SectionIndex; + SIZE_T ModuleSize; + EFI_STATUS Status; + PVOID ModuleData; + PWCHAR DepsData; + PXTBL_MODULE_INFO ModuleInfo; + + ModuleListEntry = BlpLoadedModules.Flink; + while(ModuleListEntry != &BlpLoadedModules) + { + /* Get module information */ + ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) + { + /* Module already loaded */ + BlDebugPrint(L"Module '%S' already loaded\n", ModuleName); + return STATUS_EFI_SUCCESS; + } + + /* Move to the module */ + ModuleListEntry = ModuleListEntry->Flink; + } + + /* Print debug message */ + BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); + + /* Set module path */ + RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); + RtlConcatenateWideString(ModuleFileName, L".EFI", 0); + + /* Open EFI volume */ + Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + return Status; + } + + /* Open XTLDR modules directory and close the FS immediately */ + Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if directory opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + BlCloseVolume(DiskHandle); + return Status; + } + + /* Read module file from disk and close EFI volume */ + Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + BlCloseVolume(DiskHandle); + + /* Make sure module file was read successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read file */ + return Status; + } + + /* Allocate memory for new option */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + return Status; + } + + RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); + + /* Setup PE/COFF EFI image headers */ + DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; + PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew); + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + + PeHeader->FileHeader.SizeOfOptionalHeader); + + /* Look for .moddeps section */ + for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) + { + /* Check section name */ + if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0) + { + /* Store address of .moddeps data segment */ + DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + + /* Iterate over all dependencies stored */ + while(*DepsData != 0) + { + /* Load dependency module */ + BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData); + Status = BlLoadModule(DepsData); + + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and return status code */ + BlDebugPrint(L"Failed to load dependency module '%S', status = 0x%lx\n", DepsData, Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Add dependency module name to the list */ + RtlConcatenateWideString(ModuleInfo->Dependencies, DepsData, RtlWideStringLength(DepsData, 0)); + RtlConcatenateWideString(ModuleInfo->Dependencies, L" ", 1); + + /* Get next dependency module name */ + DepsData += 8; + } + } + else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) + { + /* Store module description */ + ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + } + } + + /* Store module name */ + ModuleInfo->ModuleName = ModuleName; + + /* Setup module device path */ + ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); + ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; + ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; + ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; + ModuleDevicePath[0].MemoryType = EfiLoaderData; + ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; + ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; + ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; + ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; + ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; + + /* Load EFI image */ + Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, + ModuleData, ModuleSize, &ModuleHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module image */ + return Status; + } + + /* Start EFI image */ + Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to start module image */ + return Status; + } + + /* Add module to the list of loaded modules */ + RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * This routine is the entry point of the XT EFI boot loader. * @@ -187,6 +455,41 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, return Status; } + BlLoadModules(BlGetConfigValue(L"MODULES")); + + BlLoadModule(L"DUMMY"); + + + BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); + PLIST_ENTRY ModuleListEntry; + PXTBL_MODULE_INFO ModuleInfo; + + ModuleListEntry = BlpLoadedModules.Flink; + while(ModuleListEntry != &BlpLoadedModules) + { + /* Get module information */ + ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + /* Module already loaded */ + BlConsolePrint(L"\n%.8S", ModuleInfo->ModuleName); + if(ModuleInfo->ModuleDescription != 0) + { + BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); + } + + if(ModuleInfo->Dependencies[0] != 0) + { + BlConsolePrint(L"\n - Uses: %S", ModuleInfo->Dependencies); + } + + /* Move to the module */ + ModuleListEntry = ModuleListEntry->Flink; + } + + BlConsolePrint(L"\n\n END OF LIST\n"); + + for(;;); + for(;;) { if(BlpStatus.BootMenu != NULL) -- 2.45.1 From 08fb9b92d5b4639a385f069676023fb966eccec0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 10:28:25 +0100 Subject: [PATCH 097/182] Small fixes --- xtldr2/efiutils.c | 2 +- xtldr2/xtldr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 4b3733c..6d2e866 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -134,7 +134,7 @@ BlpInitializeEfiBootLoader() PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; EFI_STATUS Status; - /* Set current XTLDR status */ + /* Set current XTLDR's EFI BootServices status */ BlpStatus.BootServices = TRUE; /* Initialize console */ diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index dcc5109..48c1255 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -471,7 +471,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); /* Module already loaded */ - BlConsolePrint(L"\n%.8S", ModuleInfo->ModuleName); + BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); if(ModuleInfo->ModuleDescription != 0) { BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); -- 2.45.1 From ea06286a8bbda2cb30d302fade1907ef10aba79d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 10:31:28 +0100 Subject: [PATCH 098/182] Store SecureBoot status --- sdk/xtdk/bltypes.h | 1 + xtldr2/efiutils.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index f42ffc9..d3cb9aa 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -183,6 +183,7 @@ typedef struct _XTBL_STATUS PBL_XT_BOOT_MENU BootMenu; BOOLEAN BootServices; ULONG DebugPort; + INT_PTR SecureBoot; CPPORT SerialPort; } XTBL_STATUS, *PXTBL_STATUS; diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 6d2e866..a41b5a5 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -147,6 +147,9 @@ BlpInitializeEfiBootLoader() RtlInitializeListHead(&BlpConfig); RtlInitializeListHead(&BlpLoadedModules); + /* Store SecureBoot status */ + BlpStatus.SecureBoot = BlGetSecureBootStatus(); + /* Check if debug is enabled */ if(DEBUG) { -- 2.45.1 From aa03fc9cb230cf37194babea21d59b25292800b2 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 10:54:38 +0100 Subject: [PATCH 099/182] Add more checks to BlLoadModule() and make it more verbose --- xtldr2/xtldr.c | 62 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 48c1255..138a5cd 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -169,7 +169,10 @@ EFI_STATUS BlLoadModules(IN PWCHAR ModulesList) { PWCHAR LastModule, Module; - EFI_STATUS Status; + EFI_STATUS ReturnStatus, Status; + + /* Set default return value */ + ReturnStatus = STATUS_EFI_SUCCESS; if(ModulesList != NULL) { @@ -182,9 +185,9 @@ BlLoadModules(IN PWCHAR ModulesList) Status = BlLoadModule(Module); if(Status != STATUS_EFI_SUCCESS) { - /* Failed to load module, print error message and return status code */ + /* Failed to load module, print error message and set new return value */ BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status); - // return Status; + ReturnStatus = STATUS_EFI_LOAD_ERROR; } /* Take next module from the list */ @@ -193,14 +196,16 @@ BlLoadModules(IN PWCHAR ModulesList) } /* Return success */ - return STATUS_EFI_SUCCESS; + return ReturnStatus; } XTCDECL EFI_STATUS BlLoadModule(IN PWCHAR ModuleName) { + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; PEFI_FILE_HANDLE DirHandle, FsHandle; EFI_HANDLE DiskHandle, ModuleHandle; PPECOFF_IMAGE_SECTION_HEADER SectionHeader; @@ -224,7 +229,7 @@ BlLoadModule(IN PWCHAR ModuleName) if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) { /* Module already loaded */ - BlDebugPrint(L"Module '%S' already loaded\n", ModuleName); + BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); return STATUS_EFI_SUCCESS; } @@ -270,7 +275,7 @@ BlLoadModule(IN PWCHAR ModuleName) return Status; } - /* Allocate memory for new option */ + /* Allocate memory for module information block */ Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); if(Status != STATUS_EFI_SUCCESS) { @@ -278,6 +283,7 @@ BlLoadModule(IN PWCHAR ModuleName) return Status; } + /* Zero module information block */ RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); /* Setup PE/COFF EFI image headers */ @@ -286,7 +292,7 @@ BlLoadModule(IN PWCHAR ModuleName) SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + PeHeader->FileHeader.SizeOfOptionalHeader); - /* Look for .moddeps section */ + /* Look for .moddeps and .modinfo sections */ for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) { /* Check section name */ @@ -305,7 +311,7 @@ BlLoadModule(IN PWCHAR ModuleName) if(Status != STATUS_EFI_SUCCESS) { /* Failed to load module, print error message and return status code */ - BlDebugPrint(L"Failed to load dependency module '%S', status = 0x%lx\n", DepsData, Status); + BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status); return STATUS_EFI_UNSUPPORTED; } @@ -324,7 +330,7 @@ BlLoadModule(IN PWCHAR ModuleName) } } - /* Store module name */ + /* Finally, store module name */ ModuleInfo->ModuleName = ModuleName; /* Setup module device path */ @@ -345,15 +351,51 @@ BlLoadModule(IN PWCHAR ModuleName) ModuleData, ModuleSize, &ModuleHandle); if(Status != STATUS_EFI_SUCCESS) { - /* Failed to load module image */ + /* Check if caused by secure boot */ + if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) + { + /* SecureBoot signature validation failed */ + BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); + } + else + { + /* Failed to load module */ + BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); + } + + /* Return error status code */ return Status; } + /* Access module interface for further module type check */ + Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open LoadedImage protocol */ + BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status); + return Status; + } + + /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ + if(LoadedImage->ImageCodeType != EfiBootServicesCode) + { + /* Different type set, probably 'runtime driver', refuse to load it */ + BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); + + /* Close protocol and skip module */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + } + + /* Close loaded image protocol */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + /* Start EFI image */ Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); if(Status != STATUS_EFI_SUCCESS) { /* Failed to start module image */ + BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); return Status; } -- 2.45.1 From effde90ece3df2d8f08f9de5c14ca2688042b363 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 11:18:51 +0100 Subject: [PATCH 100/182] Another improvements to module loading support --- sdk/xtdk/bltypes.h | 20 ++++++++++++-------- xtldr2/modules/dummy/dummy.c | 5 ++--- xtldr2/xtldr.c | 10 ++++++---- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index d3cb9aa..f253b4c 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -19,6 +19,10 @@ #define XTBL_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\MODULES\\" #define XTBL_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\THEMES\\" +/* XTLDR module segment macros */ +#define XTBL_MODDEPS SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8] +#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[] + /* EFI XT boot devices */ #define XTBL_BOOT_DEVICE_UNKNOWN 0x00 #define XTBL_BOOT_DEVICE_CDROM 0x01 @@ -31,16 +35,16 @@ #define XTBL_DEBUGPORT_SERIAL 2 /* TUI dialog box attributes */ -#define XTBL_TUI_DIALOG_GENERIC_BOX 1 -#define XTBL_TUI_DIALOG_ERROR_BOX 2 -#define XTBL_TUI_DIALOG_ACTIVE_BUTTON 4 -#define XTBL_TUI_DIALOG_INACTIVE_BUTTON 8 -#define XTBL_TUI_DIALOG_ACTIVE_INPUT 16 -#define XTBL_TUI_DIALOG_INACTIVE_INPUT 32 -#define XTBL_TUI_DIALOG_PROGRESS_BAR 64 +#define XTBL_TUI_DIALOG_GENERIC_BOX 1 +#define XTBL_TUI_DIALOG_ERROR_BOX 2 +#define XTBL_TUI_DIALOG_ACTIVE_BUTTON 4 +#define XTBL_TUI_DIALOG_INACTIVE_BUTTON 8 +#define XTBL_TUI_DIALOG_ACTIVE_INPUT 16 +#define XTBL_TUI_DIALOG_INACTIVE_INPUT 32 +#define XTBL_TUI_DIALOG_PROGRESS_BAR 64 /* TUI dialog box maximum width */ -#define XTBL_TUI_MAX_DIALOG_WIDTH 100 +#define XTBL_TUI_MAX_DIALOG_WIDTH 100 /* Boot Loader protocol routine pointers */ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory); diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index 0a78fde..881a8d2 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -8,11 +8,10 @@ #include -#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8] -#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[] -XTBL_MODDEP = {L"dummy2", L"dummy2"}; +/* Dummy module information */ XTBL_MODINFO = L"Dummy XTLDR module"; +XTBL_MODDEPS = {L"dummy2"}; /** * This routine is the entry point of the XT EFI boot loader module. diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 138a5cd..f971152 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -155,9 +155,11 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) if(Status != STATUS_EFI_SUCCESS) { /* Failed to load modules, print error message and return status code */ - BlDebugPrint(L"Failed to load XTLDR modules\n"); - return Status; + BlDebugPrint(L"ERROR: Failed to load XTLDR modules\n"); + return STATUS_EFI_NOT_READY; } + + // TODO: Add support for boot protocol and invoke it for(;;); /* This point should never be reached */ @@ -186,7 +188,7 @@ BlLoadModules(IN PWCHAR ModulesList) if(Status != STATUS_EFI_SUCCESS) { /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status); + BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); ReturnStatus = STATUS_EFI_LOAD_ERROR; } @@ -211,6 +213,7 @@ BlLoadModule(IN PWCHAR ModuleName) PPECOFF_IMAGE_SECTION_HEADER SectionHeader; PPECOFF_IMAGE_DOS_HEADER DosHeader; PPECOFF_IMAGE_PE_HEADER PeHeader; + PXTBL_MODULE_INFO ModuleInfo; PLIST_ENTRY ModuleListEntry; WCHAR ModuleFileName[1024]; USHORT SectionIndex; @@ -218,7 +221,6 @@ BlLoadModule(IN PWCHAR ModuleName) EFI_STATUS Status; PVOID ModuleData; PWCHAR DepsData; - PXTBL_MODULE_INFO ModuleInfo; ModuleListEntry = BlpLoadedModules.Flink; while(ModuleListEntry != &BlpLoadedModules) -- 2.45.1 From 1d61b2fb6a3fe2eba73280150806d02dada0b26a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 13:36:17 +0100 Subject: [PATCH 101/182] Store module dependencies in a linked list --- sdk/xtdk/bltypes.h | 9 ++++++++- xtldr2/modules/dummy/dummy.c | 2 +- xtldr2/modules/dummy2/dummy2.c | 5 +---- xtldr2/xtldr.c | 27 ++++++++++++++++++++------- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index f253b4c..ce550d8 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -172,13 +172,20 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; +/* XTLDR Module dependencies data */ +typedef struct _XTBL_MODULE_DEPS +{ + LIST_ENTRY Flink; + PWCHAR ModuleName; +} XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; + /* XTLDR Module information data */ typedef struct _XTBL_MODULE_INFO { LIST_ENTRY Flink; PWCHAR ModuleName; PWCHAR ModuleDescription; - WCHAR Dependencies[1024]; + LIST_ENTRY Dependencies; } XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; /* XTLDR Status data */ diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index 881a8d2..cc24ebb 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -31,5 +31,5 @@ EFI_STATUS XtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { - return STATUS_EFI_SUCCESS; + return STATUS_EFI_SUCCESS; } diff --git a/xtldr2/modules/dummy2/dummy2.c b/xtldr2/modules/dummy2/dummy2.c index f9a184a..4681052 100644 --- a/xtldr2/modules/dummy2/dummy2.c +++ b/xtldr2/modules/dummy2/dummy2.c @@ -8,9 +8,6 @@ #include -#define XTBL_MODDEP SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8] - -//XTBL_MODDEP = {L""}; /** * This routine is the entry point of the XT EFI boot loader module. @@ -30,5 +27,5 @@ EFI_STATUS XtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { - return STATUS_EFI_SUCCESS; + return STATUS_EFI_SUCCESS; } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index f971152..6a71a5b 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -213,9 +213,10 @@ BlLoadModule(IN PWCHAR ModuleName) PPECOFF_IMAGE_SECTION_HEADER SectionHeader; PPECOFF_IMAGE_DOS_HEADER DosHeader; PPECOFF_IMAGE_PE_HEADER PeHeader; + PXTBL_MODULE_DEPS ModuleDependencies; PXTBL_MODULE_INFO ModuleInfo; PLIST_ENTRY ModuleListEntry; - WCHAR ModuleFileName[1024]; + WCHAR ModuleFileName[12]; USHORT SectionIndex; SIZE_T ModuleSize; EFI_STATUS Status; @@ -285,8 +286,9 @@ BlLoadModule(IN PWCHAR ModuleName) return Status; } - /* Zero module information block */ + /* Zero module information block and initialize dependencies list */ RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); + RtlInitializeListHead(&ModuleInfo->Dependencies); /* Setup PE/COFF EFI image headers */ DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; @@ -317,9 +319,14 @@ BlLoadModule(IN PWCHAR ModuleName) return STATUS_EFI_UNSUPPORTED; } - /* Add dependency module name to the list */ - RtlConcatenateWideString(ModuleInfo->Dependencies, DepsData, RtlWideStringLength(DepsData, 0)); - RtlConcatenateWideString(ModuleInfo->Dependencies, L" ", 1); + /* Allocate memory for module dependency */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); + if(Status == STATUS_EFI_SUCCESS) + { + /* Memory allocated successfully, store module's dependency */ + ModuleDependencies->ModuleName = DepsData; + RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); + } /* Get next dependency module name */ DepsData += 8; @@ -521,9 +528,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); } - if(ModuleInfo->Dependencies[0] != 0) + PLIST_ENTRY DepsListEntry; + PXTBL_MODULE_DEPS DepsInfo; + BlConsolePrint(L"\n - Uses: "); + DepsListEntry = ModuleInfo->Dependencies.Flink; + while(DepsListEntry != &ModuleInfo->Dependencies) { - BlConsolePrint(L"\n - Uses: %S", ModuleInfo->Dependencies); + DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); + BlConsolePrint(L"%S ", DepsInfo->ModuleName); + DepsListEntry = DepsListEntry->Flink; } /* Move to the module */ -- 2.45.1 From 03ffa1d901a9a432abd2376d772fbc774b09e5e0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 14:23:58 +0100 Subject: [PATCH 102/182] Clean up code a bit --- xtldr2/includes/bootman.h | 8 ++ xtldr2/protocol.c | 269 ++++++++++++++++++++++++++++++++++++++ xtldr2/textui.c | 4 +- xtldr2/xtldr.c | 259 ------------------------------------ 4 files changed, 279 insertions(+), 261 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index b45f494..b728275 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -105,6 +105,14 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName); + +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 02793ce..ac743e2 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -9,6 +9,275 @@ #include +/** + * Loads a specified XTLDR module from disk. + * + * @param ModuleName + * Specifies the name of the module to load. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + PEFI_FILE_HANDLE DirHandle, FsHandle; + EFI_HANDLE DiskHandle, ModuleHandle; + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_DOS_HEADER DosHeader; + PPECOFF_IMAGE_PE_HEADER PeHeader; + PXTBL_MODULE_DEPS ModuleDependencies; + PXTBL_MODULE_INFO ModuleInfo; + PLIST_ENTRY ModuleListEntry; + WCHAR ModuleFileName[12]; + USHORT SectionIndex; + SIZE_T ModuleSize; + EFI_STATUS Status; + PVOID ModuleData; + PWCHAR DepsData; + + ModuleListEntry = BlpLoadedModules.Flink; + while(ModuleListEntry != &BlpLoadedModules) + { + /* Get module information */ + ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) + { + /* Module already loaded */ + BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); + return STATUS_EFI_SUCCESS; + } + + /* Move to the module */ + ModuleListEntry = ModuleListEntry->Flink; + } + + /* Print debug message */ + BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); + + /* Set module path */ + RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); + RtlConcatenateWideString(ModuleFileName, L".EFI", 0); + + /* Open EFI volume */ + Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + return Status; + } + + /* Open XTLDR modules directory and close the FS immediately */ + Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if directory opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + BlCloseVolume(DiskHandle); + return Status; + } + + /* Read module file from disk and close EFI volume */ + Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + BlCloseVolume(DiskHandle); + + /* Make sure module file was read successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read file */ + return Status; + } + + /* Allocate memory for module information block */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + return Status; + } + + /* Zero module information block and initialize dependencies list */ + RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); + RtlInitializeListHead(&ModuleInfo->Dependencies); + + /* Setup PE/COFF EFI image headers */ + DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; + PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew); + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + + PeHeader->FileHeader.SizeOfOptionalHeader); + + /* Look for .moddeps and .modinfo sections */ + for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) + { + /* Check section name */ + if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0) + { + /* Store address of .moddeps data segment */ + DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + + /* Iterate over all dependencies stored */ + while(*DepsData != 0) + { + /* Load dependency module */ + BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData); + Status = BlLoadModule(DepsData); + + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and return status code */ + BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Allocate memory for module dependency */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); + if(Status == STATUS_EFI_SUCCESS) + { + /* Memory allocated successfully, store module's dependency */ + ModuleDependencies->ModuleName = DepsData; + RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); + } + + /* Get next dependency module name */ + DepsData += 8; + } + } + else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) + { + /* Store module description */ + ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + } + } + + /* Finally, store module name */ + ModuleInfo->ModuleName = ModuleName; + + /* Setup module device path */ + ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); + ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; + ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; + ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; + ModuleDevicePath[0].MemoryType = EfiLoaderData; + ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; + ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; + ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; + ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; + ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; + + /* Load EFI image */ + Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, + ModuleData, ModuleSize, &ModuleHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Check if caused by secure boot */ + if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) + { + /* SecureBoot signature validation failed */ + BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); + } + else + { + /* Failed to load module */ + BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); + } + + /* Return error status code */ + return Status; + } + + /* Access module interface for further module type check */ + Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open LoadedImage protocol */ + BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status); + return Status; + } + + /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ + if(LoadedImage->ImageCodeType != EfiBootServicesCode) + { + /* Different type set, probably 'runtime driver', refuse to load it */ + BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); + + /* Close protocol and skip module */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + } + + /* Close loaded image protocol */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + + /* Start EFI image */ + Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to start module image */ + BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); + return Status; + } + + /* Add module to the list of loaded modules */ + RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Helper routine to load all modules supplied in the configuration file. + * + * @param ModulesList + * Supplies a space separated list of XTLDR modules to load (mostly read from configuration file). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList) +{ + PWCHAR LastModule, Module; + EFI_STATUS ReturnStatus, Status; + + /* Set default return value */ + ReturnStatus = STATUS_EFI_SUCCESS; + + if(ModulesList != NULL) + { + /* Tokenize provided list of modules */ + Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); + + /* Iterate over all arguments passed to boot loader */ + while(Module != NULL) + { + Status = BlLoadModule(Module); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and set new return value */ + BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); + ReturnStatus = STATUS_EFI_LOAD_ERROR; + } + + /* Take next module from the list */ + Module = RtlTokenizeWideString(NULL, L" ", &LastModule); + } + } + + /* Return success */ + return ReturnStatus; +} + /** * This routine locates and opens the requested XT boot loader protocol. * diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 01fb4a1..0ec3605 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1085,7 +1085,7 @@ BlDisplayBootMenu() if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", MenuEntries[HighligtedEntryId].EntryName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); } @@ -1198,7 +1198,7 @@ BlDisplayBootMenu() if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", MenuEntries[HighligtedEntryId].EntryName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 6a71a5b..09d786a 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,14 +9,6 @@ #include -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR Module); - -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList); - /** * Initializes a list of operating systems for XTLDR boot menu. * @@ -166,255 +158,6 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) return STATUS_EFI_SUCCESS; } -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList) -{ - PWCHAR LastModule, Module; - EFI_STATUS ReturnStatus, Status; - - /* Set default return value */ - ReturnStatus = STATUS_EFI_SUCCESS; - - if(ModulesList != NULL) - { - /* Tokenize provided list of modules */ - Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); - - /* Iterate over all arguments passed to boot loader */ - while(Module != NULL) - { - Status = BlLoadModule(Module); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); - ReturnStatus = STATUS_EFI_LOAD_ERROR; - } - - /* Take next module from the list */ - Module = RtlTokenizeWideString(NULL, L" ", &LastModule); - } - } - - /* Return success */ - return ReturnStatus; -} - -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName) -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - PEFI_FILE_HANDLE DirHandle, FsHandle; - EFI_HANDLE DiskHandle, ModuleHandle; - PPECOFF_IMAGE_SECTION_HEADER SectionHeader; - PPECOFF_IMAGE_DOS_HEADER DosHeader; - PPECOFF_IMAGE_PE_HEADER PeHeader; - PXTBL_MODULE_DEPS ModuleDependencies; - PXTBL_MODULE_INFO ModuleInfo; - PLIST_ENTRY ModuleListEntry; - WCHAR ModuleFileName[12]; - USHORT SectionIndex; - SIZE_T ModuleSize; - EFI_STATUS Status; - PVOID ModuleData; - PWCHAR DepsData; - - ModuleListEntry = BlpLoadedModules.Flink; - while(ModuleListEntry != &BlpLoadedModules) - { - /* Get module information */ - ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) - { - /* Module already loaded */ - BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); - return STATUS_EFI_SUCCESS; - } - - /* Move to the module */ - ModuleListEntry = ModuleListEntry->Flink; - } - - /* Print debug message */ - BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); - - /* Set module path */ - RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); - RtlConcatenateWideString(ModuleFileName, L".EFI", 0); - - /* Open EFI volume */ - Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open a volume */ - return Status; - } - - /* Open XTLDR modules directory and close the FS immediately */ - Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); - FsHandle->Close(FsHandle); - - /* Check if directory opened successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - BlCloseVolume(DiskHandle); - return Status; - } - - /* Read module file from disk and close EFI volume */ - Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); - BlCloseVolume(DiskHandle); - - /* Make sure module file was read successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read file */ - return Status; - } - - /* Allocate memory for module information block */ - Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory */ - return Status; - } - - /* Zero module information block and initialize dependencies list */ - RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); - RtlInitializeListHead(&ModuleInfo->Dependencies); - - /* Setup PE/COFF EFI image headers */ - DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; - PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew); - SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + - PeHeader->FileHeader.SizeOfOptionalHeader); - - /* Look for .moddeps and .modinfo sections */ - for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) - { - /* Check section name */ - if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0) - { - /* Store address of .moddeps data segment */ - DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; - - /* Iterate over all dependencies stored */ - while(*DepsData != 0) - { - /* Load dependency module */ - BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData); - Status = BlLoadModule(DepsData); - - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load module, print error message and return status code */ - BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Allocate memory for module dependency */ - Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); - if(Status == STATUS_EFI_SUCCESS) - { - /* Memory allocated successfully, store module's dependency */ - ModuleDependencies->ModuleName = DepsData; - RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); - } - - /* Get next dependency module name */ - DepsData += 8; - } - } - else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) - { - /* Store module description */ - ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData; - } - } - - /* Finally, store module name */ - ModuleInfo->ModuleName = ModuleName; - - /* Setup module device path */ - ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); - ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; - ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; - ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; - ModuleDevicePath[0].MemoryType = EfiLoaderData; - ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; - ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; - ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); - ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; - ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; - ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; - - /* Load EFI image */ - Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, - ModuleData, ModuleSize, &ModuleHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Check if caused by secure boot */ - if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) - { - /* SecureBoot signature validation failed */ - BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); - } - else - { - /* Failed to load module */ - BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); - } - - /* Return error status code */ - return Status; - } - - /* Access module interface for further module type check */ - Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open LoadedImage protocol */ - BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status); - return Status; - } - - /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ - if(LoadedImage->ImageCodeType != EfiBootServicesCode) - { - /* Different type set, probably 'runtime driver', refuse to load it */ - BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); - - /* Close protocol and skip module */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - } - - /* Close loaded image protocol */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - - /* Start EFI image */ - Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to start module image */ - BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); - return Status; - } - - /* Add module to the list of loaded modules */ - RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - /** * This routine is the entry point of the XT EFI boot loader. * @@ -545,8 +288,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlConsolePrint(L"\n\n END OF LIST\n"); - for(;;); - for(;;) { if(BlpStatus.BootMenu != NULL) -- 2.45.1 From a65c22c9c99bb4fb504a0ea0613e1968cbde65e3 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 14:36:37 +0100 Subject: [PATCH 103/182] Make a copy of modules list, because RtlTokenizeWideString() modifies input data --- xtldr2/xtldr.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 09d786a..be50e7d 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -113,10 +113,10 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) PWCHAR ModulesList, ProtocolName; PLIST_ENTRY OptionsListEntry; PXTBL_CONFIG_ENTRY Option; + SIZE_T ModuleListLength; EFI_STATUS Status; /* Set default values */ - ModulesList = NULL; ProtocolName = NULL; /* Iterate through all options provided by boot menu entry */ @@ -134,8 +134,19 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } else if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) { - /* Set protocol name */ - ModulesList = Option->Value; + /* Check a length of modules list */ + ModuleListLength = RtlWideStringLength(Option->Value, 0); + + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * ModuleListLength, (PVOID *)&ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory, print error message and return status code */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n"); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Make a copy of modules list */ + RtlCopyMemory(ModulesList, Option->Value, sizeof(PWCHAR) * ModuleListLength); } /* Move to the next option entry */ -- 2.45.1 From 5b64cf21a0a98e0c73b93fdfb8cc75f0107b21bf Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 16:34:27 +0100 Subject: [PATCH 104/182] Add boot protocol parameters --- sdk/xtdk/bltypes.h | 13 +++++++++++++ xtldr2/xtldr.c | 48 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index ce550d8..687684e 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -79,6 +79,19 @@ typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PW typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); typedef VOID (*PBL_XT_BOOT_MENU)(); +/* Boot parameters structure */ +typedef struct _XTBL_BOOT_PARAMETERS +{ + PEFI_DEVICE_PATH_PROTOCOL DevicePath; + PWCHAR ArcName; + PWCHAR SystemPath; + PWCHAR SystemType; + PWCHAR KernelFile; + PWCHAR InitrdFile; + PWCHAR HalFile; + PWCHAR Parameters; +} XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; + /* Boot menu list structure */ typedef struct _XTBL_BOOTMENU_ITEM { diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index be50e7d..8a4e324 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -110,16 +110,17 @@ XTCDECL EFI_STATUS BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) { - PWCHAR ModulesList, ProtocolName; + XTBL_BOOT_PARAMETERS BootParameters; + PWCHAR ModulesList; PLIST_ENTRY OptionsListEntry; PXTBL_CONFIG_ENTRY Option; SIZE_T ModuleListLength; EFI_STATUS Status; - /* Set default values */ - ProtocolName = NULL; + /* Initialize boot parameters */ + RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); - /* Iterate through all options provided by boot menu entry */ + /* Iterate through all options provided by boot menu entry and propagate boot parameters */ OptionsListEntry = OptionsList->Flink; while(OptionsListEntry != OptionsList) { @@ -127,12 +128,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); /* Look for boot protocol and modules list */ - if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) - { - /* Boot protocol found */ - ProtocolName = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) + if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) { /* Check a length of modules list */ ModuleListLength = RtlWideStringLength(Option->Value, 0); @@ -148,6 +144,36 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) /* Make a copy of modules list */ RtlCopyMemory(ModulesList, Option->Value, sizeof(PWCHAR) * ModuleListLength); } + else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) + { + /* Boot protocol found */ + BootParameters.SystemType = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) + { + /* System path found, get boot volume */ + + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) + { + /* Kernel file name found */ + BootParameters.KernelFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) + { + /* Initrd file name found */ + BootParameters.InitrdFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) + { + /* Hal file name found */ + BootParameters.HalFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) + { + /* Kernel parameters found */ + BootParameters.Parameters = Option->Value; + } /* Move to the next option entry */ OptionsListEntry = OptionsListEntry->Flink; @@ -163,7 +189,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } // TODO: Add support for boot protocol and invoke it - for(;;); + return STATUS_EFI_UNSUPPORTED; /* This point should never be reached */ return STATUS_EFI_SUCCESS; -- 2.45.1 From 9aaf8ddb68f88fdad2289ba54428545cabd6bf7d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 17:20:20 +0100 Subject: [PATCH 105/182] Improvements to EFI volume support --- xtldr2/includes/bootman.h | 12 +++++----- xtldr2/volume.c | 50 +++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index b728275..8bec805 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -94,10 +94,10 @@ BlGetSecureBootStatus(); XTCDECL EFI_STATUS -BlGetVolumeDevicePath(IN PCHAR SystemPath, +BlGetVolumeDevicePath(IN PWCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PCHAR *ArcName, - OUT PCHAR *Path); + OUT PWCHAR *ArcName, + OUT PWCHAR *Path); XTCDECL VOID @@ -233,9 +233,9 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); XTCDECL EFI_STATUS -BlpDissectVolumeArcPath(IN PCHAR SystemPath, - OUT PCHAR *ArcName, - OUT PCHAR *Path, +BlpDissectVolumeArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, OUT PUSHORT DriveType, OUT PULONG DriveNumber, OUT PULONG PartNumber); diff --git a/xtldr2/volume.c b/xtldr2/volume.c index 8b11882..c4ded1b 100644 --- a/xtldr2/volume.c +++ b/xtldr2/volume.c @@ -70,7 +70,7 @@ BlEnumerateBlockDevices() Status = BlpDiscoverEfiBlockDevices(&BlockDevices); if(Status != STATUS_EFI_SUCCESS) { - BlDebugPrint(L"ERROR: Failed to discover EFI block devices (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%lx)\n", Status); return Status; } @@ -169,7 +169,7 @@ BlEnumerateBlockDevices() Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { - BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); return STATUS_EFI_OUT_OF_RESOURCES; } @@ -294,16 +294,16 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, */ XTCDECL EFI_STATUS -BlGetVolumeDevicePath(IN PCHAR SystemPath, +BlGetVolumeDevicePath(IN PWCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PCHAR *ArcName, - OUT PCHAR *Path) + OUT PWCHAR *ArcName, + OUT PWCHAR *Path) { PEFI_BLOCK_DEVICE Device; USHORT DriveType; ULONG DriveNumber; ULONG PartNumber; - PCHAR Volume; + PWCHAR Volume; ULONG PathLength; PLIST_ENTRY ListEntry; EFI_STATUS Status; @@ -333,13 +333,13 @@ BlGetVolumeDevicePath(IN PCHAR SystemPath, if(PathLength == GUID_STRING_LENGTH) { /* This is EFI GUID */ - BlDebugPrint(L"EFI/GPT GUID in system path is not supported yet\n"); + BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else if(PathLength == PARTUUID_STRING_LENGTH) { /* This is MBR UUID */ - BlDebugPrint(L"MBR partition UUID in system path is not supported yet\n"); + BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else @@ -358,7 +358,7 @@ BlGetVolumeDevicePath(IN PCHAR SystemPath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse system path */ - BlDebugPrint(L"Failed to parse system path: '%s' with status code: %lx\n", SystemPath, Status); + BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%lx)\n", SystemPath, Status); return Status; } @@ -382,7 +382,7 @@ BlGetVolumeDevicePath(IN PCHAR SystemPath, if(*DevicePath == NULL) { /* Failed to find volume */ - BlDebugPrint(L"Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", + BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", DriveType, DriveNumber, PartNumber); return STATUS_EFI_NOT_FOUND; } @@ -617,7 +617,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS) { /* Failed to locate handles */ - BlDebugPrint(L"ERROR: Failed to locate block devices handles (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%lx)\n", Status); return Status; } @@ -634,7 +634,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS || Io == NULL) { /* Failed to open I/O protocol, skip it */ - BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (status code: %lx)\n", Status); + BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%lx)\n", Status); continue; } @@ -652,7 +652,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) { /* Device failed to handle DP protocol */ - BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (status code: %lx)\n", Status); + BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%lx)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); continue; } @@ -662,7 +662,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - BlDebugPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); return Status; @@ -705,14 +705,14 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) */ XTCDECL EFI_STATUS -BlpDissectVolumeArcPath(IN PCHAR SystemPath, - OUT PCHAR *ArcName, - OUT PCHAR *Path, +BlpDissectVolumeArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, OUT PUSHORT DriveType, OUT PULONG DriveNumber, OUT PULONG PartNumber) { - PCHAR ArcPath, LocalArcName; + PWCHAR ArcPath, LocalArcName; ULONG ArcLength = 0; /* Set default values */ @@ -721,20 +721,20 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, *PartNumber = 0; /* Look for the ARC path */ - if(RtlCompareStringInsensitive(SystemPath, "ramdisk(0)", 0) == 0) + if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0) { /* This is RAM disk */ ArcLength = 10; *DriveType = XTBL_BOOT_DEVICE_RAMDISK; } - else if(RtlCompareStringInsensitive(SystemPath, "multi(0)disk(0)", 0) == 0) + else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) { /* This is a multi-disk port */ ArcLength = 15; ArcPath = SystemPath + ArcLength; /* Check for disk type */ - if(RtlCompareStringInsensitive(ArcPath, "cdrom(", 0) == 0) + if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0) { /* This is an optical drive */ ArcLength += 6; @@ -755,7 +755,7 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_CDROM; ArcLength++; } - else if(RtlCompareStringInsensitive(ArcPath, "fdisk(", 0) == 0) + else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) { /* This is a floppy drive */ ArcLength += 6; @@ -776,7 +776,7 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_FLOPPY; ArcLength++; } - else if(RtlCompareStringInsensitive(ArcPath, "rdisk(", 0) == 0) + else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) { /* This is a hard disk */ ArcLength += 6; @@ -799,7 +799,7 @@ BlpDissectVolumeArcPath(IN PCHAR SystemPath, ArcPath = SystemPath + ArcLength; /* Look for a partition */ - if(RtlCompareStringInsensitive(ArcPath, "partition(", 0) == 0) + if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) { /* Partition information found */ ArcLength += 10; @@ -893,7 +893,7 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ - BlDebugPrint(L"ERROR: Unable to allocate memory pool for device path duplicate\n"); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%lx)\n", Status); return NULL; } -- 2.45.1 From aa4f917fa7dee158a58d23d420a21b0c25abc4c8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 19:57:41 +0100 Subject: [PATCH 106/182] Allocate and copy the appropriate amount of memory --- xtldr2/volume.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xtldr2/volume.c b/xtldr2/volume.c index c4ded1b..32cfed7 100644 --- a/xtldr2/volume.c +++ b/xtldr2/volume.c @@ -839,8 +839,8 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, /* Store ARC name if possible */ if(ArcName) { - BlMemoryAllocatePool(ArcLength, (PVOID *)&LocalArcName); - RtlCopyMemory(LocalArcName, SystemPath, ArcLength); + BlMemoryAllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); + RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); LocalArcName[ArcLength] = '\0'; *ArcName = LocalArcName; } -- 2.45.1 From b4ef1932ab03c32f56c07aea9f90fee9b5cc6c5c Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 00:21:41 +0100 Subject: [PATCH 107/182] Add support for boot protocols --- sdk/xtdk/bltypes.h | 30 +++++++++- sdk/xtdk/xtstruct.h | 7 ++- xtldr2/efiutils.c | 3 +- xtldr2/globals.c | 3 + xtldr2/includes/bootman.h | 14 +++++ xtldr2/includes/globals.h | 3 + xtldr2/protocol.c | 112 ++++++++++++++++++++++++++++++++++++-- xtldr2/xtldr.c | 37 ++++++++++--- 8 files changed, 192 insertions(+), 17 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 687684e..23192bd 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -50,6 +50,7 @@ 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_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); @@ -64,12 +65,15 @@ typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); +typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); +typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); +typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); @@ -92,6 +96,12 @@ typedef struct _XTBL_BOOT_PARAMETERS PWCHAR Parameters; } XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; +/* Boot protocol structure */ +typedef struct _XTBL_BOOT_PROTOCOL +{ + PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; +} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; + /* Boot menu list structure */ typedef struct _XTBL_BOOTMENU_ITEM { @@ -129,9 +139,25 @@ typedef struct _XTBL_DIALOG_HANDLE UINT_PTR Height; } XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; +/* Registered boot protocol structure */ +typedef struct _XTBL_KNOWN_BOOT_PROTOCOL +{ + LIST_ENTRY Flink; + PWCHAR SystemType; + EFI_GUID Guid; +} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; + /* XTLDR Loader protocol */ typedef struct _XTBL_LOADER_PROTOCOL { + struct + { + PBL_FIND_BOOT_PROTOCOL FindProtocol; + PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeMenuList; + PBL_INVOKE_BOOT_PROTOCOL InvokeProtocol; + PBL_REGISTER_XT_BOOT_MENU RegisterMenu; + PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol; + } Boot; struct { PBL_CLEAR_CONSOLE_LINE ClearLine; @@ -165,9 +191,7 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { - PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeBootMenuList; - PBL_OPEN_XT_PROTOCOL OpenProtocol; - PBL_REGISTER_XT_BOOT_MENU RegisterBootMenu; + PBL_OPEN_XT_PROTOCOL Open; } Protocol; struct { diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index b005bfd..a8835f4 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -264,12 +264,17 @@ typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRM typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32; typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64; +typedef struct _XTBL_BOOT_PARAMETERS XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; +typedef struct _XTBL_BOOT_PROTOCOL XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; -typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS; +typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; +typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; +typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; +typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS; /* Unions forward references */ typedef union _EFI_DEV_PATH EFI_DEV_PATH, *PEFI_DEV_PATH; diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index a41b5a5..41e7f5a 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -143,7 +143,8 @@ BlpInitializeEfiBootLoader() /* Print XTLDR version */ BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - /* Initialize XTLDR configuration and loaded modules lists */ + /* Initialize XTLDR configuration linked lists */ + RtlInitializeListHead(&BlpBootProtocols); RtlInitializeListHead(&BlpConfig); RtlInitializeListHead(&BlpLoadedModules); diff --git a/xtldr2/globals.c b/xtldr2/globals.c index 431c828..cbfc400 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -9,6 +9,9 @@ #include +/* XT Boot Loader registered boot protocol list */ +LIST_ENTRY BlpBootProtocols; + /* XT Boot Loader configuration list */ LIST_ENTRY BlpConfig; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 8bec805..246096b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -78,6 +78,11 @@ XTCDECL EFI_STATUS BlExitBootServices(IN UINT_PTR MapKey); +XTCDECL +EFI_STATUS +BlFindBootProtocol(IN PWCHAR SystemType, + OUT PEFI_GUID BootProtocolGuid); + XTCDECL EFI_STATUS BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, @@ -105,6 +110,10 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +XTCDECL +EFI_STATUS +BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); + XTCDECL EFI_STATUS BlLoadModule(IN PWCHAR ModuleName); @@ -163,6 +172,11 @@ XTCDECL VOID BlRegisterBootMenu(PVOID BootMenuRoutine); +XTCDECL +EFI_STATUS +BlRegisterBootProtocol(IN PWCHAR SystemType, + IN PEFI_GUID BootProtocolGuid); + XTCDECL VOID BlResetConsoleInputBuffer(); diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 5fe9363..b5eed43 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -12,6 +12,9 @@ #include +/* XT Boot Loader registered boot protocol list */ +EXTERN LIST_ENTRY BlpBootProtocols; + /* XT Boot Loader configuration list */ EXTERN LIST_ENTRY BlpConfig; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index ac743e2..3ba341e 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -9,6 +9,49 @@ #include +/** + * Finds a boot protocol for specified system type. + * + * @param SystemType + * Specifies the system type to search for. + * + * @param BootProtocolGuid + * Receives the GUID of the registered boot protocol, that supports specified system. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlFindBootProtocol(IN PWCHAR SystemType, + OUT PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + + ProtocolListEntry = BlpBootProtocols.Flink; + while(ProtocolListEntry != &BlpBootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if this boot protocol supports specified system */ + if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol matched, return success */ + BootProtocolGuid = &ProtocolEntry->Guid; + return STATUS_EFI_SUCCESS; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Boot protocol not found, return error */ + return STATUS_EFI_NOT_FOUND; +} + /** * Loads a specified XTLDR module from disk. * @@ -287,7 +330,7 @@ BlLoadModules(IN PWCHAR ModulesList) * @param ProtocolGuid * Supplies a pointer to the unique protocol GUID. * - * @return This routine returns status code. + * @return This routine returns a status code. * * @since XT 1.0 */ @@ -361,10 +404,66 @@ BlRegisterBootMenu(PVOID BootMenuRoutine) BlpStatus.BootMenu = BootMenuRoutine; } +/** + * Registers a known boot protocol for a specified OS. + * + * @param SystemType + * Supplies the type of the OS, such as "LINUX", "XTOS", etc. that is supported by the boot protocol. + * + * @param BootProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlRegisterBootProtocol(IN PWCHAR SystemType, + IN PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + EFI_STATUS Status; + + ProtocolListEntry = BlpBootProtocols.Flink; + while(ProtocolListEntry != &BlpBootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if boot protocol already registered for specified system */ + if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol already registered */ + return STATUS_EFI_ABORTED; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Create new boot protocol entry */ + Status = BlMemoryAllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Set protocol properties and add it to the list */ + ProtocolEntry->SystemType = SystemType; + ProtocolEntry->Guid = *BootProtocolGuid; + RtlInsertTailList(&BlpBootProtocols, &ProtocolEntry->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * This routine registers XTLDR protocol for further usage by modules. * - * @return This routine returns status code. + * @return This routine returns a status code. * * @since XT 1.0 */ @@ -377,6 +476,11 @@ BlpRegisterXtLoaderProtocol() EFI_HANDLE Handle = NULL; /* Set all routines available via loader protocol */ + LdrProtocol.Boot.FindProtocol = BlFindBootProtocol; + LdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; + LdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; + LdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; + LdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; LdrProtocol.Console.ClearLine = BlClearConsoleLine; LdrProtocol.Console.ClearScreen = BlClearConsoleScreen; LdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; @@ -396,9 +500,7 @@ BlpRegisterXtLoaderProtocol() LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; LdrProtocol.Memory.FreePages = BlMemoryFreePages; LdrProtocol.Memory.FreePool = BlMemoryFreePool; - LdrProtocol.Protocol.InitializeBootMenuList = BlInitializeBootMenuList; - LdrProtocol.Protocol.OpenProtocol = BlOpenXtProtocol; - LdrProtocol.Protocol.RegisterBootMenu = BlRegisterBootMenu; + LdrProtocol.Protocol.Open = BlOpenXtProtocol; LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 8a4e324..921104c 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -111,10 +111,12 @@ EFI_STATUS BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) { XTBL_BOOT_PARAMETERS BootParameters; - PWCHAR ModulesList; + PXTBL_BOOT_PROTOCOL BootProtocol; PLIST_ENTRY OptionsListEntry; PXTBL_CONFIG_ENTRY Option; + EFI_GUID BootProtocolGuid; SIZE_T ModuleListLength; + PWCHAR ModulesList; EFI_STATUS Status; /* Initialize boot parameters */ @@ -151,8 +153,14 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) { - /* System path found, get boot volume */ - + /* System path found, get volume device path */ + Status = BlGetVolumeDevicePath((PWCHAR)Option->Value, &BootParameters.DevicePath, &BootParameters.ArcName, &BootParameters.SystemPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to find volume */ + BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%lx)\n", Status); + return Status; + } } else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) { @@ -188,11 +196,26 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) return STATUS_EFI_NOT_READY; } - // TODO: Add support for boot protocol and invoke it - return STATUS_EFI_UNSUPPORTED; + /* Attempt to get boot protocol GUID */ + Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get boot protocol GUID */ + BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%lx)\n", Status); + return STATUS_EFI_UNSUPPORTED; + } - /* This point should never be reached */ - return STATUS_EFI_SUCCESS; + /* Open boot protocol */ + Status = BlOpenXtProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open boot protocol */ + BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%lx)\n", Status); + return Status; + } + + /* Boot Operating System */ + return BootProtocol->BootSystem(&BootParameters); } /** -- 2.45.1 From fc3d23640510b3ea0d061988932ade01141e5c36 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 00:30:18 +0100 Subject: [PATCH 108/182] Load boot loader modules --- xtldr2/xtldr.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 921104c..4d8895a 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -300,6 +300,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, return Status; } + /* Load boot loader modules */ + Status = BlLoadModules(BlGetConfigValue(L"MODULES")); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load modules */ + BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); + } + /* Discover and enumerate EFI block devices */ Status = BlEnumerateBlockDevices(); if(Status != STATUS_EFI_SUCCESS) @@ -309,10 +318,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, return Status; } - BlLoadModules(BlGetConfigValue(L"MODULES")); - - BlLoadModule(L"DUMMY"); - BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); PLIST_ENTRY ModuleListEntry; -- 2.45.1 From 167c09be0a75d72da11b77e3a7a1f0945c3bbe08 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 00:37:01 +0100 Subject: [PATCH 109/182] Move XTLDR initialization code out of EFI utils --- xtldr2/efiutils.c | 55 ------------------------------------- xtldr2/includes/bootman.h | 8 +++--- xtldr2/xtldr.c | 57 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/xtldr2/efiutils.c b/xtldr2/efiutils.c index 41e7f5a..34dac18 100644 --- a/xtldr2/efiutils.c +++ b/xtldr2/efiutils.c @@ -118,58 +118,3 @@ BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, { return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); } - -/** - * Initializes EFI Boot Loader (XTLDR). - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpInitializeEfiBootLoader() -{ - EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - EFI_STATUS Status; - - /* Set current XTLDR's EFI BootServices status */ - BlpStatus.BootServices = TRUE; - - /* Initialize console */ - BlpInitializeConsole(); - - /* Print XTLDR version */ - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - - /* Initialize XTLDR configuration linked lists */ - RtlInitializeListHead(&BlpBootProtocols); - RtlInitializeListHead(&BlpConfig); - RtlInitializeListHead(&BlpLoadedModules); - - /* Store SecureBoot status */ - BlpStatus.SecureBoot = BlGetSecureBootStatus(); - - /* Check if debug is enabled */ - if(DEBUG) - { - /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenXtProtocol((PVOID *)&LoadedImage, &LipGuid); - if(Status == STATUS_EFI_SUCCESS) - { - /* Protocol opened successfully, print useful debug information */ - BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" - L"Pointer Size : %d\n" - L"Image Base Address: 0x%lx\n" - L"Image Base Size : 0x%lx\n" - L"Image Revision : 0x%lx\n" - L"--------------------------------------\n", - sizeof(PVOID), - LoadedImage->ImageBase, - LoadedImage->ImageSize, - LoadedImage->Revision); - BlSleepExecution(3000); - } - } -} diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 246096b..3f8bfc0 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -104,6 +104,10 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, OUT PWCHAR *ArcName, OUT PWCHAR *Path); +XTCDECL +VOID +BlInitializeBootLoader(); + XTCDECL VOID BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, @@ -309,10 +313,6 @@ XTCDECL EFI_STATUS BlpInitializeDebugConsole(); -XTCDECL -VOID -BlpInitializeEfiBootLoader(); - XTCDECL EFI_STATUS BlpInitializeSerialPort(IN ULONG PortNumber, diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 4d8895a..7fd32ef 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,6 +9,61 @@ #include +/** + * Initializes EFI Boot Loader (XTLDR). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlInitializeBootLoader() +{ + EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + EFI_STATUS Status; + + /* Set current XTLDR's EFI BootServices status */ + BlpStatus.BootServices = TRUE; + + /* Initialize console */ + BlpInitializeConsole(); + + /* Print XTLDR version */ + BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + + /* Initialize XTLDR configuration linked lists */ + RtlInitializeListHead(&BlpBootProtocols); + RtlInitializeListHead(&BlpConfig); + RtlInitializeListHead(&BlpLoadedModules); + + /* Store SecureBoot status */ + BlpStatus.SecureBoot = BlGetSecureBootStatus(); + + /* Check if debug is enabled */ + if(DEBUG) + { + /* Attempt to open EFI LoadedImage protocol */ + Status = BlOpenXtProtocol((PVOID *)&LoadedImage, &LipGuid); + if(Status == STATUS_EFI_SUCCESS) + { + /* Protocol opened successfully, print useful debug information */ + BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" + L"Pointer Size : %d\n" + L"Image Base Address: 0x%lx\n" + L"Image Base Size : 0x%lx\n" + L"Image Revision : 0x%lx\n" + L"--------------------------------------\n", + sizeof(PVOID), + LoadedImage->ImageBase, + LoadedImage->ImageSize, + LoadedImage->Revision); + BlSleepExecution(3000); + } + } +} + /** * Initializes a list of operating systems for XTLDR boot menu. * @@ -243,7 +298,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiSystemTable = SystemTable; /* Initialize XTLDR and */ - BlpInitializeEfiBootLoader(); + BlInitializeBootLoader(); /* Parse configuration options passed from UEFI shell */ Status = BlpParseCommandLine(); -- 2.45.1 From 096b65c43206171744389da77a18b3d586ce0b5e Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 00:44:25 +0100 Subject: [PATCH 110/182] Update boot loader configuration file --- bootdata/xtldr/xtldr.ini | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bootdata/xtldr/xtldr.ini b/bootdata/xtldr/xtldr.ini index 9b59049..124a8f4 100644 --- a/bootdata/xtldr/xtldr.ini +++ b/bootdata/xtldr/xtldr.ini @@ -8,7 +8,7 @@ # Default - specifies which operating system listen in config file will be started if no choice is made # Modules - supplies a list of modules that will be loaded in orded to extend XTLDR functionality # 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 +# Tune - plays a tune on the pcspeaker right before the XTLDR boot menu shows up # # Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type # of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored @@ -32,14 +32,15 @@ Tune=400 880 2 988 2 783 2 392 2 587 3 [ExectOS] SystemName="ExectOS Operating System" SystemType=XTOS -BootModules=pecoff xtos +BootModules=xtos SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS KernelFile=xtoskrnl.exe -Parameters=DEBUG DEBUGPORT=COM1,115200 +Parameters=DEBUG=COM1,115200 [Windows] SystemName="Microsoft Windows 2000" SystemType=NT50 +BootModules=ntos SystemPath=multi(0)disk(0)rdisk(0)partition(2)/Windows KernelFile=ntoskrnl.exe HalFile=hal.dll @@ -48,7 +49,7 @@ Parameters=/NOGUIBOOT /MININT [Linux] SystemName="GNU/Linux" SystemType=LINUX -BootModules=elf linux +BootModules=linux SystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot KernelFile=vmlinuz InitrdFile=initramfs.cpio.gz -- 2.45.1 From 05865fd4c06c9aaacd8eb3595a264f75dc791b28 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 15:54:05 +0100 Subject: [PATCH 111/182] Initial version of XTBL_EXECUTABLE_IMAGE_PROTOCOL --- sdk/xtdk/bltypes.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 23192bd..ceba425 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -83,6 +83,26 @@ typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PW typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); typedef VOID (*PBL_XT_BOOT_MENU)(); +/* XTLDR Boot protocol structure */ +typedef struct _XTBL_BOOT_PROTOCOL +{ + PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; +} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; + +/* XTLDR Executable image protocol structure */ +typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL +{ + // PBL_EXECIMAGE_GET_ENTRY_POINT GetEntryPoint; + // PBL_EXECIMAGE_GET_MACHINE_TYPE GetMachineType; + // PBL_EXECIMAGE_GET_SECTION GetSection; + // PBL_EXECIMAGE_GET_SUBSYSTEM GetSubSystem; + // PBL_EXECIMAGE_GET_VERSION GetVersion; + // PBL_EXECIMAGE_LOAD_IMAGE LoadImage; + // PBL_EXECIMAGE_PRINT_INFO PrintDebugInfo; + // PBL_EXECIMAGE_RELOCATE_IMAGE RelocateImage; + // PBL_EXECUTABLE_VERIFY_IMAGE VerifyImage; +} XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL; + /* Boot parameters structure */ typedef struct _XTBL_BOOT_PARAMETERS { @@ -96,12 +116,6 @@ typedef struct _XTBL_BOOT_PARAMETERS PWCHAR Parameters; } XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS; -/* Boot protocol structure */ -typedef struct _XTBL_BOOT_PROTOCOL -{ - PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; -} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; - /* Boot menu list structure */ typedef struct _XTBL_BOOTMENU_ITEM { -- 2.45.1 From 835d2f3551c5b6f7b1714cdcc42f3aa5e90d02df Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 31 Dec 2023 16:22:03 +0100 Subject: [PATCH 112/182] Comment out unnecessary code --- xtldr2/xtldr.c | 72 ++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 7fd32ef..1efd698 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -374,42 +374,44 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } - BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); - PLIST_ENTRY ModuleListEntry; - PXTBL_MODULE_INFO ModuleInfo; + // BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); + // PLIST_ENTRY ModuleListEntry; + // PXTBL_MODULE_INFO ModuleInfo; - ModuleListEntry = BlpLoadedModules.Flink; - while(ModuleListEntry != &BlpLoadedModules) - { - /* Get module information */ - ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - /* Module already loaded */ - BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); - if(ModuleInfo->ModuleDescription != 0) - { - BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); - } - - PLIST_ENTRY DepsListEntry; - PXTBL_MODULE_DEPS DepsInfo; - BlConsolePrint(L"\n - Uses: "); - DepsListEntry = ModuleInfo->Dependencies.Flink; - while(DepsListEntry != &ModuleInfo->Dependencies) - { - DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); - BlConsolePrint(L"%S ", DepsInfo->ModuleName); - DepsListEntry = DepsListEntry->Flink; - } - - /* Move to the module */ - ModuleListEntry = ModuleListEntry->Flink; - } - - BlConsolePrint(L"\n\n END OF LIST\n"); - - for(;;) + // ModuleListEntry = BlpLoadedModules.Flink; + // while(ModuleListEntry != &BlpLoadedModules) + // { + // /* Get module information */ + // ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + // /* Module already loaded */ + // BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); + // if(ModuleInfo->ModuleDescription != 0) + // { + // BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); + // } + + // PLIST_ENTRY DepsListEntry; + // PXTBL_MODULE_DEPS DepsInfo; + // BlConsolePrint(L"\n - Uses: "); + // DepsListEntry = ModuleInfo->Dependencies.Flink; + // while(DepsListEntry != &ModuleInfo->Dependencies) + // { + // DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); + // BlConsolePrint(L"%S ", DepsInfo->ModuleName); + // DepsListEntry = DepsListEntry->Flink; + // } + + // /* Move to the module */ + // ModuleListEntry = ModuleListEntry->Flink; + // } + + // BlConsolePrint(L"\n\n END OF LIST\n"); + + /* Main boot loader loop */ + while(TRUE) { + /* Check if custom boot menu registered */ if(BlpStatus.BootMenu != NULL) { /* Display alternative boot menu */ @@ -420,6 +422,8 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, /* Display default boot menu */ BlDisplayBootMenu(); } + + /* Fallback to shell, if boot menu returned */ } /* This point should be never reached, if this happen return error code */ -- 2.45.1 From e728b9d299afc690f8f4068c7bdff07a039ece75 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 14:05:48 +0100 Subject: [PATCH 113/182] Loader protocol must be globally accessible --- xtldr2/globals.c | 3 ++ xtldr2/includes/bootman.h | 4 +- xtldr2/includes/globals.h | 2 + xtldr2/protocol.c | 77 +++++++++++++++++++-------------------- xtldr2/xtldr.c | 4 +- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/xtldr2/globals.c b/xtldr2/globals.c index cbfc400..4a6a286 100644 --- a/xtldr2/globals.c +++ b/xtldr2/globals.c @@ -21,6 +21,9 @@ LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; +/* XT Boot Loader protocol */ +XTBL_LOADER_PROTOCOL BlpLdrProtocol; + /* XT Boot Loader loaded modules list */ LIST_ENTRY BlpLoadedModules; diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 3f8bfc0..59a34c2 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -153,8 +153,8 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, XTCDECL EFI_STATUS -BlOpenXtProtocol(OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); +BlOpenProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); XTCDECL VOID diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index b5eed43..0e6402a 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -24,6 +24,8 @@ EXTERN LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; +EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol; + /* XT Boot Loader loaded modules list */ EXTERN LIST_ENTRY BlpLoadedModules; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 3ba341e..503eaa7 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -308,7 +308,7 @@ BlLoadModules(IN PWCHAR ModulesList) if(Status != STATUS_EFI_SUCCESS) { /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); + BlDebugPrint(L"ERROR: Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); ReturnStatus = STATUS_EFI_LOAD_ERROR; } @@ -322,7 +322,7 @@ BlLoadModules(IN PWCHAR ModulesList) } /** - * This routine locates and opens the requested XT boot loader protocol. + * This routine locates and opens the requested XT Boot Loader or EFI protocol. * * @param ProtocolHandler * Supplies the address where a pointer to the opened protocol is returned. @@ -336,8 +336,8 @@ BlLoadModules(IN PWCHAR ModulesList) */ XTCDECL EFI_STATUS -BlOpenXtProtocol(OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid) +BlOpenProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) { PEFI_HANDLE Handles = NULL; EFI_STATUS Status; @@ -472,45 +472,44 @@ 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.Boot.FindProtocol = BlFindBootProtocol; - LdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; - LdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; - LdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; - LdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; - LdrProtocol.Console.ClearLine = BlClearConsoleLine; - LdrProtocol.Console.ClearScreen = BlClearConsoleScreen; - LdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; - LdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; - LdrProtocol.Console.Print = BlConsolePrint; - LdrProtocol.Console.QueryMode = BlQueryConsoleMode; - LdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; - LdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; - LdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; - LdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; - LdrProtocol.Console.Write = BlConsoleWrite; - LdrProtocol.Debug.Print = BlDebugPrint; - LdrProtocol.Disk.CloseVolume = BlCloseVolume; - LdrProtocol.Disk.OpenVolume = BlOpenVolume; - LdrProtocol.Disk.ReadFile = BlReadFile; - LdrProtocol.Memory.AllocatePages = BlMemoryAllocatePages; - LdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; - LdrProtocol.Memory.FreePages = BlMemoryFreePages; - LdrProtocol.Memory.FreePool = BlMemoryFreePool; - LdrProtocol.Protocol.Open = BlOpenXtProtocol; - LdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; - LdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; - LdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; - LdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; - LdrProtocol.Util.ExitBootServices = BlExitBootServices; - LdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; - LdrProtocol.Util.SleepExecution = BlSleepExecution; - LdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; + BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol; + BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; + BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; + BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; + BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; + BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; + BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; + BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; + BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; + BlpLdrProtocol.Console.Print = BlConsolePrint; + BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode; + BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; + BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; + BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; + BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; + BlpLdrProtocol.Console.Write = BlConsoleWrite; + BlpLdrProtocol.Debug.Print = BlDebugPrint; + BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume; + BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume; + BlpLdrProtocol.Disk.ReadFile = BlReadFile; + BlpLdrProtocol.Memory.AllocatePages = BlMemoryAllocatePages; + BlpLdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; + BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages; + BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool; + BlpLdrProtocol.Protocol.Open = BlOpenProtocol; + BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; + BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; + BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; + BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; + BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices; + BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; + BlpLdrProtocol.Util.SleepExecution = BlSleepExecution; + BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, &LdrProtocol); + return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, &BlpLdrProtocol); } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 1efd698..e1c5230 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -45,7 +45,7 @@ BlInitializeBootLoader() if(DEBUG) { /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenXtProtocol((PVOID *)&LoadedImage, &LipGuid); + Status = BlOpenProtocol((PVOID *)&LoadedImage, &LipGuid); if(Status == STATUS_EFI_SUCCESS) { /* Protocol opened successfully, print useful debug information */ @@ -261,7 +261,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } /* Open boot protocol */ - Status = BlOpenXtProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); + Status = BlOpenProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open boot protocol */ -- 2.45.1 From f4871801a7ec8155684188be22847b5f31e77ca8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 14:18:50 +0100 Subject: [PATCH 114/182] Implement BlGetXtLdrProtocol() --- sdk/xtdk/blfuncs.h | 23 +++++++++++++++ sdk/xtdk/xtblapi.h | 1 + xtldr2/protocol.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 sdk/xtdk/blfuncs.h diff --git a/sdk/xtdk/blfuncs.h b/sdk/xtdk/blfuncs.h new file mode 100644 index 0000000..77e0bf1 --- /dev/null +++ b/sdk/xtdk/blfuncs.h @@ -0,0 +1,23 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/blfuncs.h + * DESCRIPTION: XT Boot Manager routines + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTDK_BLFUNCS_H +#define __XTDK_BLFUNCS_H + +#include +#include + + +/* XT BootLoader routines forward references */ +XTCDECL +EFI_STATUS +BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, + IN EFI_HANDLE ImageHandle, + OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler); + +#endif /* __XTDK_BLFUNCS_H */ diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index f58c149..5da87e8 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -45,3 +45,4 @@ /* Boot Manager specific structures */ #include +#include diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 503eaa7..13afe52 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -52,6 +52,76 @@ BlFindBootProtocol(IN PWCHAR SystemType, return STATUS_EFI_NOT_FOUND; } +/** + * Finds and opens the XT Boot Loader protocol. This routine should be called by module to access XTLDR protocol. + * + * @param SystemTable + * Provides the EFI system table. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param ProtocolHandler + * Receives the pointer to the XT Boot Loader protocol. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, + IN EFI_HANDLE ImageHandle, + OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler) +{ + EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + PEFI_HANDLE Handles = NULL; + EFI_STATUS Status; + UINT_PTR Count; + UINT Index; + + /* Try to locate the handles */ + Status = SystemTable->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 = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid, + (PVOID*)ProtocolHandler, ImageHandle, 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 */ + SystemTable->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; +} + /** * Loads a specified XTLDR module from disk. * -- 2.45.1 From 89caaa977e3067b33aebc5fec3706e1c579c4801 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 16:16:35 +0100 Subject: [PATCH 115/182] Fix how GUID is passed to BlInvokeBootProtocol() --- xtldr2/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 13afe52..bf10273 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -40,7 +40,7 @@ BlFindBootProtocol(IN PWCHAR SystemType, if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) { /* Boot protocol matched, return success */ - BootProtocolGuid = &ProtocolEntry->Guid; + *BootProtocolGuid = ProtocolEntry->Guid; return STATUS_EFI_SUCCESS; } -- 2.45.1 From 35f36adfa6be12916b2c99fc3c7cdd21c71cdbdf Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 16:28:29 +0100 Subject: [PATCH 116/182] Update dummy module --- xtldr2/modules/dummy/dummy.c | 37 ++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index cc24ebb..26e90b6 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -11,7 +11,20 @@ /* Dummy module information */ XTBL_MODINFO = L"Dummy XTLDR module"; -XTBL_MODDEPS = {L"dummy2"}; +// XTBL_MODDEPS = {L"dummy2"}; + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL XtLdrProto; + +/* Dummy Boot Protocol handler */ +XTBL_BOOT_PROTOCOL DummyProtocol; + +XTCDECL +EFI_STATUS +BootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters) +{ + return STATUS_EFI_SUCCESS; +} /** * This routine is the entry point of the XT EFI boot loader module. @@ -31,5 +44,25 @@ EFI_STATUS XtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { - return STATUS_EFI_SUCCESS; + EFI_GUID DummyGuid = XT_XTOS_BOOT_PROTOCOL_GUID; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProto); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the protocol, return error */ + return STATUS_EFI_LOAD_ERROR; + } + + /* Set boot protocol routines */ + DummyProtocol.BootSystem = BootDummyOS; + + /* Register XTOS boot protocol */ + XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid); + + /* Register DUMMY protocol as XTOS boot protocol */ + return SystemTable->BootServices->InstallProtocolInterface(&Handle, &DummyGuid, EFI_NATIVE_INTERFACE, + &DummyProtocol); } -- 2.45.1 From 09ca6dace9f2902ba79648fe6cc1bf25b29bc701 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 19:27:51 +0100 Subject: [PATCH 117/182] Implement BlRegisterProtocol() routine --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/includes/bootman.h | 5 +++++ xtldr2/modules/dummy/dummy.c | 4 +--- xtldr2/protocol.c | 25 +++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index ceba425..e910672 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -74,6 +74,7 @@ typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, O typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); +typedef EFI_STATUS (*PBL_REGISTER_XT_PROTOCOL)(IN PEFI_GUID Guid, IN PVOID Interface); typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); @@ -206,6 +207,7 @@ typedef struct _XTBL_LOADER_PROTOCOL struct { PBL_OPEN_XT_PROTOCOL Open; + PBL_REGISTER_XT_PROTOCOL Register; } Protocol; struct { diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 59a34c2..3d19134 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -181,6 +181,11 @@ EFI_STATUS BlRegisterBootProtocol(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); +XTCDECL +EFI_STATUS +BlRegisterProtocol(IN PEFI_GUID Guid, + IN PVOID Interface); + XTCDECL VOID BlResetConsoleInputBuffer(); diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index 26e90b6..4aa9d65 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -45,7 +45,6 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { EFI_GUID DummyGuid = XT_XTOS_BOOT_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; EFI_STATUS Status; /* Open the XTLDR protocol */ @@ -63,6 +62,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid); /* Register DUMMY protocol as XTOS boot protocol */ - return SystemTable->BootServices->InstallProtocolInterface(&Handle, &DummyGuid, EFI_NATIVE_INTERFACE, - &DummyProtocol); + return XtLdrProto->Protocol.Register(&DummyGuid, &DummyProtocol); } diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index bf10273..f004310 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -530,6 +530,30 @@ BlRegisterBootProtocol(IN PWCHAR SystemType, return STATUS_EFI_SUCCESS; } +/** + * Installs XTLDR protocol interface. + * + * @param Guid + * Specifies a unique protocol GUID. + * + * @param Interface + * Supplies a pointer to the protocol interface, or NULL if there is no structure associated. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlRegisterProtocol(IN PEFI_GUID Guid, + IN PVOID Interface) +{ + EFI_HANDLE Handle = NULL; + + /* Install protocol interface */ + return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); +} + /** * This routine registers XTLDR protocol for further usage by modules. * @@ -570,6 +594,7 @@ BlpRegisterXtLoaderProtocol() BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages; BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool; BlpLdrProtocol.Protocol.Open = BlOpenProtocol; + BlpLdrProtocol.Protocol.Register = BlRegisterProtocol; BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; -- 2.45.1 From e1670e5d58e6f4d6427ec5736c6b30db6119b413 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 22:00:24 +0100 Subject: [PATCH 118/182] NULLify a list of modules --- xtldr2/xtldr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index e1c5230..c16021f 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -174,8 +174,9 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) PWCHAR ModulesList; EFI_STATUS Status; - /* Initialize boot parameters */ + /* Initialize boot parameters and a list of modules */ RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); + ModulesList = NULL; /* Iterate through all options provided by boot menu entry and propagate boot parameters */ OptionsListEntry = OptionsList->Flink; -- 2.45.1 From afb503961c1d8f6e3acc7b23896645d37a304aa8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 22:08:35 +0100 Subject: [PATCH 119/182] Add missing description for BlDisplayBootMenu() --- xtldr2/textui.c | 495 ++++++++++++++++++++++++------------------------ 1 file changed, 247 insertions(+), 248 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 0ec3605..6a9d6ba 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -9,6 +9,253 @@ #include +/** + * Displays a simple TUI-based boot menu. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayBootMenu() +{ + XTBL_DIALOG_HANDLE Handle; + PXTBL_BOOTMENU_ITEM MenuEntries = NULL; + ULONG Index, NumberOfEntries, HighligtedEntryId; + UINT_PTR EventIndex; + EFI_EVENT Events[2]; + EFI_INPUT_KEY Key; + EFI_EVENT TimerEvent; + EFI_STATUS Status; + LONG TimeOut; + PWCHAR TimeOutString; + + /* Initialize boot menu list */ + BlInitializeBootMenuList(MenuEntries, &NumberOfEntries, &HighligtedEntryId); + + /* Get timeout from the configuration */ + TimeOutString = BlGetConfigValue(L"TIMEOUT"); + TimeOut = -1; + + /* Check if timeout is specified */ + if(TimeOutString != NULL) + { + /* Convert timeout string to number */ + TimeOut = 0; + while(*TimeOutString >= '0' && *TimeOutString <= '9') + { + TimeOut *= 10; + TimeOut += *TimeOutString - '0'; + TimeOutString++; + } + } + + /* Infinite boot menu loop */ + while(TRUE) + { + /* Draw boot menu */ + BlpDrawBootMenu(&Handle); + + /* Check if there is anything to show in the boot menu */ + if(NumberOfEntries > 0) { + /* Iterate through all menu entries */ + for(Index = 0; Index < NumberOfEntries; Index++) + { + /* Draw menu entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[Index].EntryName, Index, Index == HighligtedEntryId); + } + } + else + { + /* No menu entries found, show error message */ + BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); + + /* Exit into XTLDR shell */ + return; + } + + /* Create a timer event for controlling the timeout of the boot menu */ + Status = EfiSystemTable->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, NULL, NULL, &TimerEvent); + if(Status == STATUS_EFI_SUCCESS) + { + /* Setup new EFI timer */ + Status = EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000); + } + + /* Check is EFI timer was successfully created */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Timer creation failed, disable the timer */ + TimeOut = -1; + } + + /* Initialize EFI events */ + Events[0] = EfiSystemTable->ConIn->WaitForKey; + Events[1] = TimerEvent; + + /* Infinite boot menu event loop */ + while(TRUE) + { + /* Wait for EFI event */ + BlWaitForEfiEvent(2, Events, &EventIndex); + + /* Check which event was received */ + if(EventIndex == 0) + { + /* Key pressed, check if timer is still active */ + if(TimeOut != -1) + { + /* Disable the timer */ + TimeOut = -1; + + /* Cancel timer event */ + EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); + + /* Remove the timer message */ + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + } + + /* Read key stroke */ + BlReadKeyStroke(&Key); + + if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) + { + /* ENTER or RightArrow key pressed, boot the highlighted OS */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); + + /* Boot the highlighted (chosen) OS */ + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + if(Status != STATUS_SUCCESS) + { + /* Failed to boot OS */ + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", + MenuEntries[HighligtedEntryId].EntryName, Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + } + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.ScanCode == 0x01) + { + /* UpArrow key pressed, go to previous entry if possible */ + if(HighligtedEntryId > 0) + { + /* Highlight previous entry */ + HighligtedEntryId--; + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, + HighligtedEntryId + 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, TRUE); + } + } + else if(Key.ScanCode == 0x02) + { + /* DownArrow key pressed, go to next entry if possible */ + if(HighligtedEntryId < NumberOfEntries - 1) + { + /* Highlight next entry */ + HighligtedEntryId++; + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, + HighligtedEntryId - 1, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, TRUE); + } + } + else if(Key.ScanCode == 0x09) + { + /* PageUp key pressed, go to top entry */ + if(HighligtedEntryId != 0) + { + /* Highlight first entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[0].EntryName, 0, TRUE); + + /* Update highlighted entry ID */ + HighligtedEntryId = 0; + } + } + else if(Key.ScanCode == 0x0A) + { + /* PageDown key pressed, go to bottom entry */ + if(HighligtedEntryId != NumberOfEntries - 1) + { + /* Highlight last entry */ + BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId, FALSE); + BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName, + NumberOfEntries - 1, TRUE); + + /* Update highlighted entry ID */ + HighligtedEntryId = NumberOfEntries - 1; + } + } + else if(Key.ScanCode == 0x0B) + { + /* F1 key pressed, show help */ + BlDisplayInfoDialog(L"XTLDR", L"XTLDR Boot Loader Help"); + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.UnicodeChar == 0x65) + { + /* 'e' key pressed, edit the highlighted entry */ + BlDisplayErrorDialog(L"XTLDR", L"Editing boot menu entries is not implemented yet!"); + + /* Break from boot menu event loop to redraw whole boot menu */ + break; + } + else if(Key.UnicodeChar == 0x73) + { + /* 's' key pressed, exit into XTLDR shell */ + return; + } + } + else + { + /* Timer tick, check if time out expired */ + if(TimeOut > 0) + { + /* Update a message and decrease timeout value */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); + TimeOut--; + } + else if(TimeOut == 0) + { + /* Time out expired, update a message */ + BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); + BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); + + /* Disable the timer just in case booting OS fails */ + TimeOut = -1; + + /* Boot the highlighted (default) OS */ + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + if(Status != STATUS_SUCCESS) + { + /* Failed to boot OS */ + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", + MenuEntries[HighligtedEntryId].EntryName, Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + } + break; + } + } + } + } +} + /** * Displays a red error dialog box with the specified caption and message. * @@ -960,251 +1207,3 @@ BlDisplayInputDialog(IN PWCHAR Caption, BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); BlClearConsoleScreen(); } - - - -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PLIST_ENTRY Options); - - - -XTCDECL -VOID -BlDisplayBootMenu() -{ - XTBL_DIALOG_HANDLE Handle; - PXTBL_BOOTMENU_ITEM MenuEntries = NULL; - ULONG Index, NumberOfEntries, HighligtedEntryId; - UINT_PTR EventIndex; - EFI_EVENT Events[2]; - EFI_INPUT_KEY Key; - EFI_EVENT TimerEvent; - EFI_STATUS Status; - LONG TimeOut; - PWCHAR TimeOutString; - - /* Initialize boot menu list */ - BlInitializeBootMenuList(MenuEntries, &NumberOfEntries, &HighligtedEntryId); - - /* Get timeout from the configuration */ - TimeOutString = BlGetConfigValue(L"TIMEOUT"); - TimeOut = -1; - - /* Check if timeout is specified */ - if(TimeOutString != NULL) - { - /* Convert timeout string to number */ - TimeOut = 0; - while(*TimeOutString >= '0' && *TimeOutString <= '9') - { - TimeOut *= 10; - TimeOut += *TimeOutString - '0'; - TimeOutString++; - } - } - - /* Infinite boot menu loop */ - while(TRUE) - { - /* Draw boot menu */ - BlpDrawBootMenu(&Handle); - - /* Check if there is anything to show in the boot menu */ - if(NumberOfEntries > 0) { - /* Iterate through all menu entries */ - for(Index = 0; Index < NumberOfEntries; Index++) - { - /* Draw menu entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[Index].EntryName, Index, Index == HighligtedEntryId); - } - } - else - { - /* No menu entries found, show error message */ - BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); - - /* Exit into XTLDR shell */ - return; - } - - /* Create a timer event for controlling the timeout of the boot menu */ - Status = EfiSystemTable->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, NULL, NULL, &TimerEvent); - if(Status == STATUS_EFI_SUCCESS) - { - /* Setup new EFI timer */ - Status = EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000); - } - - /* Check is EFI timer was successfully created */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Timer creation failed, disable the timer */ - TimeOut = -1; - } - - /* Initialize EFI events */ - Events[0] = EfiSystemTable->ConIn->WaitForKey; - Events[1] = TimerEvent; - - /* Infinite boot menu event loop */ - while(TRUE) - { - /* Wait for EFI event */ - BlWaitForEfiEvent(2, Events, &EventIndex); - - /* Check which event was received */ - if(EventIndex == 0) - { - /* Key pressed, check if timer is still active */ - if(TimeOut != -1) - { - /* Disable the timer */ - TimeOut = -1; - - /* Cancel timer event */ - EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); - - /* Remove the timer message */ - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - } - - /* Read key stroke */ - BlReadKeyStroke(&Key); - - if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) - { - /* ENTER or RightArrow key pressed, boot the highlighted OS */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); - - /* Boot the highlighted (chosen) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); - if(Status != STATUS_SUCCESS) - { - /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", - MenuEntries[HighligtedEntryId].EntryName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); - } - - /* Break from boot menu event loop to redraw whole boot menu */ - break; - } - else if(Key.ScanCode == 0x01) - { - /* UpArrow key pressed, go to previous entry if possible */ - if(HighligtedEntryId > 0) - { - /* Highlight previous entry */ - HighligtedEntryId--; - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, - HighligtedEntryId + 1, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId, TRUE); - } - } - else if(Key.ScanCode == 0x02) - { - /* DownArrow key pressed, go to next entry if possible */ - if(HighligtedEntryId < NumberOfEntries - 1) - { - /* Highlight next entry */ - HighligtedEntryId++; - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, - HighligtedEntryId - 1, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId, TRUE); - } - } - else if(Key.ScanCode == 0x09) - { - /* PageUp key pressed, go to top entry */ - if(HighligtedEntryId != 0) - { - /* Highlight first entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[0].EntryName, 0, TRUE); - - /* Update highlighted entry ID */ - HighligtedEntryId = 0; - } - } - else if(Key.ScanCode == 0x0A) - { - /* PageDown key pressed, go to bottom entry */ - if(HighligtedEntryId != NumberOfEntries - 1) - { - /* Highlight last entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName, - NumberOfEntries - 1, TRUE); - - /* Update highlighted entry ID */ - HighligtedEntryId = NumberOfEntries - 1; - } - } - else if(Key.ScanCode == 0x0B) - { - /* F1 key pressed, show help */ - BlDisplayInfoDialog(L"XTLDR", L"XTLDR Boot Loader Help"); - - /* Break from boot menu event loop to redraw whole boot menu */ - break; - } - else if(Key.UnicodeChar == 0x65) - { - /* 'e' key pressed, edit the highlighted entry */ - BlDisplayErrorDialog(L"XTLDR", L"Editing boot menu entries is not implemented yet!"); - - /* Break from boot menu event loop to redraw whole boot menu */ - break; - } - else if(Key.UnicodeChar == 0x73) - { - /* 's' key pressed, exit into XTLDR shell */ - return; - } - } - else - { - /* Timer tick, check if time out expired */ - if(TimeOut > 0) - { - /* Update a message and decrease timeout value */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); - TimeOut--; - } - else if(TimeOut == 0) - { - /* Time out expired, update a message */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); - - /* Disable the timer just in case booting OS fails */ - TimeOut = -1; - - /* Boot the highlighted (default) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); - if(Status != STATUS_SUCCESS) - { - /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", - MenuEntries[HighligtedEntryId].EntryName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); - } - break; - } - } - } - } -} -- 2.45.1 From e618f112b5ab1d38da0e4fb99b9f30e6fd978307 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 22:11:36 +0100 Subject: [PATCH 120/182] Use BlRegisterProtocol() wrapper --- xtldr2/protocol.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index f004310..5fbf82a 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -566,7 +566,6 @@ EFI_STATUS BlpRegisterXtLoaderProtocol() { EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; /* Set all routines available via loader protocol */ BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol; @@ -606,5 +605,5 @@ BlpRegisterXtLoaderProtocol() /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, &BlpLdrProtocol); + return BlRegisterProtocol(&Guid, &BlpLdrProtocol); } -- 2.45.1 From 46253c05039437603cd0234162c9173c7800a696 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 22:24:45 +0100 Subject: [PATCH 121/182] Limit number of boot menu entries to match box size, this usually should be enough to display all entries --- xtldr2/textui.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 6a9d6ba..2496027 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -59,6 +59,13 @@ BlDisplayBootMenu() /* Check if there is anything to show in the boot menu */ if(NumberOfEntries > 0) { + /* Check if all menu entries will fit into the menu box */ + if(NumberOfEntries > Handle.Height - 2) + { + /* Too many menu entries, limit entries to match box height (-2 for upper and bottom borders) */ + NumberOfEntries = Handle.Height - 2; + } + /* Iterate through all menu entries */ for(Index = 0; Index < NumberOfEntries; Index++) { -- 2.45.1 From acacc3f2e855f1b6c3ca05035100dafb95a04aa2 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 1 Jan 2024 23:02:27 +0100 Subject: [PATCH 122/182] Fix input field text positioning --- xtldr2/textui.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 2496027..5141a33 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -881,6 +881,7 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, WCHAR InputField[XTBL_TUI_MAX_DIALOG_WIDTH]; ULONG InputColor, TextColor; UINT_PTR Index, Position; + SIZE_T Length; /* Set dialog button colors */ if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) @@ -922,9 +923,27 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, BlDisableConsoleCursor(); BlConsoleWrite(InputField); + /* Check input field text length */ + Length = RtlWideStringLength(InputFieldText, 0); + if(Length > (Handle->Width - 9)) + { + /* Text longer than input field width, display only part of it */ + Length = Handle->Width - 9; + } + + /* Copy a part of input field text to input field */ + for(Index = 0; Index < Length; Index++) + { + /* Write input field text */ + InputField[Index] = InputFieldText[Index]; + } + + /* Add null terminator to the end of the line */ + InputField[Handle->Width] = 0; + /* Write input field text */ BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); - BlConsoleWrite(InputFieldText); + BlConsoleWrite(InputField); /* Check if this is an active input field */ if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) @@ -1178,21 +1197,18 @@ BlDisplayInputDialog(IN PWCHAR Caption, /* Other key pressed, add character to the buffer */ if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) { - if(InputFieldLength < Handle.Width - 8 - 1 && TextPosition < Handle.Width - 8 - 1) - { - RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR)); - InputFieldBuffer[TextPosition] = Key.UnicodeChar; - TextPosition++; - InputFieldLength++; - InputFieldBuffer[InputFieldLength] = 0; - } + RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR)); + InputFieldBuffer[TextPosition] = Key.UnicodeChar; + TextPosition++; + InputFieldLength++; + InputFieldBuffer[InputFieldLength] = 0; } } - if(TextPosition > (Handle.Width - 8)) + if(TextPosition > (Handle.Width - 9)) { - TextIndex = TextPosition - (Handle.Width - 8); - TextCursorPosition = Handle.Width - 8; + TextIndex = TextPosition - (Handle.Width - 9); + TextCursorPosition = Handle.Width - 9; } else { -- 2.45.1 From 39208ac1cdcbd32bbb45a52544ce7a22f8ac9ed3 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 10:49:51 +0100 Subject: [PATCH 123/182] Add ability to produce linker map file --- sdk/cmake/functions.cmake | 8 -------- sdk/cmake/xtchain.cmake | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sdk/cmake/functions.cmake b/sdk/cmake/functions.cmake index 2e27199..93a710f 100644 --- a/sdk/cmake/functions.cmake +++ b/sdk/cmake/functions.cmake @@ -88,14 +88,6 @@ function(set_install_target TARGET DESTINATION) install(TARGETS ${TARGET} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION}) endfunction() -# This function enables or disables binary ordinals export for specified module -function(set_ordinals MODULE STATE) - if(NOT ${ARGC} EQUAL 2) - message(FATAL_ERROR "Invalid number of arguments passed to set_ordinals() function") - endif() - set_module_property(${MODULE} ENABLE_EXPORTS ${STATE}) -endfunction() - # This function is responsible for compiling module SPEC file function(set_specfile SPECFILE) if(NOT ${ARGC} EQUAL 1) diff --git a/sdk/cmake/xtchain.cmake b/sdk/cmake/xtchain.cmake index 5a5526a..3925dc5 100644 --- a/sdk/cmake/xtchain.cmake +++ b/sdk/cmake/xtchain.cmake @@ -80,6 +80,24 @@ function(set_imagebase MODULE IMAGEBASE) add_module_linker_flags(${MODULE} "/BASE:${IMAGEBASE}") endfunction() +# This function enables or disables map file generation for specified module +function(set_linker_map MODULE STATE) + if(NOT ${ARGC} EQUAL 2) + message(FATAL_ERROR "Invalid number of arguments passed to set_ordinals() function") + endif() + if(STATE STREQUAL "TRUE") + add_module_linker_flags(${MODULE} "/MAP:${CMAKE_CURRENT_BINARY_DIR}/${MODULE}.map") + endif() +endfunction() + +# This function enables or disables binary ordinals export for specified module +function(set_ordinals MODULE STATE) + if(NOT ${ARGC} EQUAL 2) + message(FATAL_ERROR "Invalid number of arguments passed to set_ordinals() function") + endif() + set_module_property(${MODULE} ENABLE_EXPORTS ${STATE}) +endfunction() + # This functions sets PE/COFF subsystem and XTOS version of the binary function(set_subsystem MODULE SUBSYSTEM) string(TOUPPER ${SUBSYSTEM} SUBSYSTEM) -- 2.45.1 From 5425abb19f74c74aeed51fbe55b73b96c7eb6f0b Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 11:31:45 +0100 Subject: [PATCH 124/182] Let BlDisplayInputDialog() work on a copy of input text and save it only on ENTER key press --- xtldr2/includes/bootman.h | 6 + xtldr2/textui.c | 386 +++++++++++++++++++++----------------- 2 files changed, 222 insertions(+), 170 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 3d19134..0002412 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -60,6 +60,12 @@ VOID BlDisplayInfoDialog(IN PWCHAR Caption, IN PWCHAR Message); +XTCDECL +VOID +BlDisplayInputDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN OUT PWCHAR *InputFieldText); + XTCDECL XTBL_DIALOG_HANDLE BlDisplayProgressDialog(IN PWCHAR Caption, diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 5141a33..52b5755 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -369,6 +369,222 @@ BlDisplayInfoDialog(IN PWCHAR Caption, BlClearConsoleScreen(); } +/** + * Displays a blue informational dialog box with the specified caption and message and an input field. + * + * @param Caption + * Specifies a caption string put on the dialog box. + * + * @param Message + * Specifies a message string put on the dialog box. + * + * @param InputFieldText + * Specifies a pointer to the input field text that will be edited. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlDisplayInputDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN PWCHAR *InputFieldText) +{ + SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; + XTBL_DIALOG_HANDLE Handle; + PWCHAR InputFieldBuffer; + SIZE_T BufferLength; + EFI_INPUT_KEY Key; + EFI_STATUS Status; + UINT_PTR Index; + + /* Set dialog window attributes */ + Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON; + + /* Determine dialog window size and position */ + BlpDetermineDialogBoxSize(&Handle, Message); + + /* Disable cursor and draw dialog box */ + BlDisableConsoleCursor(); + BlpDrawDialogBox(&Handle, Caption, Message); + + /* Draw inactive button */ + BlpDrawDialogButton(&Handle); + + /* Draw active input field */ + BlpDrawDialogInputField(&Handle, *InputFieldText); + + /* Initialize key stroke */ + Key.ScanCode = 0; + Key.UnicodeChar = 0; + + /* Get initial input text length and allocate a buffer */ + BufferLength = RtlWideStringLength(*InputFieldText, 0); + Status = BlMemoryAllocatePool(BufferLength * sizeof(WCHAR), (PVOID *)&InputFieldBuffer); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print error message and return */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer."); + return; + } + + /* Copy input text into edit buffer */ + RtlCopyMemory(InputFieldBuffer, *InputFieldText, BufferLength * sizeof(WCHAR)); + InputFieldBuffer[BufferLength] = L'\0'; + + /* Determine input field length */ + InputFieldLength = BufferLength; + if(InputFieldLength > Handle.Width - 8) + { + InputFieldLength = Handle.Width - 8; + } + + /* Start at first character */ + TextPosition = 0; + BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); + + /* Wait until ENTER or ESC key is pressed */ + while(TRUE) + { + /* Wait for key press and read key stroke */ + BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + BlReadKeyStroke(&Key); + BlResetConsoleInputBuffer(); + + /* Check key press scan code */ + if(Key.ScanCode == 0x17) + { + /* ESC key pressed, return */ + break; + } + else if(Key.UnicodeChar == 0x09) + { + /* TAB key pressed, toggle input field and button */ + Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT); + Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON); + } + else if(Key.ScanCode == 0x03) + { + /* RIGHT key pressed, move cursor forward */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength) + { + TextPosition++; + } + } + else if(Key.ScanCode == 0x04) + { + /* LEFT key pressed, move cursor back */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0) + { + TextPosition--; + } + } + else if(Key.ScanCode == 0x05) + { + /* HOME key pressed, move cursor to the beginning */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) + { + TextPosition = 0; + } + } + else if(Key.ScanCode == 0x06) + { + /* END key pressed, move cursor to the end */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) + { + TextPosition = InputFieldLength; + } + } + else if(Key.ScanCode == 0x08) + { + /* DELETE key pressed, delete character */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) + { + if(InputFieldLength > 0 && TextPosition < InputFieldLength) + { + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, + (InputFieldLength - TextPosition) * sizeof(WCHAR)); + InputFieldLength--; + InputFieldBuffer[InputFieldLength] = 0; + } + } + } + else if(Key.UnicodeChar == 0x08) + { + /* BACKSPACE key pressed, delete character */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) + { + if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) + { + TextPosition--; + RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, + (InputFieldLength - TextPosition) * sizeof(WCHAR)); + InputFieldLength--; + InputFieldBuffer[InputFieldLength] = 0; + } + } + } + else if(Key.UnicodeChar == 0x0D) + { + /* ENTER key pressed, allocate memory for updated input text */ + BufferLength = RtlWideStringLength(InputFieldBuffer, 0); + BlMemoryFreePool(*InputFieldText); + Status = BlMemoryAllocatePool(BufferLength * sizeof(WCHAR), (PVOID *)*InputFieldText); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory, print error message and return status code */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to save input data."); + break; + } + + /* Copy edit buffer into original buffer */ + RtlZeroMemory(InputFieldText, BufferLength * sizeof(WCHAR)); + RtlCopyMemory(*InputFieldText, InputFieldBuffer, BufferLength * sizeof(WCHAR)); + break; + } + else + { + /* Other key pressed, add character to the buffer */ + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) + { + RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, + (InputFieldLength - TextPosition) * sizeof(WCHAR)); + InputFieldBuffer[TextPosition] = Key.UnicodeChar; + TextPosition++; + InputFieldLength++; + InputFieldBuffer[InputFieldLength] = 0; + } + } + + if(TextPosition > (Handle.Width - 9)) + { + TextIndex = TextPosition - (Handle.Width - 9); + TextCursorPosition = Handle.Width - 9; + } + else + { + TextIndex = 0; + TextCursorPosition = TextPosition; + } + + /* Redraw input field and button */ + BlpDrawDialogButton(&Handle); + BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); + + if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) + { + BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); + } + } + + /* Clear screen to remove dialog box */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); +} + /** * Displays a blue informational dialog box with the specified caption and message and a progress bar. * @@ -1060,173 +1276,3 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, BlDisableConsoleCursor(); BlConsoleWrite(ProgressBar); } - - - - - - -// TODO: FIX, this is completely broken -XTCDECL -VOID -BlDisplayInputDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN PWCHAR InputFieldBuffer) -{ - XTBL_DIALOG_HANDLE Handle; - SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; - EFI_INPUT_KEY Key; - UINT_PTR Index; - - /* Set dialog window attributes */ - Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON; - - /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); - - /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); - - /* Draw inactive button */ - BlpDrawDialogButton(&Handle); - - /* Draw active input field */ - BlpDrawDialogInputField(&Handle, InputFieldBuffer); - - /* Initialize key stroke */ - Key.ScanCode = 0; - Key.UnicodeChar = 0; - - /* Determine input field length */ - InputFieldLength = RtlWideStringLength(InputFieldBuffer, 0); - if(InputFieldLength > Handle.Width - 8) - { - InputFieldLength = Handle.Width - 8; - } - - /* Start at first character */ - TextPosition = 0; - BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); - - /* Wait until ENTER or ESC key is pressed */ - while(TRUE) - { - /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); - - /* Check key press scan code */ - if(Key.ScanCode == 0x17) - { - /* ESC key pressed, return */ - break; - } - else if(Key.UnicodeChar == 0x09) - { - /* TAB key pressed, toggle input field and button */ - Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT); - Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON); - } - else if(Key.ScanCode == 0x03) - { - /* RIGHT key pressed, move cursor forward */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength) - { - TextPosition++; - } - } - else if(Key.ScanCode == 0x04) - { - /* LEFT key pressed, move cursor back */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0) - { - TextPosition--; - } - } - else if(Key.ScanCode == 0x05) - { - /* HOME key pressed, move cursor to the beginning */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) - { - TextPosition = 0; - } - } - else if(Key.ScanCode == 0x06) - { - /* END key pressed, move cursor to the end */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) - { - TextPosition = InputFieldLength; - } - } - else if(Key.ScanCode == 0x08) - { - /* DELETE key pressed, delete character */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) - { - if(InputFieldLength > 0 && TextPosition < InputFieldLength) - { - RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR)); - InputFieldLength--; - InputFieldBuffer[InputFieldLength] = 0; - } - } - } - else if(Key.UnicodeChar == 0x08) - { - /* BACKSPACE key pressed, delete character */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) - { - if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) - { - TextPosition--; - RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR)); - InputFieldLength--; - InputFieldBuffer[InputFieldLength] = 0; - } - } - } - else if(Key.UnicodeChar == 0x0D) - { - /* ENTER key pressed */ - } - else - { - /* Other key pressed, add character to the buffer */ - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) - { - RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR)); - InputFieldBuffer[TextPosition] = Key.UnicodeChar; - TextPosition++; - InputFieldLength++; - InputFieldBuffer[InputFieldLength] = 0; - } - } - - if(TextPosition > (Handle.Width - 9)) - { - TextIndex = TextPosition - (Handle.Width - 9); - TextCursorPosition = Handle.Width - 9; - } - else - { - TextIndex = 0; - TextCursorPosition = TextPosition; - } - - /* Redraw input field and button */ - BlpDrawDialogButton(&Handle); - BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); - - if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) - { - BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); - } - } - - /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); -} -- 2.45.1 From 3a0fd18211be27ea512ce892df705cbd4b86350d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 12:12:59 +0100 Subject: [PATCH 125/182] Simplify BlDisplayInputDialog() saving input buffer --- xtldr2/textui.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 52b5755..8f3620e 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -528,21 +528,8 @@ BlDisplayInputDialog(IN PWCHAR Caption, } else if(Key.UnicodeChar == 0x0D) { - /* ENTER key pressed, allocate memory for updated input text */ - BufferLength = RtlWideStringLength(InputFieldBuffer, 0); - BlMemoryFreePool(*InputFieldText); - Status = BlMemoryAllocatePool(BufferLength * sizeof(WCHAR), (PVOID *)*InputFieldText); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to save input data."); - break; - } - - /* Copy edit buffer into original buffer */ - RtlZeroMemory(InputFieldText, BufferLength * sizeof(WCHAR)); - RtlCopyMemory(*InputFieldText, InputFieldBuffer, BufferLength * sizeof(WCHAR)); + /* ENTER key pressed, update input buffer */ + *InputFieldText = InputFieldBuffer; break; } else -- 2.45.1 From 0055d3eaa5a39629b974da59718faac4ede9d505 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 12:37:20 +0100 Subject: [PATCH 126/182] Add missing comment --- xtldr2/includes/globals.h | 1 + 1 file changed, 1 insertion(+) diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index 0e6402a..172ec21 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -24,6 +24,7 @@ EXTERN LIST_ENTRY BlpConfigSections; /* XT Boot Loader hex table */ EXTERN PUINT16 BlpHexTable; +/* XT Boot Loader protocol */ EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol; /* XT Boot Loader loaded modules list */ -- 2.45.1 From d4252ebc05ffc798b196ea56208fef73d0aebc82 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 13:10:11 +0100 Subject: [PATCH 127/182] Remove dummy2 module --- xtldr2/modules/CMakeLists.txt | 1 - xtldr2/modules/dummy2/CMakeLists.txt | 26 ----------------------- xtldr2/modules/dummy2/dummy2.c | 31 ---------------------------- 3 files changed, 58 deletions(-) delete mode 100644 xtldr2/modules/dummy2/CMakeLists.txt delete mode 100644 xtldr2/modules/dummy2/dummy2.c diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt index 5a3e917..c65186e 100644 --- a/xtldr2/modules/CMakeLists.txt +++ b/xtldr2/modules/CMakeLists.txt @@ -1,2 +1 @@ add_subdirectory(dummy) -add_subdirectory(dummy2) diff --git a/xtldr2/modules/dummy2/CMakeLists.txt b/xtldr2/modules/dummy2/CMakeLists.txt deleted file mode 100644 index b4e0328..0000000 --- a/xtldr2/modules/dummy2/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# XT Boot Loader -PROJECT(XTLDR_DUMMY2) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes - ${XTLDR_DUMMY2_SOURCE_DIR}/includes) - -# Specify list of source code files -list(APPEND XTLDR_DUMMY2_SOURCE - ${XTLDR_DUMMY2_SOURCE_DIR}/dummy2.c) - -# Link bootloader executable -add_executable(dummy2 ${XTLDR_DUMMY2_SOURCE}) - -# Add linker libraries -target_link_libraries(dummy2 libxtldr libxtos) - -# Set proper binary name and install target -set_target_properties(dummy2 PROPERTIES SUFFIX .efi) -set_install_target(dummy2 efi/boot/xtldr/modules) - -# Set module entrypoint and subsystem -set_entrypoint(dummy2 "XtLdrModuleMain") -set_subsystem(dummy2 efi_boot_service_driver) diff --git a/xtldr2/modules/dummy2/dummy2.c b/xtldr2/modules/dummy2/dummy2.c deleted file mode 100644 index 4681052..0000000 --- a/xtldr2/modules/dummy2/dummy2.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/dummy/dummy.c - * DESCRIPTION: Dummy XTLDR module - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * This routine is the entry point of the XT EFI boot loader module. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param SystemTable - * Provides the EFI system table. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable) -{ - return STATUS_EFI_SUCCESS; -} -- 2.45.1 From 46ebe5c2500076b107c228594ea17c787f9940a9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 13:26:59 +0100 Subject: [PATCH 128/182] Cleanup dummy module a bit --- xtldr2/modules/dummy/CMakeLists.txt | 4 ++-- xtldr2/modules/dummy/globals.c | 16 ++++++++++++++++ xtldr2/modules/dummy/includes/globals.h | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 xtldr2/modules/dummy/globals.c create mode 100644 xtldr2/modules/dummy/includes/globals.h diff --git a/xtldr2/modules/dummy/CMakeLists.txt b/xtldr2/modules/dummy/CMakeLists.txt index 2108502..86b2145 100644 --- a/xtldr2/modules/dummy/CMakeLists.txt +++ b/xtldr2/modules/dummy/CMakeLists.txt @@ -4,12 +4,12 @@ PROJECT(XTLDR_DUMMY) # Specify include directories include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes ${XTLDR_DUMMY_SOURCE_DIR}/includes) # Specify list of source code files list(APPEND XTLDR_DUMMY_SOURCE - ${XTLDR_DUMMY_SOURCE_DIR}/dummy.c) + ${XTLDR_DUMMY_SOURCE_DIR}/dummy.c + ${XTLDR_DUMMY_SOURCE_DIR}/globals.c) # Link bootloader executable add_executable(dummy ${XTLDR_DUMMY_SOURCE}) diff --git a/xtldr2/modules/dummy/globals.c b/xtldr2/modules/dummy/globals.c new file mode 100644 index 0000000..d693509 --- /dev/null +++ b/xtldr2/modules/dummy/globals.c @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/dummy/globals.c + * DESCRIPTION: Dummy XTLDR module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL XtLdrProto; + +/* Dummy Boot Protocol handler */ +XTBL_BOOT_PROTOCOL BlpDummyProtocol; diff --git a/xtldr2/modules/dummy/includes/globals.h b/xtldr2/modules/dummy/includes/globals.h new file mode 100644 index 0000000..fcb72c1 --- /dev/null +++ b/xtldr2/modules/dummy/includes/globals.h @@ -0,0 +1,21 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/dummy/includes/globals.h + * DESCRIPTION: Dummy XTLDR module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_DUMMY_GLOBALS_H +#define __XTLDR_DUMMY_GLOBALS_H + +#include + + +/* XTLDR protocol handler */ +EXTERN PXTBL_LOADER_PROTOCOL XtLdrProto; + +/* Dummy Boot Protocol handler */ +EXTERN XTBL_BOOT_PROTOCOL BlpDummyProtocol; + +#endif/* __XTLDR_DUMMY_GLOBALS_H */ -- 2.45.1 From 490501763f3ed21e829ff6fd04a812d50e8b6ef9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 13:28:58 +0100 Subject: [PATCH 129/182] Cleanup dummy module a bit #2 --- xtldr2/modules/dummy/dummy.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index 4aa9d65..1dfce92 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -7,21 +7,16 @@ */ #include +#include /* Dummy module information */ XTBL_MODINFO = L"Dummy XTLDR module"; // XTBL_MODDEPS = {L"dummy2"}; -/* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProto; - -/* Dummy Boot Protocol handler */ -XTBL_BOOT_PROTOCOL DummyProtocol; - XTCDECL EFI_STATUS -BootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters) +BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters) { return STATUS_EFI_SUCCESS; } @@ -56,11 +51,11 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, } /* Set boot protocol routines */ - DummyProtocol.BootSystem = BootDummyOS; + BlpDummyProtocol.BootSystem = BlBootDummyOS; /* Register XTOS boot protocol */ XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid); /* Register DUMMY protocol as XTOS boot protocol */ - return XtLdrProto->Protocol.Register(&DummyGuid, &DummyProtocol); + return XtLdrProto->Protocol.Register(&DummyGuid, &BlpDummyProtocol); } -- 2.45.1 From 64b23a3e7df8099ffd9f6a370fd459aa42646c70 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 14:34:34 +0100 Subject: [PATCH 130/182] Cleanup code --- xtldr2/includes/bootman.h | 402 -------------------------------------- xtldr2/includes/xtldr.h | 389 +++++++++++++++++++++++++++++++++++- xtldr2/string.c | 12 +- 3 files changed, 394 insertions(+), 409 deletions(-) delete mode 100644 xtldr2/includes/bootman.h diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h deleted file mode 100644 index 0002412..0000000 --- a/xtldr2/includes/bootman.h +++ /dev/null @@ -1,402 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/bootman.h - * DESCRIPTION: XTLDR Boot Loader related structures and routines forward references - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BOOTMAN_H -#define __XTLDR_BOOTMAN_H - -#include - - -/* XTLDR routine callbacks */ -typedef VOID (BMPRINTCHAR)(IN USHORT Character); - -/* XTLDR routines forward references */ -XTCDECL -VOID -BlClearConsoleLine(IN ULONGLONG LineNo); - -XTCDECL -VOID -BlClearConsoleScreen(); - -XTCDECL -EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle); - -XTCDECL -VOID -BlConsolePrint(IN PUINT16 Format, - IN ...); - -XTCDECL -VOID -BlConsoleWrite(IN PUSHORT String); - -XTCDECL -VOID -BlDebugPrint(IN PUINT16 Format, - IN ...); - -XTCDECL -VOID -BlDisableConsoleCursor(); - -XTCDECL -VOID -BlDisplayBootMenu(); - -XTCDECL -VOID -BlDisplayErrorDialog(IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlDisplayInfoDialog(IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlDisplayInputDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN OUT PWCHAR *InputFieldText); - -XTCDECL -XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN UCHAR Percentage); - -XTCDECL -VOID -BlEnableConsoleCursor(); - -XTCDECL -EFI_STATUS -BlEnumerateBlockDevices(); - -XTCDECL -EFI_STATUS -BlExitBootServices(IN UINT_PTR MapKey); - -XTCDECL -EFI_STATUS -BlFindBootProtocol(IN PWCHAR SystemType, - OUT PEFI_GUID BootProtocolGuid); - -XTCDECL -EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, - IN CONST PWCHAR FileSystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); - -XTCDECL -PWCHAR -BlGetConfigValue(IN CONST PWCHAR ConfigName); - -XTCDECL -INT_PTR -BlGetSecureBootStatus(); - -XTCDECL -EFI_STATUS -BlGetVolumeDevicePath(IN PWCHAR SystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path); - -XTCDECL -VOID -BlInitializeBootLoader(); - -XTCDECL -VOID -BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, - OUT PULONG EntriesCount, - OUT PULONG DefaultId); - -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); - -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName); - -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList); - -XTCDECL -EFI_STATUS -BlMemoryAllocatePages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory); - -XTCDECL -EFI_STATUS -BlMemoryFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlMemoryFreePool(IN PVOID Memory); - -XTCDECL -EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle); - -XTCDECL -EFI_STATUS -BlOpenProtocol(OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); - -XTCDECL -VOID -BlQueryConsoleMode(OUT PUINT_PTR ResX, - OUT PUINT_PTR ResY); - -XTCDECL -EFI_STATUS -BlReadFile(IN PEFI_FILE_HANDLE DirHandle, - IN CONST PWCHAR FileName, - OUT PVOID *FileData, - OUT PSIZE_T FileSize); - -XTCDECL -VOID -BlReadKeyStroke(OUT PEFI_INPUT_KEY Key); - -XTCDECL -VOID -BlRegisterBootMenu(PVOID BootMenuRoutine); - -XTCDECL -EFI_STATUS -BlRegisterBootProtocol(IN PWCHAR SystemType, - IN PEFI_GUID BootProtocolGuid); - -XTCDECL -EFI_STATUS -BlRegisterProtocol(IN PEFI_GUID Guid, - IN PVOID Interface); - -XTCDECL -VOID -BlResetConsoleInputBuffer(); - -XTCDECL -EFI_STATUS -BlSetConfigValue(IN CONST PWCHAR ConfigName, - IN CONST PWCHAR ConfigValue); - -XTCDECL -VOID -BlSetConsoleAttributes(IN ULONGLONG Attributes); - -XTCDECL -EFI_STATUS -BlSetConsoleMode(IN ULONGLONG Mode); - -XTCDECL -VOID -BlSetCursorPosition(IN ULONGLONG PosX, - IN ULONGLONG PosY); - -XTCDECL -VOID -BlSleepExecution(IN ULONG_PTR Milliseconds); - -XTCDECL -EFI_STATUS -BlStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message, - IN UCHAR Percentage); - -XTCDECL -EFI_STATUS -BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, - IN PEFI_EVENT Event, - OUT PUINT_PTR Index); - -XTCDECL -EFI_STATUS -BlpActivateSerialIOController(); - -XTCDECL -VOID -BlpInitializeConsole(); - -XTCDECL -VOID -BlpConsolePrintChar(IN USHORT Character); - -XTCDECL -VOID -BlpDebugPutChar(IN USHORT Character); - -XTCDECL -VOID -BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message); - -XTCDECL -EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); - -XTCDECL -EFI_STATUS -BlpDissectVolumeArcPath(IN PWCHAR SystemPath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber); - -XTCDECL -VOID -BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle); - -XTCDECL -VOID -BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR MenuEntry, - IN UINT Position, - IN BOOLEAN Highlighted); - -XTCDECL -VOID -BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle); - -XTCDECL -VOID -BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR InputFieldText); - -XTCDECL -VOID -BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message); - -XTCDECL -VOID -BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN UCHAR Percentage); - -XTCDECL -PEFI_DEVICE_PATH_PROTOCOL -BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); - -XTCDECL -EFI_STATUS -BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); - -XTCDECL -BOOLEAN -BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA ParentNode); - -XTCDECL -EFI_STATUS -BlpInitializeDebugConsole(); - -XTCDECL -EFI_STATUS -BlpInitializeSerialPort(IN ULONG PortNumber, - IN ULONG PortAddress, - IN ULONG BaudRate); - -XTCDECL -EFI_STATUS -BlpLoadConfiguration(); - -XTCDECL -EFI_STATUS -BlpParseCommandLine(VOID); - -XTCDECL -EFI_STATUS -BlpParseConfigFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration); - -XTCDECL -EFI_STATUS -BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); - -XTCDECL -EFI_STATUS -BlpRegisterXtLoaderProtocol(); - -XTCDECL -VOID -BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN ...); - -XTCDECL -VOID -BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN VA_LIST Arguments); - -XTCDECL -VOID -BlpStringPrintSigned32(IN BMPRINTCHAR PrintCharRoutine, - IN INT Number, - IN UINT Base); - -XTCDECL -VOID -BlpStringPrintSigned64(IN BMPRINTCHAR PrintCharRoutine, - IN INT_PTR Number, - IN UINT_PTR Base); - -XTCDECL -VOID -BlpStringPrintUnsigned32(IN BMPRINTCHAR PrintCharRoutine, - IN UINT Number, - IN UINT Base, - IN UINT Padding); - -XTCDECL -VOID -BlpStringPrintUnsigned64(IN BMPRINTCHAR PrintCharRoutine, - IN UINT_PTR Number, - IN UINT_PTR Base, - IN UINT_PTR Padding); - -XTCDECL -UINT64 -BlpStringReadPadding(IN PUINT16 *Format); - -XTCDECL -VOID -BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig); - -#endif /* __XTLDR_BOOTMAN_H */ diff --git a/xtldr2/includes/xtldr.h b/xtldr2/includes/xtldr.h index 497b0b1..d385deb 100644 --- a/xtldr2/includes/xtldr.h +++ b/xtldr2/includes/xtldr.h @@ -13,6 +13,393 @@ #include #include -#include + + +/* XTLDR routine callbacks */ +typedef VOID (BLPRINTCHAR)(IN USHORT Character); + +/* XTLDR routines forward references */ +XTCDECL +VOID +BlClearConsoleLine(IN ULONGLONG LineNo); + +XTCDECL +VOID +BlClearConsoleScreen(); + +XTCDECL +EFI_STATUS +BlCloseVolume(IN PEFI_HANDLE VolumeHandle); + +XTCDECL +VOID +BlConsolePrint(IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BlConsoleWrite(IN PUSHORT String); + +XTCDECL +VOID +BlDebugPrint(IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BlDisableConsoleCursor(); + +XTCDECL +VOID +BlDisplayBootMenu(); + +XTCDECL +VOID +BlDisplayErrorDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlDisplayInfoDialog(IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlDisplayInputDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN OUT PWCHAR *InputFieldText); + +XTCDECL +XTBL_DIALOG_HANDLE +BlDisplayProgressDialog(IN PWCHAR Caption, + IN PWCHAR Message, + IN UCHAR Percentage); + +XTCDECL +VOID +BlEnableConsoleCursor(); + +XTCDECL +EFI_STATUS +BlEnumerateBlockDevices(); + +XTCDECL +EFI_STATUS +BlExitBootServices(IN UINT_PTR MapKey); + +XTCDECL +EFI_STATUS +BlFindBootProtocol(IN PWCHAR SystemType, + OUT PEFI_GUID BootProtocolGuid); + +XTCDECL +EFI_STATUS +BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); + +XTCDECL +PWCHAR +BlGetConfigValue(IN CONST PWCHAR ConfigName); + +XTCDECL +INT_PTR +BlGetSecureBootStatus(); + +XTCDECL +EFI_STATUS +BlGetVolumeDevicePath(IN PWCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path); + +XTCDECL +VOID +BlInitializeBootLoader(); + +XTCDECL +VOID +BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId); + +XTCDECL +EFI_STATUS +BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); + +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName); + +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList); + +XTCDECL +EFI_STATUS +BlMemoryAllocatePages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory); + +XTCDECL +EFI_STATUS +BlMemoryAllocatePool(IN UINT_PTR Size, + OUT PVOID *Memory); + +XTCDECL +EFI_STATUS +BlMemoryFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory); + +XTCDECL +EFI_STATUS +BlMemoryFreePool(IN PVOID Memory); + +XTCDECL +EFI_STATUS +BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle); + +XTCDECL +EFI_STATUS +BlOpenProtocol(OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); + +XTCDECL +VOID +BlQueryConsoleMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY); + +XTCDECL +EFI_STATUS +BlReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN CONST PWCHAR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize); + +XTCDECL +VOID +BlReadKeyStroke(OUT PEFI_INPUT_KEY Key); + +XTCDECL +VOID +BlRegisterBootMenu(PVOID BootMenuRoutine); + +XTCDECL +EFI_STATUS +BlRegisterBootProtocol(IN PWCHAR SystemType, + IN PEFI_GUID BootProtocolGuid); + +XTCDECL +EFI_STATUS +BlRegisterProtocol(IN PEFI_GUID Guid, + IN PVOID Interface); + +XTCDECL +VOID +BlResetConsoleInputBuffer(); + +XTCDECL +EFI_STATUS +BlSetConfigValue(IN CONST PWCHAR ConfigName, + IN CONST PWCHAR ConfigValue); + +XTCDECL +VOID +BlSetConsoleAttributes(IN ULONGLONG Attributes); + +XTCDECL +EFI_STATUS +BlSetConsoleMode(IN ULONGLONG Mode); + +XTCDECL +VOID +BlSetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY); + +XTCDECL +VOID +BlSleepExecution(IN ULONG_PTR Milliseconds); + +XTCDECL +EFI_STATUS +BlStartXtLoader(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +XTCDECL +VOID +BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message, + IN UCHAR Percentage); + +XTCDECL +EFI_STATUS +BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index); + +XTCDECL +EFI_STATUS +BlpActivateSerialIOController(); + +XTCDECL +VOID +BlpInitializeConsole(); + +XTCDECL +VOID +BlpConsolePrintChar(IN USHORT Character); + +XTCDECL +VOID +BlpDebugPutChar(IN USHORT Character); + +XTCDECL +VOID +BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + +XTCDECL +EFI_STATUS +BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); + +XTCDECL +EFI_STATUS +BlpDissectVolumeArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber); + +XTCDECL +VOID +BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle); + +XTCDECL +VOID +BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted); + +XTCDECL +VOID +BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Caption, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle); + +XTCDECL +VOID +BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText); + +XTCDECL +VOID +BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR Message); + +XTCDECL +VOID +BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage); + +XTCDECL +PEFI_DEVICE_PATH_PROTOCOL +BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); + +XTCDECL +EFI_STATUS +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); + +XTCDECL +BOOLEAN +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode); + +XTCDECL +EFI_STATUS +BlpInitializeDebugConsole(); + +XTCDECL +EFI_STATUS +BlpInitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate); + +XTCDECL +EFI_STATUS +BlpLoadConfiguration(); + +XTCDECL +EFI_STATUS +BlpParseCommandLine(VOID); + +XTCDECL +EFI_STATUS +BlpParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration); + +XTCDECL +EFI_STATUS +BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, + IN CONST PWCHAR ConfigFile, + OUT PCHAR *ConfigData); + +XTCDECL +EFI_STATUS +BlpRegisterXtLoaderProtocol(); + +XTCDECL +VOID +BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN ...); + +XTCDECL +VOID +BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments); + +XTCDECL +VOID +BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, + IN INT Number, + IN UINT Base); + +XTCDECL +VOID +BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, + IN INT_PTR Number, + IN UINT_PTR Base); + +XTCDECL +VOID +BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, + IN UINT Number, + IN UINT Base, + IN UINT Padding); + +XTCDECL +VOID +BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, + IN UINT_PTR Number, + IN UINT_PTR Base, + IN UINT_PTR Padding); + +XTCDECL +UINT64 +BlpStringReadPadding(IN PUINT16 *Format); + +XTCDECL +VOID +BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig); #endif /* __XTLDR_XTLDR_H */ diff --git a/xtldr2/string.c b/xtldr2/string.c index 991fbce..f082232 100644 --- a/xtldr2/string.c +++ b/xtldr2/string.c @@ -27,7 +27,7 @@ */ XTCDECL VOID -BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN VA_LIST Arguments) { @@ -202,7 +202,7 @@ BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, +BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...) { @@ -236,7 +236,7 @@ BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BlpStringPrintSigned32(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, IN INT Number, IN UINT Base) { @@ -269,7 +269,7 @@ BlpStringPrintSigned32(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BlpStringPrintSigned64(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, IN INT_PTR Number, IN UINT_PTR Base) { @@ -305,7 +305,7 @@ BlpStringPrintSigned64(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BlpStringPrintUnsigned32(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, IN UINT Number, IN UINT Base, IN UINT Padding) @@ -366,7 +366,7 @@ BlpStringPrintUnsigned32(IN BMPRINTCHAR PrintCharRoutine, */ XTCDECL VOID -BlpStringPrintUnsigned64(IN BMPRINTCHAR PrintCharRoutine, +BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, IN UINT_PTR Number, IN UINT_PTR Base, IN UINT_PTR Padding) -- 2.45.1 From c0f99cc79802c84940b0d792f898bd423bb7fa92 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 14:41:38 +0100 Subject: [PATCH 131/182] Enable linker map for XTLDR and its modules --- xtldr2/CMakeLists.txt | 3 ++- xtldr2/modules/dummy/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 2527989..08e0901 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -43,6 +43,7 @@ set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi) set_install_target(xtldr efi/boot) # Set loader entrypoint and subsystem -set_imagebase(xtldr ${BASEADDRESS_XTLDR}) set_entrypoint(xtldr "BlStartXtLoader") +set_imagebase(xtldr ${BASEADDRESS_XTLDR}) +set_linker_map(xtldr TRUE) set_subsystem(xtldr efi_application) diff --git a/xtldr2/modules/dummy/CMakeLists.txt b/xtldr2/modules/dummy/CMakeLists.txt index 86b2145..46bd990 100644 --- a/xtldr2/modules/dummy/CMakeLists.txt +++ b/xtldr2/modules/dummy/CMakeLists.txt @@ -23,4 +23,5 @@ set_install_target(dummy efi/boot/xtldr/modules) # Set module entrypoint and subsystem set_entrypoint(dummy "XtLdrModuleMain") +set_linker_map(dummy TRUE) set_subsystem(dummy efi_boot_service_driver) -- 2.45.1 From ee0603c31846d817f8309ddc598da054c7c9df26 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 14:45:40 +0100 Subject: [PATCH 132/182] Loader shell stub --- xtldr2/CMakeLists.txt | 1 + xtldr2/includes/xtldr.h | 4 ++++ xtldr2/shell.c | 16 ++++++++++++++++ xtldr2/xtldr.c | 2 ++ 4 files changed, 23 insertions(+) create mode 100644 xtldr2/shell.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 08e0901..d9f2946 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -19,6 +19,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c + ${XTLDR_SOURCE_DIR}/shell.c ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/textui.c ${XTLDR_SOURCE_DIR}/volume.c diff --git a/xtldr2/includes/xtldr.h b/xtldr2/includes/xtldr.h index d385deb..3480f68 100644 --- a/xtldr2/includes/xtldr.h +++ b/xtldr2/includes/xtldr.h @@ -221,6 +221,10 @@ XTCDECL VOID BlSleepExecution(IN ULONG_PTR Milliseconds); +XTCDECL +VOID +BlStartLoaderShell(); + XTCDECL EFI_STATUS BlStartXtLoader(IN EFI_HANDLE ImageHandle, diff --git a/xtldr2/shell.c b/xtldr2/shell.c new file mode 100644 index 0000000..167165a --- /dev/null +++ b/xtldr2/shell.c @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/shell.c + * DESCRIPTION: XT Boot Loader shell + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +XTCDECL +VOID +BlStartLoaderShell() +{ +} diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index c16021f..d03eb5f 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,6 +9,7 @@ #include + /** * Initializes EFI Boot Loader (XTLDR). * @@ -425,6 +426,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, } /* Fallback to shell, if boot menu returned */ + BlStartLoaderShell(); } /* This point should be never reached, if this happen return error code */ -- 2.45.1 From 45e2a7ec66b5ced33a4d4bb16324f3876cbda9a0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 18:31:58 +0100 Subject: [PATCH 133/182] Import old and deprecated 'pecoff_o' module from old XTLDR --- sdk/xtdk/bltypes.h | 97 ++-- xtldr2/modules/CMakeLists.txt | 1 + xtldr2/modules/pecoff_o/CMakeLists.txt | 27 + xtldr2/modules/pecoff_o/includes/pecoff.h | 58 +++ xtldr2/modules/pecoff_o/pecoff.c | 607 ++++++++++++++++++++++ 5 files changed, 744 insertions(+), 46 deletions(-) create mode 100644 xtldr2/modules/pecoff_o/CMakeLists.txt create mode 100644 xtldr2/modules/pecoff_o/includes/pecoff.h create mode 100644 xtldr2/modules/pecoff_o/pecoff.c diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index e910672..199520b 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -64,6 +64,11 @@ typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...); +typedef EFI_STATUS (*PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint); +typedef EFI_STATUS (*PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType); +typedef EFI_STATUS (*PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem); +typedef EFI_STATUS (*PBL_EXECIMAGE_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, IN PVOID VirtualAddress, OUT PVOID *ImagePointer); +typedef EFI_STATUS (*PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); @@ -84,26 +89,6 @@ typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PW typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); typedef VOID (*PBL_XT_BOOT_MENU)(); -/* XTLDR Boot protocol structure */ -typedef struct _XTBL_BOOT_PROTOCOL -{ - PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; -} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; - -/* XTLDR Executable image protocol structure */ -typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL -{ - // PBL_EXECIMAGE_GET_ENTRY_POINT GetEntryPoint; - // PBL_EXECIMAGE_GET_MACHINE_TYPE GetMachineType; - // PBL_EXECIMAGE_GET_SECTION GetSection; - // PBL_EXECIMAGE_GET_SUBSYSTEM GetSubSystem; - // PBL_EXECIMAGE_GET_VERSION GetVersion; - // PBL_EXECIMAGE_LOAD_IMAGE LoadImage; - // PBL_EXECIMAGE_PRINT_INFO PrintDebugInfo; - // PBL_EXECIMAGE_RELOCATE_IMAGE RelocateImage; - // PBL_EXECUTABLE_VERIFY_IMAGE VerifyImage; -} XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL; - /* Boot parameters structure */ typedef struct _XTBL_BOOT_PARAMETERS { @@ -162,6 +147,52 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL EFI_GUID Guid; } XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; +/* XTLDR Module dependencies data */ +typedef struct _XTBL_MODULE_DEPS +{ + LIST_ENTRY Flink; + PWCHAR ModuleName; +} XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; + +/* XTLDR Module information data */ +typedef struct _XTBL_MODULE_INFO +{ + LIST_ENTRY Flink; + PWCHAR ModuleName; + PWCHAR ModuleDescription; + LIST_ENTRY Dependencies; +} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; + +/* XTLDR Status data */ +typedef struct _XTBL_STATUS +{ + PBL_XT_BOOT_MENU BootMenu; + BOOLEAN BootServices; + ULONG DebugPort; + INT_PTR SecureBoot; + CPPORT SerialPort; +} XTBL_STATUS, *PXTBL_STATUS; + +/* XTLDR Boot protocol structure */ +typedef struct _XTBL_BOOT_PROTOCOL +{ + PBL_BOOTPROTO_BOOT_SYSTEM BootSystem; +} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL; + +/* XTLDR Executable image protocol structure */ +typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL +{ + PBL_EXECIMAGE_GET_ENTRY_POINT GetEntryPoint; + PBL_EXECIMAGE_GET_MACHINE_TYPE GetMachineType; + // PBL_EXECIMAGE_GET_SECTION GetSection; + PBL_EXECIMAGE_GET_SUBSYSTEM GetSubSystem; + // PBL_EXECIMAGE_GET_VERSION GetVersion; + PBL_EXECIMAGE_LOAD_IMAGE LoadImage; + // PBL_EXECIMAGE_PRINT_INFO PrintDebugInfo; + PBL_EXECIMAGE_RELOCATE_IMAGE RelocateImage; + // PBL_EXECUTABLE_VERIFY_IMAGE VerifyImage; +} XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL; + /* XTLDR Loader protocol */ typedef struct _XTBL_LOADER_PROTOCOL { @@ -225,30 +256,4 @@ typedef struct _XTBL_LOADER_PROTOCOL } Util; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; -/* XTLDR Module dependencies data */ -typedef struct _XTBL_MODULE_DEPS -{ - LIST_ENTRY Flink; - PWCHAR ModuleName; -} XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; - -/* XTLDR Module information data */ -typedef struct _XTBL_MODULE_INFO -{ - LIST_ENTRY Flink; - PWCHAR ModuleName; - PWCHAR ModuleDescription; - LIST_ENTRY Dependencies; -} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; - -/* XTLDR Status data */ -typedef struct _XTBL_STATUS -{ - PBL_XT_BOOT_MENU BootMenu; - BOOLEAN BootServices; - ULONG DebugPort; - INT_PTR SecureBoot; - CPPORT SerialPort; -} XTBL_STATUS, *PXTBL_STATUS; - #endif /* __XTDK_BLTYPES_H */ diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt index c65186e..cde0c5e 100644 --- a/xtldr2/modules/CMakeLists.txt +++ b/xtldr2/modules/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(dummy) +add_subdirectory(pecoff_o) diff --git a/xtldr2/modules/pecoff_o/CMakeLists.txt b/xtldr2/modules/pecoff_o/CMakeLists.txt new file mode 100644 index 0000000..427597e --- /dev/null +++ b/xtldr2/modules/pecoff_o/CMakeLists.txt @@ -0,0 +1,27 @@ +# XT Boot Loader +PROJECT(XTLDR_PECOFF_O) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_SOURCE_DIR}/includes + ${XTLDR_PECOFF_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_PECOFF_O_SOURCE + ${XTLDR_PECOFF_O_SOURCE_DIR}/pecoff.c) + +# Link bootloader executable +add_executable(pecoff_o ${XTLDR_PECOFF_O_SOURCE}) + +# Add linker libraries +target_link_libraries(pecoff_o libxtos libxtldr) + +# Set proper binary name and install target +set_target_properties(pecoff_o PROPERTIES SUFFIX .efi) +set_install_target(pecoff_o efi/boot/xtldr) + +# Set module entrypoint and subsystem +set_entrypoint(pecoff_o "XtLdrModuleMain") +set_linker_map(pecoff_o TRUE) +set_subsystem(pecoff_o efi_boot_service_driver) diff --git a/xtldr2/modules/pecoff_o/includes/pecoff.h b/xtldr2/modules/pecoff_o/includes/pecoff.h new file mode 100644 index 0000000..af30bf9 --- /dev/null +++ b/xtldr2/modules/pecoff_o/includes/pecoff.h @@ -0,0 +1,58 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/pecoff_o/includes/pecoff.h + * DESCRIPTION: PE/COFF executable file format support header + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_MODULES_PECOFF_O_H +#define __XTLDR_MODULES_PECOFF_O_H + +#include + + +/* PE/COFF image protocol related routines forward references */ +XTCDECL +EFI_STATUS +PeGetEntryPoint(IN PVOID ImagePointer, + OUT PVOID *EntryPoint); + +XTCDECL +EFI_STATUS +PeGetMachineType(IN PVOID ImagePointer, + OUT PUSHORT MachineType); + +XTCDECL +EFI_STATUS +PeGetSubSystem(IN PVOID ImagePointer, + OUT PUSHORT SubSystem); + +XTCDECL +EFI_STATUS +PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, + IN LOADER_MEMORY_TYPE MemoryType, + IN PVOID VirtualAddress, + OUT PVOID *ImagePointer); + +XTCDECL +EFI_STATUS +PeRelocateImage(IN PVOID ImagePointer, + IN EFI_VIRTUAL_ADDRESS Address); + +XTCDECL +EFI_STATUS +PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image); + +XTCDECL +EFI_STATUS +PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, + IN PPECOFF_IMAGE_PE_HEADER PeHeader, + IN SIZE_T FileSize); + +XTCDECL +EFI_STATUS +BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif /* __XTLDR_MODULES_PECOFF_O_H */ diff --git a/xtldr2/modules/pecoff_o/pecoff.c b/xtldr2/modules/pecoff_o/pecoff.c new file mode 100644 index 0000000..d9c87d2 --- /dev/null +++ b/xtldr2/modules/pecoff_o/pecoff.c @@ -0,0 +1,607 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/pecoff_o/pecoff.c + * DESCRIPTION: OLD and deprecated PE/COFF executable file format support module + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* PE/COFF_O module information */ +XTBL_MODINFO = L"PE/COFF executable file format support"; + +/* EFI XT Loader Protocol */ +PXTBL_LOADER_PROTOCOL XtLdrProtocol; + +/* XTOS PE/COFF Image Protocol */ +XTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol; + +/** + * Returns the address of the entry point. + * + * @param Image + * A pointer to the PE/COFF context structure representing the loaded image. + * + * @param EntryPoint + * A pointer to the memory area where address of the image entry point will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeGetEntryPoint(IN PVOID ImagePointer, + OUT PVOID *EntryPoint) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Get entry point and return success */ + *EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader.AddressOfEntryPoint; + return STATUS_EFI_SUCCESS; +} + +/** + * Returns the machine type of the PE/COFF image. + * + * @param Image + * A pointer to the PE/COFF context structure representing the loaded image. + * + * @param MachineType + * A pointer to the memory area where a value defined for the 'machine' field will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeGetMachineType(IN PVOID ImagePointer, + OUT PUSHORT MachineType) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Get image machine type and return success */ + *MachineType = Image->PeHeader->FileHeader.Machine; + return STATUS_EFI_SUCCESS; +} + +/** + * Returns an information about subsystem that is required to run PE/COFF image. + * + * @param Image + * A pointer to the PE/COFF context structure representing the loaded image. + * + * @param SubSystem + * A pointer to the memory area storing a value defined for the 'subsystem' field of the image. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeGetSubSystem(IN PVOID ImagePointer, + OUT PUSHORT SubSystem) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Get image subsystem and return success */ + *SubSystem = Image->PeHeader->OptionalHeader.Subsystem; + return STATUS_EFI_SUCCESS; +} + +/** + * Loads a PE/COFF image file. + * + * @param FileHandle + * The handle of the opened portable executable (PE) file. + * + * @param MemoryType + * Supplies the type of memory to be assigned to the memory descriptor. + * + * @param VirtualAddress + * Optional virtual address pointing to the memory area where PE/COFF file will be loaded. + * + * @param Image + * Supplies pointer to the memory area where loaded PE/COFF image context will be stored. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, + IN LOADER_MEMORY_TYPE MemoryType, + IN PVOID VirtualAddress, + OUT PVOID *ImagePointer) +{ + EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_CONTEXT ImageData; + EFI_PHYSICAL_ADDRESS Address; + PEFI_FILE_INFO FileInfo; + UINT_PTR ReadSize; + EFI_STATUS Status; + UINT SectionSize; + SIZE_T Pages; + PUCHAR Data; + UINT Index; + + /* Set required size for getting file information */ + ReadSize = sizeof(EFI_FILE_INFO) + 32; + + /* Allocate necessary amount of memory */ + Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + return Status; + } + + /* First attempt to get file information */ + Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + if(Status == STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Buffer it too small, but EFI tells the required size, let's reallocate */ + XtLdrProtocol->Memory.FreePool(&FileInfo); + Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + return Status; + } + + /* Second attempt to get file information */ + Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + } + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get file information */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get file information\n"); + return Status; + } + + /* Allocate memory for storing image data */ + Status = XtLdrProtocol->Memory.AllocatePool(sizeof(PECOFF_IMAGE_CONTEXT), (PVOID *)&ImageData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + return Status; + } + + /* Store file size and memory type, nullify data and free up memory */ + ImageData->Data = NULL; + ImageData->FileSize = FileInfo->FileSize; + ImageData->MemoryType = MemoryType; + XtLdrProtocol->Memory.FreePool(FileInfo); + + /* Calculate number of pages */ + Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize); + + /* Allocate pages */ + Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Pages allocation failure */ + XtLdrProtocol->Debug.Print(L"ERROR: Pages allocation failure\n"); + XtLdrProtocol->Memory.FreePool(ImageData); + return Status; + } + + /* Read PE/COFF image */ + ReadSize = Pages * EFI_PAGE_SIZE; + Data = (PUCHAR)(UINT_PTR)Address; + Status = FileHandle->Read(FileHandle, &ReadSize, Data); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read data */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to read PE/COFF image file\n"); + XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); + XtLdrProtocol->Memory.FreePool(ImageData); + return Status; + } + + /* Extract DOS and PE headers */ + ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data; + ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUINT8)Data + ImageData->DosHeader->e_lfanew); + + /* Validate headers */ + Status = PepValidateImageHeaders(ImageData->DosHeader, ImageData->PeHeader, ImageData->FileSize); + if(Status != STATUS_EFI_SUCCESS) + { + /* Header validation failed, probably broken or invalid PE/COFF image */ + XtLdrProtocol->Debug.Print(L"ERROR: Invalid PE/COFF image headers\n"); + XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); + XtLdrProtocol->Memory.FreePool(ImageData); + return Status; + } + + /* Make sure image is executable */ + if (!(ImageData->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_EXECUTABLE_IMAGE)) + { + /* Loaded image is not executable */ + XtLdrProtocol->Debug.Print(L"ERROR: Non-executable PE/COFF image loaded\n"); + XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); + XtLdrProtocol->Memory.FreePool(ImageData); + return STATUS_EFI_LOAD_ERROR; + } + + /* Store image size and calculate number of image pages */ + ImageData->ImageSize = ImageData->PeHeader->OptionalHeader.SizeOfImage; + ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize); + + /* Allocate image pages */ + Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Pages reallocation failure */ + XtLdrProtocol->Debug.Print(L"ERROR: Pages reallocation failure\n"); + XtLdrProtocol->Memory.FreePool(ImageData); + return Status; + } + + /* Store image data and virtual address */ + ImageData->Data = (PUINT8)(UINT_PTR)Address; + ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address; + if(VirtualAddress) + { + /* Virtual address passed to this routine */ + ImageData->VirtualAddress = VirtualAddress; + } + else + { + /* Virtual address not specified, use physical address */ + ImageData->VirtualAddress = (PVOID)(UINT_PTR)Address; + } + + /* Copy all sections */ + RtlCopyMemory(ImageData->Data, Data, ImageData->PeHeader->OptionalHeader.SizeOfHeaders); + + /* Find section header */ + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&ImageData->PeHeader->OptionalHeader + + ImageData->PeHeader->FileHeader.SizeOfOptionalHeader); + + /* Load each section into memory */ + for(Index = 0; Index < ImageData->PeHeader->FileHeader.NumberOfSections; Index++) + { + /* Check section raw data size and section virtual size */ + if(SectionHeader[Index].SizeOfRawData < SectionHeader[Index].Misc.VirtualSize) + { + /* Use raw data size if it is smaller than virtual size */ + SectionSize = SectionHeader[Index].SizeOfRawData; + } + else + { + /* User virtual size otherwise */ + SectionSize = SectionHeader[Index].Misc.VirtualSize; + } + + /* Make sure section is available */ + if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0) + { + /* Copy section */ + RtlCopyMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress, + Data + SectionHeader[Index].PointerToRawData, SectionSize); + } + + /* Check if raw size is shorter than virtual size */ + if(SectionSize < SectionHeader[Index].Misc.VirtualSize) + { + /* Fill remaining space with zeroes */ + RtlZeroMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize, + SectionHeader[Index].Misc.VirtualSize - SectionSize); + } + } + + /* Free pages */ + XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages); + + /* Perform relocation fixups */ + Status = PepRelocateLoadedImage(ImageData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to relocate image */ + XtLdrProtocol->Debug.Print(L"ERROR: PE/COFF image relocation failed\n"); + return Status; + } + + /* Store image data */ + *ImagePointer = ImageData; + + /* Return SUCCESS */ + return STATUS_EFI_SUCCESS; +} + +/** + * Relocates PE/COFF image to the specified address. + * + * @param Image + * A pointer to the PE/COFF context structure representing the loaded image. + * + * @param Address + * Destination address of memory region, where image should be relocated. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeRelocateImage(IN PVOID ImagePointer, + IN EFI_VIRTUAL_ADDRESS Address) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + UINT64 ImageBase, OldVirtualAddress; + EFI_STATUS Status; + + /* Store original virtual address */ + OldVirtualAddress = (UINT_PTR)Image->VirtualAddress; + + /* Check PE/COFF image type */ + if(Image->PeHeader->OptionalHeader.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) + { + /* This is 64-bit PE32+, store its image base address */ + ImageBase = Image->PeHeader->OptionalHeader.ImageBase64; + } + else + { + /* This is 32-bit PE32, store its image base address */ + ImageBase = Image->PeHeader->OptionalHeader.ImageBase32; + } + + /* Overwrite virtual address and relocate image once again */ + Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase); + Status = PepRelocateLoadedImage(Image); + if(Status != STATUS_EFI_SUCCESS) + { + /* Relocation failed */ + return Status; + } + + /* Store new image virtual address */ + Image->VirtualAddress = (PVOID)Address; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Relocates a loaded PE/COFF image. + * + * @param Image + * A pointer to the PE/COFF context structure representing the loaded image. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) +{ + PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; + PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory; + USHORT Offset, Type, Count; + PUSHORT TypeOffset; + UINT64 ImageBase; + PUINT32 Address; + PUINT64 LongPtr; + PUINT ShortPtr; + + /* Make sure image is not stripped */ + if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED) + { + /* No relocation information found */ + XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n"); + return STATUS_EFI_SUCCESS; + } + + /* Set relocation data directory */ + DataDirectory = &Image->PeHeader->OptionalHeader.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC]; + + /* Check if loaded image should be relocated */ + if(Image->PeHeader->OptionalHeader.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC || + DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION)) + { + /* No need to relocate the image */ + return STATUS_EFI_SUCCESS; + } + + /* Check PE/COFF image type */ + if(Image->PeHeader->OptionalHeader.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) + { + /* This is 64-bit PE32+, store its image base address */ + ImageBase = Image->PeHeader->OptionalHeader.ImageBase64; + } + else + { + /* This is 32-bit PE32, store its image base address */ + ImageBase = Image->PeHeader->OptionalHeader.ImageBase32; + } + + /* Set relocation pointers */ + RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)Image->Data + DataDirectory->VirtualAddress); + RelocationEnd = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + DataDirectory->Size); + + /* Do relocations */ + while(RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) + { + /* Calculate number of relocations needed, address and type offset */ + Count = (RelocationDir->SizeOfBlock - sizeof(PECOFF_IMAGE_BASE_RELOCATION)) / sizeof(USHORT); + Address = (PUINT)((PUCHAR)Image->Data + RelocationDir->VirtualAddress); + TypeOffset = (PUSHORT)((PUCHAR)RelocationDir + sizeof(PECOFF_IMAGE_BASE_RELOCATION)); + + /* Do relocations */ + while(Count--) + { + /* Calculate offset and relocation type */ + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + + /* Check if end of the loaded address reached */ + if((PVOID)(PUSHORT)(Address + Offset) >= Image->Data + Image->ImageSize) + { + /* Do not relocate after the end of loaded image */ + break; + } + + /* Make sure we are not going to relocate into .reloc section */ + if((ULONG_PTR)(Address + Offset) < (ULONG_PTR)RelocationDir || + (ULONG_PTR)(Address + Offset) >= (ULONG_PTR)RelocationEnd) + { + /* Apply relocation fixup */ + switch (Type) + { + case PECOFF_IMAGE_REL_BASED_ABSOLUTE: + /* No relocation required */ + break; + case PECOFF_IMAGE_REL_BASED_DIR64: + /* 64-bit relocation */ + LongPtr = (PULONGLONG)((PUCHAR)Address + Offset); + *LongPtr = *LongPtr - ImageBase + (UINT_PTR)Image->VirtualAddress; + break; + case PECOFF_IMAGE_REL_BASED_HIGHLOW: + /* 32-bit relocation of hight and low half of address */ + ShortPtr = (PUINT32)((PUCHAR)Address + Offset); + *ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress; + break; + default: + /* Unknown or unsupported relocation type */ + return STATUS_EFI_UNSUPPORTED; + } + } + /* Increment the type offset */ + TypeOffset++; + } + + /* Next relocation */ + RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((PUCHAR)RelocationDir + RelocationDir->SizeOfBlock); + } + + /* Return SUCCESS */ + return STATUS_EFI_SUCCESS; +} + +/** + * Validates a PE/COFF image headers. + * + * @param DosHeader + * Pointer to the memory area with DOS header stored. + * + * @param PeHeader + * Pointer to the memory area with PE header stored. + * + * @param FileSize + * A PE/COFF image file size. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, + IN PPECOFF_IMAGE_PE_HEADER PeHeader, + IN SIZE_T FileSize) +{ + /* Validate file size */ + if(FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER)) + { + XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image shorter than DOS header\n"); + return STATUS_EFI_END_OF_FILE; + } + + /* Validate DOS header */ + if(DosHeader->e_magic != PECOFF_IMAGE_DOS_SIGNATURE) + { + XtLdrProtocol->Debug.Print(L"WARNING: Invalid DOS signature found\n"); + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Validate PE header */ + if(PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE && PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE) + { + XtLdrProtocol->Debug.Print(L"WARNING: Invalid NT/XT signature found\n"); + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Validate optional header */ + if(PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC && + PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) + { + XtLdrProtocol->Debug.Print(L"WARNING: Invalid optional header signature found\n"); + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID; + EFI_STATUS Status; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open loader protocol */ + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Set routines available via PE/COFF image protocol */ + XtPeCoffProtocol.GetEntryPoint = PeGetEntryPoint; + XtPeCoffProtocol.GetMachineType = PeGetMachineType; + XtPeCoffProtocol.GetSubSystem = PeGetSubSystem; + XtPeCoffProtocol.LoadImage = PeLoadImage; + XtPeCoffProtocol.RelocateImage = PeRelocateImage; + + /* Register PE/COFF protocol */ + return XtLdrProtocol->Protocol.Register(&Guid, &XtPeCoffProtocol); +} -- 2.45.1 From b5b7c1f86e67f31be432150a9808ff3b55a845b9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 18:34:30 +0100 Subject: [PATCH 134/182] Export BlDisplayInputDialog() in XTLDR protocol --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/protocol.c | 1 + 2 files changed, 3 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 199520b..062fb78 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -84,6 +84,7 @@ typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); +typedef VOID (*PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN PWCHAR *InputFieldText); typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage); typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage); typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); @@ -244,6 +245,7 @@ typedef struct _XTBL_LOADER_PROTOCOL { PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog; PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog; + PBL_TUI_DISPLAY_INPUT_DIALOG DisplayInputDialog; PBL_TUI_DISPLAY_PROGRESS_DIALOG DisplayProgressDialog; PBL_TUI_UPDATE_PROGRESS_BAR UpdateProgressBar; } Tui; diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 5fbf82a..23f131d 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -596,6 +596,7 @@ BlpRegisterXtLoaderProtocol() BlpLdrProtocol.Protocol.Register = BlRegisterProtocol; BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; + BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog; BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices; -- 2.45.1 From a0700280c46107961fa9a54abbd126a2baafaff8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 18:36:06 +0100 Subject: [PATCH 135/182] Return STATUS_EFI_PROTOCOL_ERROR --- xtldr2/modules/dummy/dummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr2/modules/dummy/dummy.c index 1dfce92..d98c845 100644 --- a/xtldr2/modules/dummy/dummy.c +++ b/xtldr2/modules/dummy/dummy.c @@ -47,7 +47,7 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to open the protocol, return error */ - return STATUS_EFI_LOAD_ERROR; + return STATUS_EFI_PROTOCOL_ERROR; } /* Set boot protocol routines */ -- 2.45.1 From 8820440fb770690b49aa8732ecd802384b27a3c6 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 18:37:25 +0100 Subject: [PATCH 136/182] Fix build --- xtldr2/modules/pecoff_o/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xtldr2/modules/pecoff_o/CMakeLists.txt b/xtldr2/modules/pecoff_o/CMakeLists.txt index 427597e..09b0fff 100644 --- a/xtldr2/modules/pecoff_o/CMakeLists.txt +++ b/xtldr2/modules/pecoff_o/CMakeLists.txt @@ -4,8 +4,7 @@ PROJECT(XTLDR_PECOFF_O) # Specify include directories include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes - ${XTLDR_PECOFF_SOURCE_DIR}/includes) + ${XTLDR_PECOFF_O_SOURCE_DIR}/includes) # Specify list of source code files list(APPEND XTLDR_PECOFF_O_SOURCE -- 2.45.1 From 339bbe163dd9141672eed5c8849a8c6ba19ad8ab Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 22:20:55 +0100 Subject: [PATCH 137/182] Install 'pecoff_o' module in correct place --- xtldr2/modules/pecoff_o/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/modules/pecoff_o/CMakeLists.txt b/xtldr2/modules/pecoff_o/CMakeLists.txt index 09b0fff..12e137f 100644 --- a/xtldr2/modules/pecoff_o/CMakeLists.txt +++ b/xtldr2/modules/pecoff_o/CMakeLists.txt @@ -18,7 +18,7 @@ target_link_libraries(pecoff_o libxtos libxtldr) # Set proper binary name and install target set_target_properties(pecoff_o PROPERTIES SUFFIX .efi) -set_install_target(pecoff_o efi/boot/xtldr) +set_install_target(pecoff_o efi/boot/xtldr/modules) # Set module entrypoint and subsystem set_entrypoint(pecoff_o "XtLdrModuleMain") -- 2.45.1 From 4c0f4e74c2298a6e423f356ece5ffdba6c03ff78 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 22:34:02 +0100 Subject: [PATCH 138/182] Import old and deprecated 'fb_o' module from old XTLDR --- xtldr2/modules/CMakeLists.txt | 1 + xtldr2/modules/fb_o/CMakeLists.txt | 27 +++ xtldr2/modules/fb_o/framebuf.c | 256 ++++++++++++++++++++++++ xtldr2/modules/fb_o/gop.c | 51 +++++ xtldr2/modules/fb_o/includes/framebuf.h | 79 ++++++++ 5 files changed, 414 insertions(+) create mode 100644 xtldr2/modules/fb_o/CMakeLists.txt create mode 100644 xtldr2/modules/fb_o/framebuf.c create mode 100644 xtldr2/modules/fb_o/gop.c create mode 100644 xtldr2/modules/fb_o/includes/framebuf.h diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt index cde0c5e..ffdddb3 100644 --- a/xtldr2/modules/CMakeLists.txt +++ b/xtldr2/modules/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(dummy) +add_subdirectory(fb_o) add_subdirectory(pecoff_o) diff --git a/xtldr2/modules/fb_o/CMakeLists.txt b/xtldr2/modules/fb_o/CMakeLists.txt new file mode 100644 index 0000000..f8d811b --- /dev/null +++ b/xtldr2/modules/fb_o/CMakeLists.txt @@ -0,0 +1,27 @@ +# XT Boot Loader +PROJECT(XTLDR_FB_O) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_FB_O_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_FB_O_SOURCE + ${XTLDR_FB_O_SOURCE_DIR}/framebuf.c + ${XTLDR_FB_O_SOURCE_DIR}/gop.c) + +# Link bootloader executable +add_executable(fb_o ${XTLDR_FB_O_SOURCE}) + +# Add linker libraries +target_link_libraries(fb_o libxtos libxtldr) + +# Set proper binary name and install target +set_target_properties(fb_o PROPERTIES SUFFIX .efi) +set_install_target(fb_o efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(fb_o "XtLdrModuleMain") +set_linker_map(fb_o TRUE) +set_subsystem(fb_o efi_boot_service_driver) diff --git a/xtldr2/modules/fb_o/framebuf.c b/xtldr2/modules/fb_o/framebuf.c new file mode 100644 index 0000000..cd8db2e --- /dev/null +++ b/xtldr2/modules/fb_o/framebuf.c @@ -0,0 +1,256 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/framebuf/framebuf.c + * DESCRIPTION: Boot loader framebuffer support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* PE/COFF_O module information */ +XTBL_MODINFO = L"EFI FB (FrameBuffer) support"; + +/* EFI XT Loader Protocol */ +PXTBL_LOADER_PROTOCOL XtLdrProtocol; + +/* XT FrameBuffer Information */ +XT_FRAMEBUFFER_INFORMATION FrameBufferInfo; + +/* XT FrameBuffer Protocol */ +XT_FRAMEBUFFER_PROTOCOL XtFramebufferProtocol; + +/** + * Provides a current FrameBuffer driver name. + * + * @param DriverName + * Supplies a pointer to the memory area where FB driver name will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +FbGetDisplayDriver(OUT PWCHAR DriverName) +{ + switch(FrameBufferInfo.Protocol) + { + case GOP: + DriverName = L"GOP"; + break; + case UGA: + DriverName = L"UGA"; + break; + default: + DriverName = L"NONE"; + break; + } +} + +/** + * Returns information about frame buffer in XTOS compatible format. + * + * @param InformationBlock + * A pointer to memory area containing XT structure where all the information will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock) +{ + InformationBlock->Initialized = FrameBufferInfo.Initialized; + InformationBlock->Protocol = FrameBufferInfo.Protocol; + InformationBlock->Address = (PVOID)(ULONG_PTR)FrameBufferInfo.FrameBufferBase; + InformationBlock->BufferSize = FrameBufferInfo.FrameBufferSize; + InformationBlock->Width = FrameBufferInfo.HorizontalResolution; + InformationBlock->Height = FrameBufferInfo.VerticalResolution; + InformationBlock->BitsPerPixel = FrameBufferInfo.BitsPerPixel; + InformationBlock->PixelsPerScanLine = FrameBufferInfo.PixelsPerScanLine; + InformationBlock->Pitch = FrameBufferInfo.Pitch; +} + +/** + * Initializes FrameBuffer device on GOP and UGA compatible adapters. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FbInitializeDisplay() +{ + EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; + UINT32 Parameter1, Parameter2; + EFI_STATUS Status; + + /* Check if framebuffer already initialized */ + if(!FrameBufferInfo.Initialized) + { + /* Initialize framebuffer */ + XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n"); + FrameBufferInfo.Protocol = NONE; + FrameBufferInfo.Initialized = FALSE; + + /* Attempt to open GOP protocol */ + Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufferInfo.Adapter.GOP, &GopGuid); + + /* Check if Graphics Output Protocol is available */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Found GOP */ + XtLdrProtocol->Debug.Print(L"Found GOP compatible display adapter\n"); + + /* Set framebuffer parameters */ + FrameBufferInfo.HorizontalResolution = FrameBufferInfo.Adapter.GOP->Mode->Info->HorizontalResolution; + FrameBufferInfo.VerticalResolution = FrameBufferInfo.Adapter.GOP->Mode->Info->VerticalResolution; + FrameBufferInfo.BitsPerPixel = GoppGetBitsPerPixel(); + FrameBufferInfo.BytesPerPixel = FrameBufferInfo.BitsPerPixel >> 3; + FrameBufferInfo.PixelsPerScanLine = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelsPerScanLine; + FrameBufferInfo.PixelFormat = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelFormat; + FrameBufferInfo.Pitch = FrameBufferInfo.PixelsPerScanLine * (FrameBufferInfo.BitsPerPixel / 8); + FrameBufferInfo.FrameBufferBase = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferBase; + FrameBufferInfo.FrameBufferSize = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferSize; + FrameBufferInfo.Protocol = GOP; + FrameBufferInfo.Initialized = TRUE; + } + else + { + /* GOP is unavailable */ + FrameBufferInfo.Adapter.GOP = NULL; + + /* Attempt to open UGA protocol */ + Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufferInfo.Adapter.UGA, &UgaGuid); + + /* Check if Universal Graphics Adapter is available */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Found UGA */ + XtLdrProtocol->Debug.Print(L"Found UGA compatible display adapter\n"); + + /* Get current mode */ + Status = FrameBufferInfo.Adapter.UGA->GetMode(FrameBufferInfo.Adapter.UGA, + &FrameBufferInfo.HorizontalResolution, + &FrameBufferInfo.VerticalResolution, + &Parameter1, &Parameter2); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get current UGA mode */ + XtLdrProtocol->Debug.Print(L"Failed to get current UGA mode (Status code: %lx)\n", Status); + FrameBufferInfo.Adapter.UGA = NULL; + } + else + { + /* Set framebuffer parameters */ + FrameBufferInfo.BitsPerPixel = 32; + FrameBufferInfo.BytesPerPixel = 4; + FrameBufferInfo.PixelsPerScanLine = FrameBufferInfo.HorizontalResolution; + FrameBufferInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + FrameBufferInfo.Pitch = FrameBufferInfo.PixelsPerScanLine * (FrameBufferInfo.BitsPerPixel / 8); + FrameBufferInfo.FrameBufferBase = 0; + FrameBufferInfo.FrameBufferSize = FrameBufferInfo.HorizontalResolution * + FrameBufferInfo.VerticalResolution * + FrameBufferInfo.BytesPerPixel + 1024; + FrameBufferInfo.Protocol = UGA; + + /* Temporarily set this to FALSE, as we don't set FB base and we cannot use it anyway */ + FrameBufferInfo.Initialized = FALSE; + } + } + } + + /* Make sure framebuffer initialized properly */ + if(!FrameBufferInfo.Initialized) + { + /* GOP and UGA unavailable */ + XtLdrProtocol->Debug.Print(L"No display adapter found\n"); + return STATUS_EFI_NOT_FOUND; + } + } + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Prints important information about framebuffer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +FbPrintDisplayInformation() +{ + PWCHAR DriverName; + + /* Make sure frame buffer is initialized */ + if(!FrameBufferInfo.Initialized) + { + /* No FrameBuffer */ + XtLdrProtocol->Debug.Print(L"No display adapters initialized, unable to print video information\n"); + return; + } + + /* Get display driver name */ + FbGetDisplayDriver(DriverName); + + /* Print video information */ + XtLdrProtocol->Debug.Print(L"TEST: %S\n", DriverName); + XtLdrProtocol->Debug.Print(L"XTLDR Framebuffer information:\n" + L" FrameBuffer Address: 0x%lx\n" + L" FrameBuffer Size: %lu\n" + L" FrameBuffer Driver: %S\n", + FrameBufferInfo.FrameBufferBase, FrameBufferInfo.FrameBufferSize, DriverName); + XtLdrProtocol->Debug.Print(L" Current Resolution: %dx%dx%d\n" + L" Pixel Format: %u\n" + L" Pixels Per ScanLine: %u\n", + FrameBufferInfo.HorizontalResolution, FrameBufferInfo.VerticalResolution, + FrameBufferInfo.BitsPerPixel, FrameBufferInfo.PixelFormat, + FrameBufferInfo.PixelsPerScanLine); +} + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_GUID Guid = XT_FRAMEBUFFER_PROTOCOL_GUID; + EFI_STATUS Status; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open loader protocol */ + return STATUS_EFI_PROTOCOL_ERROR; + } + + XtFramebufferProtocol.GetDisplayDriver = FbGetDisplayDriver; + XtFramebufferProtocol.GetDisplayInformation = FbGetDisplayInformation; + XtFramebufferProtocol.Initialize = FbInitializeDisplay; + XtFramebufferProtocol.PrintDisplayInformation = FbPrintDisplayInformation; + + /* Register XTOS boot protocol */ + return XtLdrProtocol->Protocol.Register(&Guid, &XtFramebufferProtocol); +} diff --git a/xtldr2/modules/fb_o/gop.c b/xtldr2/modules/fb_o/gop.c new file mode 100644 index 0000000..baa746f --- /dev/null +++ b/xtldr2/modules/fb_o/gop.c @@ -0,0 +1,51 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/fb_o/gop.c + * DESCRIPTION: Graphical Output Protocol (GOP) support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Returns a number of bits per pixel (BPP) in the current video mode. + * + * @return A number of bits per pixel. + * + * @since XT 1.0 + */ +XTCDECL +UINT32 +GoppGetBitsPerPixel() +{ + UINT32 BitsPerPixel, CompoundMask; + + switch(FrameBufferInfo.Adapter.GOP->Mode->Info->PixelFormat) + { + case PixelBlueGreenRedReserved8BitPerColor: + case PixelRedGreenBlueReserved8BitPerColor: + case PixelBltOnly: + BitsPerPixel = 32; + break; + case PixelBitMask: + BitsPerPixel = 32; + CompoundMask = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.RedMask | + FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.GreenMask | + FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.BlueMask | + FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.ReservedMask; + while((CompoundMask & (1 << 31)) == 0) + { + BitsPerPixel--; + CompoundMask <<= 1; + } + break; + default: + BitsPerPixel = 0; + break; + } + + /* Return bpp */ + return BitsPerPixel; +} diff --git a/xtldr2/modules/fb_o/includes/framebuf.h b/xtldr2/modules/fb_o/includes/framebuf.h new file mode 100644 index 0000000..164eae4 --- /dev/null +++ b/xtldr2/modules/fb_o/includes/framebuf.h @@ -0,0 +1,79 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/fb_o/includes/framebuf.h + * DESCRIPTION: Framebuffer support module header file + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_MODULES_FRAMEBUF_H +#define __XTLDR_MODULES_FRAMEBUF_H + +#include + + +typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR DriverName); +typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); +typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)(); +typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)(); + +/* XT framebuffer support protocol */ +typedef struct _XT_FRAMEBUFFER_PROTOCOL +{ + PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver; + PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation; + PXT_FRAMEBUFFER_INITIALIZE Initialize; + PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation; +} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL; + +/* XT framebuffer information structure definition */ +typedef struct _XT_FRAMEBUFFER_INFORMATION +{ + BOOLEAN Initialized; + EFI_GRAPHICS_PROTOCOL Protocol; + union + { + PEFI_GRAPHICS_OUTPUT_PROTOCOL GOP; + PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL UGA; + } Adapter; + UINT HorizontalResolution; + UINT VerticalResolution; + UINT BitsPerPixel; + UINT BytesPerPixel; + UINT PixelsPerScanLine; + UINT Pitch; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PHYSICAL_ADDRESS FrameBufferBase; + ULONG_PTR FrameBufferSize; +} XT_FRAMEBUFFER_INFORMATION, *PXT_FRAMEBUFFER_INFORMATION; + +/* XT FrameBuffer Information */ +EXTERN XT_FRAMEBUFFER_INFORMATION FrameBufferInfo; + +/* FrameBuffer support protocol related routines forward references */ +XTCDECL +VOID +FbGetDisplayDriver(OUT PWCHAR DriverName); + +XTCDECL +VOID +FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); + +XTCDECL +EFI_STATUS +FbInitializeDisplay(); + +XTCDECL +VOID +FbPrintDisplayInformation(); + +XTCDECL +UINT32 +GoppGetBitsPerPixel(); + +XTCDECL +EFI_STATUS +BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif /* __XTLDR_MODULES_FRAMEBUF_H */ -- 2.45.1 From a90cf727c524def4a78d903a59421e7c760edcd8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 23:19:51 +0100 Subject: [PATCH 139/182] Implement BlGetMemoryMap() routine --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/includes/xtldr.h | 4 +++ xtldr2/memory.c | 63 +++++++++++++++++++++++++++++++++++++++++ xtldr2/protocol.c | 1 + 4 files changed, 70 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 062fb78..0d84500 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -73,6 +73,7 @@ typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey); typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); 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_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); @@ -235,6 +236,7 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_ALLOCATE_POOL AllocatePool; PBL_FREE_PAGES FreePages; PBL_FREE_POOL FreePool; + PBL_GET_MEMORY_MAP GetMemoryMap; } Memory; struct { diff --git a/xtldr2/includes/xtldr.h b/xtldr2/includes/xtldr.h index 3480f68..bebc8ca 100644 --- a/xtldr2/includes/xtldr.h +++ b/xtldr2/includes/xtldr.h @@ -102,6 +102,10 @@ XTCDECL PWCHAR BlGetConfigValue(IN CONST PWCHAR ConfigName); +XTCDECL +EFI_STATUS +BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); + XTCDECL INT_PTR BlGetSecureBootStatus(); diff --git a/xtldr2/memory.c b/xtldr2/memory.c index 19e9397..8df0448 100644 --- a/xtldr2/memory.c +++ b/xtldr2/memory.c @@ -9,6 +9,69 @@ #include +/** + * Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI. + * + * @param MemoryMap + * Supplies a pointer to the buffer where memory map will be written. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) +{ + EFI_STATUS Status; + + if(MemoryMap == NULL) + { + return STATUS_EFI_INVALID_PARAMETER; + } + + MemoryMap->Map = NULL; + MemoryMap->MapSize = 0; + + /* Get memory map */ + do + { + /* Attempt do get EFI memory map */ + Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMap->MapSize, MemoryMap->Map, &MemoryMap->MapKey, + &MemoryMap->DescriptorSize, &MemoryMap->DescriptorVersion); + if(Status == STATUS_EFI_SUCCESS) + { + /* Go further if succeeded */ + break; + } + else if(Status != STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Some error occurred */ + if(MemoryMap->Map) + { + /* Free allocated memory */ + BlMemoryFreePool(MemoryMap->Map); + } + return Status; + } + + /* Allocate the desired amount of memory */ + MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; + BlMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); + } + while(Status == STATUS_EFI_BUFFER_TOO_SMALL); + + /* Make sure memory map is set */ + if(MemoryMap->Map == NULL) + { + /* Something went wrong */ + return STATUS_EFI_NO_MAPPING; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * This routine allocates one or more 4KB pages. * diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 23f131d..3fdb77b 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -592,6 +592,7 @@ BlpRegisterXtLoaderProtocol() BlpLdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool; BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages; BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool; + BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; BlpLdrProtocol.Protocol.Open = BlOpenProtocol; BlpLdrProtocol.Protocol.Register = BlRegisterProtocol; BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; -- 2.45.1 From e0b31ad9457f04d06f8693d0178cb974dd8fd2e0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 2 Jan 2024 23:41:37 +0100 Subject: [PATCH 140/182] Import old and deprecated 'xtos_o' module from old XTLDR --- sdk/xtdk/xtblapi.h | 8 +- xtldr2/modules/CMakeLists.txt | 1 + xtldr2/modules/xtos_o/CMakeLists.txt | 28 ++ xtldr2/modules/xtos_o/amd64/memory.c | 305 ++++++++++++++ xtldr2/modules/xtos_o/i686/memory.c | 329 ++++++++++++++++ xtldr2/modules/xtos_o/includes/xtos.h | 107 +++++ xtldr2/modules/xtos_o/memory.c | 385 ++++++++++++++++++ xtldr2/modules/xtos_o/xtos.c | 548 ++++++++++++++++++++++++++ 8 files changed, 1708 insertions(+), 3 deletions(-) create mode 100644 xtldr2/modules/xtos_o/CMakeLists.txt create mode 100644 xtldr2/modules/xtos_o/amd64/memory.c create mode 100644 xtldr2/modules/xtos_o/i686/memory.c create mode 100644 xtldr2/modules/xtos_o/includes/xtos.h create mode 100644 xtldr2/modules/xtos_o/memory.c create mode 100644 xtldr2/modules/xtos_o/xtos.c diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index 5da87e8..78b3e7b 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -32,15 +32,17 @@ #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) +#include ARCH_HEADER(ketypes.h) +#include ARCH_HEADER(mmtypes.h) /* XT Kernel runtime routines */ #include #include /* Architecture specific XT kernel routines */ -// #include ARCH_HEADER(arfuncs.h) +#include ARCH_HEADER(arfuncs.h) // #include ARCH_HEADER(hlfuncs.h) /* Boot Manager specific structures */ diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt index ffdddb3..136fbbb 100644 --- a/xtldr2/modules/CMakeLists.txt +++ b/xtldr2/modules/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(dummy) add_subdirectory(fb_o) add_subdirectory(pecoff_o) +add_subdirectory(xtos_o) diff --git a/xtldr2/modules/xtos_o/CMakeLists.txt b/xtldr2/modules/xtos_o/CMakeLists.txt new file mode 100644 index 0000000..f157240 --- /dev/null +++ b/xtldr2/modules/xtos_o/CMakeLists.txt @@ -0,0 +1,28 @@ +# XT Boot Loader +PROJECT(XTLDR_XTOS_O) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_XTOS_O_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_XTOS_O_SOURCE + ${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c + ${XTLDR_XTOS_O_SOURCE_DIR}/memory.c + ${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c) + +# Link bootloader executable +add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE}) + +# Add linker libraries +target_link_libraries(xtos_o libxtos libxtldr) + +# Set proper binary name and install target +set_target_properties(xtos_o PROPERTIES SUFFIX .efi) +set_install_target(xtos_o efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(xtos_o "XtLdrModuleMain") +set_linker_map(xtos_o TRUE) +set_subsystem(xtos_o efi_boot_service_driver) diff --git a/xtldr2/modules/xtos_o/amd64/memory.c b/xtldr2/modules/xtos_o/amd64/memory.c new file mode 100644 index 0000000..3a21055 --- /dev/null +++ b/xtldr2/modules/xtos_o/amd64/memory.c @@ -0,0 +1,305 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/amd64/memory.c + * DESCRIPTION: EFI memory management for AMD64 target + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param ImageProtocol + * A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed. + * + * @param PtePointer + * Supplies a pointer to memory area containing a Page Table Entries (PTE). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtEnablePaging(IN PLIST_ENTRY MemoryMappings, + IN PVOID VirtualAddress, + IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, + IN PVOID *PtePointer) +{ + PLOADER_MEMORY_MAPPING Mapping; + EFI_PHYSICAL_ADDRESS Address; + PEFI_MEMORY_MAP MemoryMap; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + + /* Allocate pages for PML4 */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Assign and zero-fill memory used by page mappings */ + *PtePointer = (PVOID)(UINT_PTR)Address; + RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE); + + /* Map XTLDR code */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, + EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping the boot loader code failed */ + return Status; + } + + /* Add page mapping itself to memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping PML4 failed */ + return Status; + } + + /* Iterate through and map all the mappings*/ + XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n"); + ListEntry = MemoryMappings->Flink; + while(ListEntry != MemoryMappings) + { + /* Take mapping from the list */ + Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + + /* Check if virtual address is set */ + if(Mapping->VirtualAddress) + { + /* Dump memory mapping */ + XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType, + Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); + + /* Map memory */ + Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failed */ + return Status; + } + } + + /* Take next element */ + ListEntry = ListEntry->Flink; + } + + /* Map zero page as well */ + XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer); + + /* Allocate and zero-fill buffer for EFI memory map */ + XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + + /* Get EFI memory map and prepare for exiting boot services */ + XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get memory map */ + return Status; + } + + /* Exit EFI Boot Services */ + Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey); + + /* Check if exitted boot services successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to exit boot services */ + XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %lx)\n", Status); + return STATUS_EFI_ABORTED; + } + + /* Write PML4 to CR3 */ + ArWriteControlRegister(3, (UINT_PTR)*PtePointer); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine does the actual virtual memory mapping. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @param PaeExtension + * Specifies whether Physical Address Extension (PAE) is supported by the hardware. Not used on AMD64. + * + * @param PtePointer + * Supplies a pointer to an array of pointers to page table entries. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PVOID *PtePointer) +{ + PHARDWARE_PTE PageDirectoryPointTable, PageDirectory, PageTable; + UINT Pml4Index, PdpIndex, PdIndex, PtIndex; + EFI_PHYSICAL_ADDRESS Address; + UINT_PTR PageFrameNumber; + EFI_STATUS Status; + UINT64 Pointer; + + /* Set the PFN */ + PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; + + /* Do the recursive mapping */ + while(NumberOfPages > 0) + { + /* Calculate indices from a virtual address */ + Pml4Index = (VirtualAddress >> 39) & 0x1FF; + PdpIndex = (VirtualAddress >> 30) & 0x1FF; + PdIndex = (VirtualAddress >> 21) & 0x1FF; + PtIndex = (VirtualAddress >> 12) & 0x1FF; + + /* Validate Page Map Level 4 (PML4) */ + if(!((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid) + { + /* Allocate pages for the PDPT */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if(Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Fill allocated memory with zeros */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry settings */ + ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber = Address / EFI_PAGE_SIZE; + ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid = 1; + ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Write = 1; + PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Directory Point Table (PDPT) */ + Pointer = ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Validate Page Directory Point Table (PDPT)*/ + if(!PageDirectoryPointTable[PdpIndex].Valid) + { + /* Allocate pages for the PD */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Fill allocated memory with zeros */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry settings */ + PageDirectoryPointTable[PdpIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; + PageDirectoryPointTable[PdpIndex].Valid = 1; + PageDirectoryPointTable[PdpIndex].Write = 1; + PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Directory (PD) */ + Pointer = PageDirectoryPointTable[PdpIndex].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Validate Page Directory (PD)*/ + if(!PageDirectory[PdIndex].Valid) + { + /* Allocate pages for the PT */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Fill allocated memory with zeros */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry settings */ + PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; + PageDirectory[PdIndex].Valid = 1; + PageDirectory[PdIndex].Write = 1; + PageTable = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Table (PT) */ + Pointer = PageDirectory[PdIndex].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Set paging entry settings */ + PageTable[PtIndex].PageFrameNumber = PageFrameNumber; + PageTable[PtIndex].Valid = 1; + PageTable[PtIndex].Write = 1; + + /* Take next virtual address and PFN */ + VirtualAddress += EFI_PAGE_SIZE; + PageFrameNumber++; + + /* Decrease number of pages left */ + NumberOfPages--; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr2/modules/xtos_o/i686/memory.c b/xtldr2/modules/xtos_o/i686/memory.c new file mode 100644 index 0000000..f0d1354 --- /dev/null +++ b/xtldr2/modules/xtos_o/i686/memory.c @@ -0,0 +1,329 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/i686/memory.c + * DESCRIPTION: EFI memory management for i686 target + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param ImageProtocol + * A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed. + * + * @param PtePointer + * Supplies a pointer to memory area containing a Page Table Entries (PTE). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtEnablePaging(IN PLIST_ENTRY MemoryMappings, + IN PVOID VirtualAddress, + IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, + IN PVOID *PtePointer) +{ + UINT_PTR PhysicalAddress, DescriptorCount; + EFI_PHYSICAL_ADDRESS Address, PDPTAddress = 0; + PCPUID_REGISTERS CpuRegisters = NULL; + PEFI_MEMORY_DESCRIPTOR Descriptor; + PLOADER_MEMORY_MAPPING Mapping; + PEFI_MEMORY_MAP MemoryMap; + PLIST_ENTRY ListEntry; + EFI_STATUS Status; + UINT Index; + + /* Prepare CPUID registers */ + CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; + CpuRegisters->SubLeaf = 0; + CpuRegisters->Eax = 0; + CpuRegisters->Ebx = 0; + CpuRegisters->Ecx = 0; + CpuRegisters->Edx = 0; + + /* Get CPUID */ + ArCpuId(CpuRegisters); + + /* Store PAE status from the CPUID results */ + if(!(CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE)) + { + /* No PAE support */ + XtLdrProtocol->Debug.Print(L"ERROR: PAE extension not supported by the CPU\n"); + return STATUS_EFI_UNSUPPORTED; + } + + /* Allocate and zero-fill buffer for EFI memory map */ + XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + + /* Get EFI memory map */ + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get memory map */ + return Status; + } + + /* Calculate descriptors count and get first one */ + Descriptor = MemoryMap->Map; + DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; + + /* Calculate physical address based on KSEG0 base */ + PhysicalAddress = (UINT_PTR)VirtualAddress - KSEG0_BASE; + + /* Iterate over all descriptors from memory map to find satisfying address for PDPT */ + for(Index = 0; Index < DescriptorCount; Index++) + { + /* Check descriptor if it can be used to store PDPT */ + if((Descriptor->PhysicalStart + ((Descriptor->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) && + (Descriptor->Type == EfiConventionalMemory)) + { + /* Use highest address possible */ + if(PhysicalAddress >= Descriptor->PhysicalStart) + { + /* Use physical address */ + PDPTAddress = PhysicalAddress; + } + else + { + /* Use descriptor physical start as PDPT address */ + PDPTAddress = Descriptor->PhysicalStart; + } + + /* Allocate pages for the PDPT address */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &PDPTAddress); + if(Status != STATUS_EFI_SUCCESS) { + return Status; + } + break; + } + + /* Get next descriptor */ + Descriptor = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)Descriptor + MemoryMap->DescriptorSize); + } + + /* Make sure PDPT address found */ + if(PDPTAddress == 0) + { + /* No suitable area for PDPT found in EFI memory map */ + return STATUS_EFI_NOT_FOUND; + } + + /* Set virtual address based on new PDPT address mapped to KSEG0 base */ + VirtualAddress = (PVOID)(UINT_PTR)(PDPTAddress + EFI_PAGE_SIZE + KSEG0_BASE); + + /* Set base page frame number */ + Address = 0x100000; + + /* Allocate pages for the PFN */ + Status = XtLdrProtocol->Memory.AllocatePages(4, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set and zero memory used by page mappings and CR3 */ + *PtePointer = (PVOID)(UINT_PTR)PDPTAddress; + RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE); + RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE * 4); + + /* Set the page directory into the PDPT and mark it present */ + for(Index = 0; Index < 4; Index++) + { + /* Set paging entry settings */ + ((PHARDWARE_PTE)*PtePointer)[Index].PageFrameNumber = Address / EFI_PAGE_SIZE; + ((PHARDWARE_PTE)*PtePointer)[Index].Valid = 1; + + /* Next valid PFN address */ + Address += EFI_PAGE_SIZE; + } + + /* Map XTLDR code */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, + EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping the boot loader code failed */ + return Status; + } + + /* Add page mapping itself to memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping PD failed */ + return Status; + } + + /* Iterate through and map all the mappings */ + XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n"); + ListEntry = MemoryMappings->Flink; + while(ListEntry != MemoryMappings) + { + /* Take mapping from the list */ + Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + + /* Check if virtual address is set */ + if(Mapping->VirtualAddress) + { + /* Dump memory mapping */ + XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%08lx, VirtualBase=0x%08lx, Pages=%lu\n", Mapping->MemoryType, + Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); + + /* Map memory */ + Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failed */ + return Status; + } + } + + /* Take next element */ + ListEntry = ListEntry->Flink; + } + + /* Map zero page as well */ + XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer); + + /* Zero-fill buffer for EFI memory map */ + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + + /* Get EFI memory map and prepare for exiting boot services */ + XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get memory map */ + return Status; + } + + /* Exit EFI Boot Services */ + Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey); + + /* Check if exitted boot services successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to exit boot services */ + XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %lx)\n", Status); + return STATUS_EFI_ABORTED; + } + + /* Enable Physical Address Extension (PAE) */ + ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE); + + /* Write page mappings to CR3 */ + ArWriteControlRegister(3, (UINT_PTR)*PtePointer); + + /* Enable paging */ + ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine does the actual virtual memory mapping. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @param PaeExtension + * Specifies whether Physical Address Extension (PAE) is supported by the hardware. + * + * @param PtePointer + * Supplies a pointer to an array of pointers to page table entries. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PVOID *PtePointer) +{ + EFI_PHYSICAL_ADDRESS Address; + UINT_PTR PageFrameNumber; + PHARDWARE_PTE PageTable, PageDirectory; + EFI_STATUS Status; + unsigned int PdIndex, PtIndex; + + /* Set the PFN */ + PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; + + /* Do the recursive mapping */ + while(NumberOfPages > 0) + { + /* Find Page Directory and calculate indices from a virtual address */ + PageDirectory = (PHARDWARE_PTE)(UINT_PTR)(((PHARDWARE_PTE)(*PtePointer))[VirtualAddress >> 30].PageFrameNumber * EFI_PAGE_SIZE); + PdIndex = (VirtualAddress >> 21) & 0x1FF; + PtIndex = (VirtualAddress & 0x1FF000) >> 12; + + /* Validate Page Directory */ + if(!PageDirectory[PdIndex].Valid) { + /* Allocate pages for new page table */ + Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + if(Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Fill allocated memory with zeros */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry settings */ + PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; + PageDirectory[PdIndex].Valid = 1; + PageDirectory[PdIndex].Write = 1; + + /* Set page table */ + PageTable = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Set page table */ + PageTable = (PHARDWARE_PTE)(UINT_PTR)(PageDirectory[PdIndex].PageFrameNumber * EFI_PAGE_SIZE); + } + /* Set page table settings */ + PageTable[PtIndex].PageFrameNumber = PageFrameNumber; + PageTable[PtIndex].Valid = 1; + PageTable[PtIndex].Write = 1; + + /* Take next virtual address and PFN */ + VirtualAddress += EFI_PAGE_SIZE; + PageFrameNumber++; + + /* Decrease number of pages left */ + NumberOfPages--; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr2/modules/xtos_o/includes/xtos.h b/xtldr2/modules/xtos_o/includes/xtos.h new file mode 100644 index 0000000..34695c5 --- /dev/null +++ b/xtldr2/modules/xtos_o/includes/xtos.h @@ -0,0 +1,107 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/xtos/includes/xtos.h + * DESCRIPTION: XTOS boot protocol support header + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_MODULES_XTOS_H +#define __XTLDR_MODULES_XTOS_H + +#include + + +typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR DriverName); +typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); +typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)(); +typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)(); + +/* XT framebuffer support protocol */ +typedef struct _XT_FRAMEBUFFER_PROTOCOL +{ + PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver; + PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation; + PXT_FRAMEBUFFER_INITIALIZE Initialize; + PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation; +} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL; + +/* EFI XT Loader Protocol */ +EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; + +/* XTOS kernel entry point */ +typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); + +/* XTOS boot protocol related routines forward references */ +XTCDECL +EFI_STATUS +XtAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, + IN PVOID VirtualAddress, + IN PVOID PhysicalAddress, + IN UINT NumberOfPages, + IN LOADER_MEMORY_TYPE MemoryType); + +XTCDECL +EFI_STATUS +XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters); + +XTCDECL +LOADER_MEMORY_TYPE +XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); + +XTCDECL +EFI_STATUS +XtEnablePaging(IN PLIST_ENTRY MemoryMappings, + IN PVOID VirtualAddress, + IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, + IN PVOID *PtePointer); + +XTCDECL +EFI_STATUS +XtGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, + IN PVOID PhysicalAddress, + OUT PVOID *VirtualAddress); + +XTCDECL +EFI_STATUS +XtInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, + IN OUT PVOID *MemoryMapAddress); + +XTCDECL +EFI_STATUS +XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PVOID *PtePointer); + +XTCDECL +EFI_STATUS +XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, + IN PXTBL_BOOT_PARAMETERS Parameters); + + +XTCDECL +EFI_STATUS +XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings); + +XTCDECL +EFI_STATUS +XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + IN PXTBL_BOOT_PARAMETERS Parameters); + +XTCDECL +EFI_STATUS +XtpLoadModule(IN PEFI_FILE_HANDLE BootDir, + IN PWCHAR FileName, + IN PVOID VirtualAddress, + IN LOADER_MEMORY_TYPE MemoryType, + OUT PPECOFF_IMAGE_CONTEXT *ImageContext); + +XTCDECL +EFI_STATUS +BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif /* __XTLDR_MODULES_XTOS_H */ diff --git a/xtldr2/modules/xtos_o/memory.c b/xtldr2/modules/xtos_o/memory.c new file mode 100644 index 0000000..c64a9cc --- /dev/null +++ b/xtldr2/modules/xtos_o/memory.c @@ -0,0 +1,385 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/memory.c + * DESCRIPTION: EFI memory management + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Adds a physical to virtual address mapping to the linked list for future processing. + * + * @param MemoryMapping + * Supplies the head of the memory mapping list. + * + * @param VirtualAddress + * Supplies a virtual address where the physical address should be mapped. + * + * @param PhysicalAddress + * Supplies a physical address which will be mapped. + * + * @param NumberOfPages + * Supplies a number of pages which will be mapped. + * + * @param MemoryType + * Supplies the type of memory that will be assigned to the memory descriptor. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, + IN PVOID VirtualAddress, + IN PVOID PhysicalAddress, + IN UINT NumberOfPages, + IN LOADER_MEMORY_TYPE MemoryType) +{ + PLOADER_MEMORY_MAPPING Mapping1, Mapping2, Mapping3; + PVOID PhysicalAddressEnd, PhysicalAddress2End; + PLIST_ENTRY ListEntry, MappingListEntry; + SIZE_T NumberOfMappedPages; + EFI_STATUS Status; + + /* Allocate memory for new mapping */ + Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID *)&Mapping1); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set mapping fields */ + Mapping1->PhysicalAddress = PhysicalAddress; + Mapping1->VirtualAddress = VirtualAddress; + Mapping1->NumberOfPages = NumberOfPages; + Mapping1->MemoryType = MemoryType; + + /* Calculate the end of the physical address */ + PhysicalAddressEnd = (PUINT8)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1; + + /* Iterate through all the mappings already set to insert new mapping at the correct place */ + ListEntry = MemoryMappings->Flink; + while(ListEntry != MemoryMappings) + { + /* Take a mapping from the list and calculate its end of physical address */ + Mapping2 = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1 ; + + /* Check if they overlap */ + if(PhysicalAddressEnd > Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End) + { + /* Make sure it's memory type is LoaderFree */ + if(Mapping2->MemoryType != LoaderFree) + { + /* LoaderFree memory type is strictly expected */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Calculate number of pages for this mapping */ + NumberOfMappedPages = ((PUINT8)PhysicalAddress2End - (PUINT8)PhysicalAddressEnd) / EFI_PAGE_SIZE; + if(NumberOfMappedPages > 0) + { + /* Pages associated to the mapping, allocate memory for it */ + Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set mapping fields and insert it on the top */ + Mapping3->PhysicalAddress = (PUINT8)PhysicalAddressEnd + 1; + Mapping3->VirtualAddress = NULL; + Mapping3->NumberOfPages = NumberOfMappedPages; + Mapping3->MemoryType = Mapping2->MemoryType; + RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); + } + + /* Calculate number of pages and the end of the physical address */ + Mapping2->NumberOfPages = ((PUINT8)PhysicalAddressEnd + 1 - + (PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; + PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; + } + + /* Check if they overlap */ + if(Mapping1->PhysicalAddress > Mapping2->PhysicalAddress && Mapping1->PhysicalAddress < PhysicalAddress2End) + { + /* Make sure it's memory type is LoaderFree */ + if(Mapping2->MemoryType != LoaderFree) + { + /* LoaderFree memory type is strictly expected */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Calculate number of pages for this mapping */ + NumberOfMappedPages = ((PUINT8)PhysicalAddress2End + 1 - (PUINT8)Mapping1->PhysicalAddress) / EFI_PAGE_SIZE; + if(NumberOfMappedPages > 0) + { + /* Pages associated to the mapping, allocate memory for it */ + Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Set mapping fields and insert it on the top */ + Mapping3->PhysicalAddress = Mapping1->PhysicalAddress; + Mapping3->VirtualAddress = NULL; + Mapping3->NumberOfPages = NumberOfMappedPages; + Mapping3->MemoryType = Mapping2->MemoryType; + RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); + } + + /* Calculate number of pages and the end of the physical address */ + Mapping2->NumberOfPages = ((PUINT8)Mapping1->PhysicalAddress - + (PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; + PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; + } + + /* Check if mapping is really needed */ + if((Mapping2->PhysicalAddress >= Mapping1->PhysicalAddress && PhysicalAddress2End <= PhysicalAddressEnd) || + (Mapping2->NumberOfPages == 0)) + { + /* Make sure it's memory type is LoaderFree */ + if(Mapping2->MemoryType != LoaderFree) + { + /* LoaderFree memory type is strictly expected */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Store address of the next mapping */ + MappingListEntry = ListEntry->Flink; + + /* Remove mapping from the list and free up it's memory */ + RtlRemoveEntryList(&Mapping2->ListEntry); + Status = XtLdrProtocol->Memory.FreePool(Mapping2); + ListEntry = MappingListEntry; + + /* Go to the next mapping */ + continue; + } + + /* Determine phsical address order */ + if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress) + { + /* Insert new mapping in front */ + RtlInsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); + return STATUS_EFI_SUCCESS; + } + + /* Get next mapping from the list */ + ListEntry = ListEntry->Flink; + } + + /* Insert new mapping to the end of the list and return success */ + RtlInsertTailList(MemoryMappings, &Mapping1->ListEntry); + return STATUS_EFI_SUCCESS; +} + +/** + * Converts an EFI memory type into an XTOS memory type. + * + * @param EfiMemoryType + * Supplies the EFI memory type. + * + * @return Returns a conversion of the memory type. + * + * @since XT 1.0 + */ +XTCDECL +LOADER_MEMORY_TYPE +XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) +{ + LOADER_MEMORY_TYPE MemoryType; + + /* Check EFI memory type and convert to XTOS memory type */ + switch(EfiMemoryType) + { + case EfiACPIMemoryNVS: + case EfiACPIReclaimMemory: + case EfiPalCode: + MemoryType = LoaderSpecialMemory; + break; + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + MemoryType = LoaderFirmwarePermanent; + break; + case EfiBootServicesData: + case EfiLoaderCode: + case EfiLoaderData: + MemoryType = LoaderFirmwareTemporary; + break; + case EfiUnusableMemory: + MemoryType = LoaderBad; + break; + default: + MemoryType = LoaderFree; + break; + } + + /* Return XTOS memory type */ + return MemoryType; +} + +/** + * Attempts to find a virtual address of the specified physical address in memory mappings. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param PhysicalAddress + * Supplies a physical address to search for in the mappings. + * + * @param VirtualAddress + * Supplies a buffer, where mapped virtual address of the found mapping will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, + IN PVOID PhysicalAddress, + OUT PVOID *VirtualAddress) +{ + PLOADER_MEMORY_MAPPING Mapping; + PLIST_ENTRY ListEntry; + + /* NULLify virtual address */ + *VirtualAddress = NULL; + + /* Iterate over memory mappings in order to find descriptor containing a physical address */ + ListEntry = MemoryMappings->Flink; + while(ListEntry != MemoryMappings) + { + /* Get mapping from linked list */ + Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + + /* Make sure any virtual address is set */ + if(Mapping->VirtualAddress) + { + /* Check if provided physical address is in range of this mapping */ + if((PhysicalAddress >= Mapping->PhysicalAddress) && + (PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) + { + /* Calculate virtual address based on the mapping */ + *VirtualAddress = PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress; + } + } + + /* Get next element from the list */ + ListEntry = ListEntry->Flink; + } + + /* If virtual address is still NULL, then mapping was not found */ + if(*VirtualAddress == NULL) + { + /* Mapping not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Mapping found, return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Initializes virtual memory by adding known and general mappings. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param MemoryMapAddress + * Supplies an address of the mapped virtual memory area. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, + IN OUT PVOID *MemoryMapAddress) +{ + PEFI_MEMORY_DESCRIPTOR Descriptor; + LOADER_MEMORY_TYPE MemoryType; + PEFI_MEMORY_MAP MemoryMap; + SIZE_T DescriptorCount; + PUCHAR VirtualAddress; + EFI_STATUS Status; + SIZE_T Index; + + /* Set initial virtual address */ + VirtualAddress = *MemoryMapAddress; + + /* Allocate and zero-fill buffer for EFI memory map */ + XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + + /* Get EFI memory map */ + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + return Status; + } + + /* Calculate descriptors count and get first one */ + Descriptor = MemoryMap->Map; + DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; + + /* Iterate through all descriptors from the memory map */ + for(Index = 0; Index < DescriptorCount; Index++) + { + /* Make sure descriptor does not go beyond lowest physical page */ + if((Descriptor->PhysicalStart + (Descriptor->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1) + { + /* Convert EFI memory type into XTOS memory type */ + MemoryType = XtConvertEfiMemoryType(Descriptor->Type); + + /* Do memory mappings depending on memory type */ + if(MemoryType == LoaderFirmwareTemporary) + { + /* Map EFI firmware code */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, (PVOID)Descriptor->PhysicalStart, + (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); + } + else if(MemoryType != LoaderFree) + { + /* Add any non-free memory mapping */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); + + /* Calculate next valid virtual address */ + VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; + } + else + { + /* Map all other memory as loader free */ + Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, LoaderFree); + } + + /* Make sure memory mapping succeeded */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping failed */ + return Status; + } + + /* Grab next descriptor */ + Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize); + } + } + + /* Store next valid virtual address and return success */ + *MemoryMapAddress = VirtualAddress; + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr2/modules/xtos_o/xtos.c b/xtldr2/modules/xtos_o/xtos.c new file mode 100644 index 0000000..b8aec1f --- /dev/null +++ b/xtldr2/modules/xtos_o/xtos.c @@ -0,0 +1,548 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/xtos/xtos.c + * DESCRIPTION: XTOS boot protocol support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* XTOS module information */ +XTBL_MODINFO = L"XTOS boot protocol support"; +XTBL_MODDEPS = {L"fb_o", L"pecoff_o"}; + +/* EFI XT Loader Protocol */ +PXTBL_LOADER_PROTOCOL XtLdrProtocol; + +/* XTOS PE/COFF Image Protocol */ +PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol; + +/* XTOS Boot Protocol */ +XTBL_BOOT_PROTOCOL XtBootProtocol; + +/* XTOS Page Map */ +PVOID XtPageMap; + +/** + * Starts the operating system according to the provided parameters using XTOS boot protocol. + * + * @param Parameters + * Input parameters with detailed system configuration like boot device or kernel path. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) +{ + EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; + EFI_HANDLE DiskHandle; + PEFI_FILE_HANDLE FsHandle, BootDir; + PWCHAR SystemPath; + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n"); + + /* Open the XT PE/COFF protocol */ + Status = XtLdrProtocol->Protocol.Open((PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open loader protocol */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n"); + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Check device path */ + if(Parameters->DevicePath == NULL) + { + /* No device path set */ + XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n"); + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Check if system path is set */ + if(Parameters->SystemPath != NULL) + { + /* Make sure system path begins with backslash, the only separator supported by EFI */ + if(Parameters->SystemPath[0] == '/') + { + /* Replace directory separator if needed */ + Parameters->SystemPath[0] = '\\'; + } + + /* Validate system path */ + SystemPath = &Parameters->SystemPath[1]; + while(*SystemPath) + { + /* Make sure it does not point to any subdirectory and not contains special characters */ + if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10)) + { + /* Invalid path specified */ + XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n"); + return STATUS_EFI_INVALID_PARAMETER; + } + /* Check next character in the path */ + SystemPath++; + } + } + else + { + /* Fallback to '/ExectOS' by default */ + XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n"); + Parameters->SystemPath = L"\\ExectOS"; + } + + /* Check if kernel file is set */ + if(Parameters->KernelFile == NULL) + { + /* No kernel filename set, fallback to default */ + XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n"); + Parameters->KernelFile = L"xtoskrnl.exe"; + } + + /* Check if provided any kernel boot arguments */ + if(Parameters->Parameters == NULL) + { + /* No argument supplied */ + Parameters->Parameters = L""; + } + + /* Print a debug message */ + XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n" + L"[XTOS] System Path: %S\n" + L"[XTOS] Kernel File: %S\n" + L"[XTOS] Boot Arguments: %S\n", + Parameters->ArcName, Parameters->SystemPath, + Parameters->KernelFile, Parameters->Parameters); + + /* Open EFI volume */ + Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n"); + return Status; + } + + /* System path has to point to the boot directory */ + RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0); + + /* Open XTOS system boot directory */ + Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if system path directory opened successfully */ + if(Status == STATUS_EFI_NOT_FOUND) + { + /* Directory not found, nothing to load */ + XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n"); + + /* Close volume */ + XtLdrProtocol->Disk.CloseVolume(DiskHandle); + return Status; + } + else if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n"); + XtLdrProtocol->Disk.CloseVolume(DiskHandle); + return Status; + } + + /* Start boot sequence */ + return XtpBootSequence(BootDir, Parameters); +} + +/** + * This routine initiates an XTOS boot sequence. + * + * @param BootDir + * An EFI handle to the XTOS boot directory. + * + * @param Parameters + * Input parameters with detailed system configuration like boot device or kernel path. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, + IN PXTBL_BOOT_PARAMETERS Parameters) +{ + EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PKERNEL_INITIALIZATION_BLOCK KernelParameters; + PPECOFF_IMAGE_CONTEXT ImageContext = NULL; + PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; + PVOID VirtualAddress, VirtualMemoryArea; + PXT_ENTRY_POINT KernelEntryPoint; + LIST_ENTRY MemoryMappings; + EFI_STATUS Status; + + /* Initialize XTOS startup sequence */ + XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n"); + + /* Set base virtual memory area for the kernel mappings */ + VirtualMemoryArea = (PVOID)KSEG0_BASE; + VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE); + + /* Initialize memory mapping linked list */ + RtlInitializeListHead(&MemoryMappings); + + /* Initialize virtual memory mappings */ + Status = XtInitializeVirtualMemory(&MemoryMappings, &VirtualMemoryArea); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to initialize virtual memory */ + return Status; + } + + /* Load the kernel */ + Status = XtpLoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load the kernel */ + return Status; + } + + /* Add kernel image memory mapping */ + Status = XtAddVirtualMemoryMapping(&MemoryMappings, ImageContext->VirtualAddress, + ImageContext->PhysicalAddress, ImageContext->ImagePages, 0); + if(Status != STATUS_EFI_SUCCESS) + { + return Status; + } + + /* Set next valid virtual address right after the kernel */ + VirtualAddress += ImageContext->ImagePages * EFI_PAGE_SIZE; + + /* Store virtual address of kernel initialization block for future kernel call */ + KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress; + + /* Setup and map kernel initialization block */ + Status = XtpInitializeLoaderBlock(&MemoryMappings, &VirtualAddress, Parameters); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to setup kernel initialization block */ + XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: %lx)\n", Status); + return Status; + } + + /* Find and map APIC base address */ + Status = XtpInitializeApicBase(&MemoryMappings); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to setup kernel initialization block */ + XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: %lx)\n", Status); + return Status; + } + + /* Get kernel entry point */ + XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint); + + /* Close boot directory handle */ + BootDir->Close(BootDir); + + /* Enable paging */ + XtLdrProtocol->Protocol.Open((PVOID*)&ImageProtocol, &LoadedImageGuid); + Status = XtEnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to enable paging */ + XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: %lx)\n", Status); + return Status; + } + + /* Call XTOS kernel */ + XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n"); + KernelEntryPoint(KernelParameters); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Checks if APIC is present in the system and finds its base address. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @return This routine returns an EFI status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings) +{ + PCPUID_REGISTERS CpuRegisters = NULL; + PVOID ApicBaseAddress; + + /* Get CPU features list */ + CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; + CpuRegisters->SubLeaf = 0; + CpuRegisters->Eax = 0; + CpuRegisters->Ebx = 0; + CpuRegisters->Ecx = 0; + CpuRegisters->Edx = 0; + ArCpuId(CpuRegisters); + + /* Check if APIC is present */ + if((CpuRegisters->Edx & CPUID_FEATURES_EDX_APIC) == 0) + { + /* APIC is not supported by the CPU */ + return STATUS_EFI_UNSUPPORTED; + } + + /* Get APIC base address */ + ApicBaseAddress = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000); + + /* Map APIC base address */ + XtAddVirtualMemoryMapping(MemoryMappings, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent); + return STATUS_EFI_SUCCESS; +} + +/** + * Initializes and maps the kernel initialization block. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + IN PXTBL_BOOT_PARAMETERS Parameters) +{ + EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID; + PXT_FRAMEBUFFER_PROTOCOL FrameBufProtocol; + PKERNEL_INITIALIZATION_BLOCK LoaderBlock; + EFI_PHYSICAL_ADDRESS Address; + // PVOID RuntimeServices; + EFI_STATUS Status; + UINT BlockPages, FrameBufferPages; + + /* Calculate number of pages needed for initialization block */ + BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); + + /* Allocate memory for kernel initialization block */ + Status = XtLdrProtocol->Memory.AllocatePages(BlockPages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Initialize and zero-fill kernel initialization block */ + LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; + RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK)); + + /* Set basic loader block properties */ + LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK); + LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION; + LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION; + + /* Set LoaderInformation block properties */ + LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; + + /* Load FrameBuffer protocol */ + Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufProtocol, &FrameBufGuid); + if(Status == STATUS_EFI_SUCCESS) + { + /* Make sure FrameBuffer is initialized */ + FrameBufProtocol->Initialize(); + FrameBufProtocol->PrintDisplayInformation(); + + /* Store information about FrameBuffer device */ + FrameBufProtocol->GetDisplayInformation(&LoaderBlock->LoaderInformation.FrameBuffer); + } + else + { + /* No FrameBuffer available */ + LoaderBlock->LoaderInformation.FrameBuffer.Initialized = FALSE; + LoaderBlock->LoaderInformation.FrameBuffer.Protocol = NONE; + } + + /* Attempt to find virtual address of the EFI Runtime Services */ + // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); + // if(Status == STATUS_EFI_SUCCESS) + // { + /* Set FirmwareInformation block properties */ + LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = 0; //EfiSystemTable->Hdr.Revision; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULL; + // } + // else + // { + // /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */ + // LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid; + // } + + /* Copy parameters to kernel initialization block */ + RtlCopyMemory(&LoaderBlock->KernelParameters, Parameters->Parameters, RtlWideStringLength(Parameters->Parameters, 0)); + + /* Map kernel initialization block */ + XtAddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock, + BlockPages, LoaderSystemBlock); + + /* Calculate next valid virtual address */ + *VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); + + /* Check if framebuffer initialized */ + if(LoaderBlock->LoaderInformation.FrameBuffer.Initialized) + { + /* Calculate pages needed to map framebuffer */ + FrameBufferPages = EFI_SIZE_TO_PAGES(LoaderBlock->LoaderInformation.FrameBuffer.BufferSize); + + /* Map frame buffer memory */ + XtAddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, + LoaderBlock->LoaderInformation.FrameBuffer.Address, + FrameBufferPages, LoaderFirmwarePermanent); + + /* Rewrite framebuffer address by using virtual address */ + LoaderBlock->LoaderInformation.FrameBuffer.Address = *VirtualAddress; + + /* Calcualate next valid virtual address */ + *VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE); + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Loads XTOS PE/COFF module. + * + * @param SystemDir + * An EFI handle to the opened system directory containing a module that will be loaded. + * + * @param FileName + * An on disk filename of the module that will be loaded. + * + * @param VirtualAddress + * Optional virtual address pointing to the memory area where PE/COFF file will be loaded. + * + * @param MemoryType + * Supplies the type of memory to be assigned to the memory descriptor. + * + * @param ImageContext + * Supplies pointer to the memory area where loaded PE/COFF image context will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, + IN PWCHAR FileName, + IN PVOID VirtualAddress, + IN LOADER_MEMORY_TYPE MemoryType, + OUT PPECOFF_IMAGE_CONTEXT *ImageContext) +{ + PEFI_FILE_HANDLE ModuleHandle; + USHORT MachineType, SubSystem; + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->Debug.Print(L"Loading %S ... \n", FileName); + + /* Open module file */ + Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to open the file */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to open '%S'\n", FileName); + return Status; + } + + /* Load the PE/COFF image file */ + Status = XtPeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID)ImageContext); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to load the file */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to load '%S'\n", FileName); + return Status; + } + + /* Close image file */ + ModuleHandle->Close(ModuleHandle); + + /* Check PE/COFF image machine type compatibility */ + XtPeCoffProtocol->GetMachineType(*ImageContext, &MachineType); + if(MachineType != _ARCH_IMAGE_MACHINE_TYPE) + { + /* Machine type mismatch */ + XtLdrProtocol->Debug.Print(L"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\n"); + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Check PE/COFF image subsystem */ + XtPeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem); + if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL && + SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION && + SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER) + { + XtLdrProtocol->Debug.Print(L"WARNING: Loaded PE/COFF image with non-XT subsystem set\n"); + } + + /* Print debug message */ + XtLdrProtocol->Debug.Print(L"Loaded %S at PA: 0x%lx, VA: 0x%lx\n", FileName, + (*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID; + EFI_STATUS Status; + + // /* Set the system table and image handle */ + // EfiImageHandle = ImageHandle; + // EfiSystemTable = SystemTable; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open loader protocol */ + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Set routines available via XTOS boot protocol */ + XtBootProtocol.BootSystem = XtBootSystem; + + /* Register XTOS boot protocol */ + return XtLdrProtocol->Protocol.Register(&Guid, &XtBootProtocol); +} -- 2.45.1 From 8ccf37a1c1b1867a3f10af1747a1f0ca86c5c7ac Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 3 Jan 2024 15:51:26 +0100 Subject: [PATCH 141/182] Increase buffer size --- xtldr2/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 3fdb77b..25e56e8 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -147,7 +147,7 @@ BlLoadModule(IN PWCHAR ModuleName) PXTBL_MODULE_DEPS ModuleDependencies; PXTBL_MODULE_INFO ModuleInfo; PLIST_ENTRY ModuleListEntry; - WCHAR ModuleFileName[12]; + WCHAR ModuleFileName[24]; USHORT SectionIndex; SIZE_T ModuleSize; EFI_STATUS Status; -- 2.45.1 From b79e650f5ffff6351ff1297a66e77479bd828762 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 3 Jan 2024 15:57:10 +0100 Subject: [PATCH 142/182] Remove empty line --- xtldr2/xtldr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index d03eb5f..85e7902 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,7 +9,6 @@ #include - /** * Initializes EFI Boot Loader (XTLDR). * -- 2.45.1 From dae5900bc71958eb1a1b87dd90b709e8d860e135 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 3 Jan 2024 15:58:04 +0100 Subject: [PATCH 143/182] Remove test debug message --- xtldr2/modules/fb_o/framebuf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xtldr2/modules/fb_o/framebuf.c b/xtldr2/modules/fb_o/framebuf.c index cd8db2e..bbff477 100644 --- a/xtldr2/modules/fb_o/framebuf.c +++ b/xtldr2/modules/fb_o/framebuf.c @@ -189,7 +189,7 @@ XTCDECL VOID FbPrintDisplayInformation() { - PWCHAR DriverName; + PWCHAR DriverName = NULL; /* Make sure frame buffer is initialized */ if(!FrameBufferInfo.Initialized) @@ -203,7 +203,6 @@ FbPrintDisplayInformation() FbGetDisplayDriver(DriverName); /* Print video information */ - XtLdrProtocol->Debug.Print(L"TEST: %S\n", DriverName); XtLdrProtocol->Debug.Print(L"XTLDR Framebuffer information:\n" L" FrameBuffer Address: 0x%lx\n" L" FrameBuffer Size: %lu\n" -- 2.45.1 From 927d256038d5c093e1d1a885a0e27d1c45bbf941 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 3 Jan 2024 15:58:55 +0100 Subject: [PATCH 144/182] Register 'XTOS' boot protocol support --- xtldr2/modules/xtos_o/xtos.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xtldr2/modules/xtos_o/xtos.c b/xtldr2/modules/xtos_o/xtos.c index b8aec1f..a1e56d1 100644 --- a/xtldr2/modules/xtos_o/xtos.c +++ b/xtldr2/modules/xtos_o/xtos.c @@ -544,5 +544,8 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtBootProtocol.BootSystem = XtBootSystem; /* Register XTOS boot protocol */ + XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid); + + /* Install XTOS protocol */ return XtLdrProtocol->Protocol.Register(&Guid, &XtBootProtocol); } -- 2.45.1 From 17049d7e829f562fbc9f5c1d1015201585754d1f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 3 Jan 2024 23:15:37 +0100 Subject: [PATCH 145/182] Move BlGetXtLdrProtocol() routine into separate file to avoid linking modules with whole libxtldr.lib statically --- xtldr2/CMakeLists.txt | 1 + xtldr2/modproto.c | 80 +++++++++++++++++++++++++++++++++++++++++++ xtldr2/protocol.c | 70 ------------------------------------- 3 files changed, 81 insertions(+), 70 deletions(-) create mode 100644 xtldr2/modproto.c diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index d9f2946..61ab57e 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.c + ${XTLDR_SOURCE_DIR}/modproto.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/shell.c ${XTLDR_SOURCE_DIR}/string.c diff --git a/xtldr2/modproto.c b/xtldr2/modproto.c new file mode 100644 index 0000000..a5b8a97 --- /dev/null +++ b/xtldr2/modproto.c @@ -0,0 +1,80 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modproto.c + * DESCRIPTION: XT Boot Loader protocol support for XTLDR modules + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Finds and opens the XT Boot Loader protocol. This routine should be called by module to access XTLDR protocol. + * + * @param SystemTable + * Provides the EFI system table. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param ProtocolHandler + * Receives the pointer to the XT Boot Loader protocol. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, + IN EFI_HANDLE ImageHandle, + OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler) +{ + EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + PEFI_HANDLE Handles = NULL; + EFI_STATUS Status; + UINT_PTR Count; + UINT Index; + + /* Try to locate the handles */ + Status = SystemTable->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 = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid, + (PVOID*)ProtocolHandler, ImageHandle, 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 */ + SystemTable->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; +} diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 25e56e8..6f74c76 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -52,76 +52,6 @@ BlFindBootProtocol(IN PWCHAR SystemType, return STATUS_EFI_NOT_FOUND; } -/** - * Finds and opens the XT Boot Loader protocol. This routine should be called by module to access XTLDR protocol. - * - * @param SystemTable - * Provides the EFI system table. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param ProtocolHandler - * Receives the pointer to the XT Boot Loader protocol. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, - IN EFI_HANDLE ImageHandle, - OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler) -{ - EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID; - PEFI_HANDLE Handles = NULL; - EFI_STATUS Status; - UINT_PTR Count; - UINT Index; - - /* Try to locate the handles */ - Status = SystemTable->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 = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid, - (PVOID*)ProtocolHandler, ImageHandle, 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 */ - SystemTable->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; -} - /** * Loads a specified XTLDR module from disk. * -- 2.45.1 From 2734245d0636c8f1e5b6085dba0915c05720e55a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 15:47:25 +0100 Subject: [PATCH 146/182] Store additional information about module, for further processing --- sdk/xtdk/bltypes.h | 4 ++++ xtldr2/protocol.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 0d84500..657b561 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -163,6 +163,10 @@ typedef struct _XTBL_MODULE_INFO PWCHAR ModuleName; PWCHAR ModuleDescription; LIST_ENTRY Dependencies; + PVOID ModuleBase; + UINT64 ModuleSize; + UINT32 Revision; + PEFI_IMAGE_UNLOAD UnloadModule; } XTBL_MODULE_INFO, *PXTBL_MODULE_INFO; /* XTLDR Status data */ diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 6f74c76..6878005 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -257,6 +257,12 @@ BlLoadModule(IN PWCHAR ModuleName) EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); } + /* Save module information */ + ModuleInfo->ModuleBase = LoadedImage->ImageBase; + ModuleInfo->ModuleSize = LoadedImage->ImageSize; + ModuleInfo->Revision = LoadedImage->Revision; + ModuleInfo->UnloadModule = LoadedImage->Unload; + /* Close loaded image protocol */ EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); -- 2.45.1 From f99b3c1136c296aa1104020375626077172d9fae Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 15:55:43 +0100 Subject: [PATCH 147/182] Separate library from boot loader --- xtldr2/CMakeLists.txt | 7 +++++-- xtldr2/{ => library}/modproto.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) rename xtldr2/{ => library}/modproto.c (98%) diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt index 61ab57e..275b9ff 100644 --- a/xtldr2/CMakeLists.txt +++ b/xtldr2/CMakeLists.txt @@ -9,6 +9,10 @@ include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk ${XTLDR_SOURCE_DIR}/includes) +# Specify list of library source code files +list(APPEND LIBXTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/library/modproto.c) + # Specify list of source code files list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/config.c @@ -18,7 +22,6 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.c - ${XTLDR_SOURCE_DIR}/modproto.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/shell.c ${XTLDR_SOURCE_DIR}/string.c @@ -27,7 +30,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/xtldr.c) # Link static XTLDR library -add_library(libxtldr ${XTLDR_SOURCE}) +add_library(libxtldr ${LIBXTLDR_SOURCE}) # Link bootloader executable add_executable(xtldr ${XTLDR_SOURCE}) diff --git a/xtldr2/modproto.c b/xtldr2/library/modproto.c similarity index 98% rename from xtldr2/modproto.c rename to xtldr2/library/modproto.c index a5b8a97..7bf441d 100644 --- a/xtldr2/modproto.c +++ b/xtldr2/library/modproto.c @@ -1,7 +1,7 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modproto.c + * FILE: xtldr/library/modproto.c * DESCRIPTION: XT Boot Loader protocol support for XTLDR modules * DEVELOPERS: Rafal Kupiec */ -- 2.45.1 From ed8b93beb0cf003c2eefeb509585479c8ca99bc3 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 16:25:13 +0100 Subject: [PATCH 148/182] Cleanup xtos_o module --- xtldr2/modules/xtos_o/xtos.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/xtldr2/modules/xtos_o/xtos.c b/xtldr2/modules/xtos_o/xtos.c index a1e56d1..5670c6c 100644 --- a/xtldr2/modules/xtos_o/xtos.c +++ b/xtldr2/modules/xtos_o/xtos.c @@ -528,10 +528,6 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID; EFI_STATUS Status; - // /* Set the system table and image handle */ - // EfiImageHandle = ImageHandle; - // EfiSystemTable = SystemTable; - /* Open the XTLDR protocol */ Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); if(Status != STATUS_EFI_SUCCESS) -- 2.45.1 From d7abe40e5d5ca46e9afd792251c437669ffb3495 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 22:42:27 +0100 Subject: [PATCH 149/182] Add temporary solution for mapping modules code --- sdk/xtdk/bltypes.h | 2 ++ xtldr2/includes/xtldr.h | 4 ++++ xtldr2/protocol.c | 20 +++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 657b561..be432d2 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -74,6 +74,7 @@ typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID 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_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); +typedef PLIST_ENTRY (*PBL_GET_MODULES_LIST)(); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); @@ -244,6 +245,7 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { + PBL_GET_MODULES_LIST GetModulesList; PBL_OPEN_XT_PROTOCOL Open; PBL_REGISTER_XT_PROTOCOL Register; } Protocol; diff --git a/xtldr2/includes/xtldr.h b/xtldr2/includes/xtldr.h index bebc8ca..b7aaaf3 100644 --- a/xtldr2/includes/xtldr.h +++ b/xtldr2/includes/xtldr.h @@ -106,6 +106,10 @@ XTCDECL EFI_STATUS BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); +XTCDECL +PLIST_ENTRY +BlGetModulesList(); + XTCDECL INT_PTR BlGetSecureBootStatus(); diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 6878005..98ededc 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -52,6 +52,23 @@ BlFindBootProtocol(IN PWCHAR SystemType, return STATUS_EFI_NOT_FOUND; } +/** + * Returns a linked list of all loaded modules. + * + * @return This routine returns a pointer to a linked list of all loaded modules. + * + * @since XT 1.0 + * + * @todo This is a temporary solution and it should be replaced by a complex API allowing to map modules. + */ +XTCDECL +PLIST_ENTRY +BlGetModulesList() +{ + /* Return a pointer to a list of all loaded modules */ + return &BlpLoadedModules; +} + /** * Loads a specified XTLDR module from disk. * @@ -404,7 +421,7 @@ BlOpenProtocol(OUT PVOID *ProtocolHandler, */ XTCDECL VOID -BlRegisterBootMenu(PVOID BootMenuRoutine) +BlRegisterBootMenu(IN PVOID BootMenuRoutine) { /* Set boot menu routine */ BlpStatus.BootMenu = BootMenuRoutine; @@ -529,6 +546,7 @@ BlpRegisterXtLoaderProtocol() BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages; BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool; BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; + BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; BlpLdrProtocol.Protocol.Open = BlOpenProtocol; BlpLdrProtocol.Protocol.Register = BlRegisterProtocol; BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; -- 2.45.1 From 297ac1acf6a711434768a463f9d54ce00f6f6184 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 22:45:12 +0100 Subject: [PATCH 150/182] Map XTLDR modules code to prevent PF exception after enabling paging --- xtldr2/modules/xtos_o/amd64/memory.c | 25 ++++++++++++++++++++++++- xtldr2/modules/xtos_o/i686/memory.c | 25 ++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/xtldr2/modules/xtos_o/amd64/memory.c b/xtldr2/modules/xtos_o/amd64/memory.c index 3a21055..cc7a16b 100644 --- a/xtldr2/modules/xtos_o/amd64/memory.c +++ b/xtldr2/modules/xtos_o/amd64/memory.c @@ -38,7 +38,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, PLOADER_MEMORY_MAPPING Mapping; EFI_PHYSICAL_ADDRESS Address; PEFI_MEMORY_MAP MemoryMap; - PLIST_ENTRY ListEntry; + PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; + PXTBL_MODULE_INFO ModuleInfo; EFI_STATUS Status; /* Allocate pages for PML4 */ @@ -53,6 +54,28 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, *PtePointer = (PVOID)(UINT_PTR)Address; RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE); + /* Get list of XTLDR modules */ + ModulesList = XtLdrProtocol->Protocol.GetModulesList(); + ModulesListEntry = ModulesList->Flink; + while(ModulesListEntry != ModulesList) + { + /* Get module info */ + ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); + + /* Map module code */ + XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping module code failed */ + return Status; + } + + /* Get next module */ + ModulesListEntry = ModulesListEntry->Flink; + } + /* Map XTLDR code */ Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); diff --git a/xtldr2/modules/xtos_o/i686/memory.c b/xtldr2/modules/xtos_o/i686/memory.c index f0d1354..141fe42 100644 --- a/xtldr2/modules/xtos_o/i686/memory.c +++ b/xtldr2/modules/xtos_o/i686/memory.c @@ -41,7 +41,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, PEFI_MEMORY_DESCRIPTOR Descriptor; PLOADER_MEMORY_MAPPING Mapping; PEFI_MEMORY_MAP MemoryMap; - PLIST_ENTRY ListEntry; + PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; + PXTBL_MODULE_INFO ModuleInfo; EFI_STATUS Status; UINT Index; @@ -151,6 +152,28 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, Address += EFI_PAGE_SIZE; } + /* Get list of XTLDR modules */ + ModulesList = XtLdrProtocol->Protocol.GetModulesList(); + ModulesListEntry = ModulesList->Flink; + while(ModulesListEntry != ModulesList) + { + /* Get module info */ + ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); + + /* Map module code */ + XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping module code failed */ + return Status; + } + + /* Get next module */ + ModulesListEntry = ModulesListEntry->Flink; + } + /* Map XTLDR code */ Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); -- 2.45.1 From 2f8820a021454667d1f25e0b38567eb239c8a69d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 22:47:40 +0100 Subject: [PATCH 151/182] Replace obsolete bootloader code, since new one can already start XTOS kernel --- CMakeLists.txt | 2 +- xtldr/CMakeLists.txt | 23 +- xtldr/README.md | 2 +- xtldr/amd64/memory.c | 310 ----- xtldr/blproto.c | 96 -- {xtldr2 => xtldr}/config.c | 0 xtldr/console.c | 260 ++++- {xtldr2 => xtldr}/debug.c | 0 xtldr/efiutil.c | 364 ------ {xtldr2 => xtldr}/efiutils.c | 0 xtldr/globals.c | 38 +- {xtldr2 => xtldr}/hardware.c | 0 xtldr/i686/memory.c | 334 ------ xtldr/includes/bldefs.h | 22 - xtldr/includes/blmod.h | 94 -- xtldr/includes/blproto.h | 62 - {xtldr2 => xtldr}/includes/globals.h | 0 xtldr/includes/xtbl.h | 264 ----- {xtldr2 => xtldr}/includes/xtldr.h | 0 {xtldr2 => xtldr}/library/modproto.c | 0 xtldr/memory.c | 495 +------- xtldr/modules/CMakeLists.txt | 7 +- .../modules/dummy/CMakeLists.txt | 0 {xtldr2 => xtldr}/modules/dummy/dummy.c | 0 {xtldr2 => xtldr}/modules/dummy/globals.c | 0 .../modules/dummy/includes/globals.h | 0 {xtldr2 => xtldr}/modules/fb_o/CMakeLists.txt | 0 {xtldr2 => xtldr}/modules/fb_o/framebuf.c | 0 {xtldr2 => xtldr}/modules/fb_o/gop.c | 0 .../modules/fb_o/includes/framebuf.h | 0 xtldr/modules/framebuf/CMakeLists.txt | 28 - xtldr/modules/framebuf/framebuf.c | 277 ----- xtldr/modules/framebuf/gop.c | 51 - xtldr/modules/framebuf/includes/framebuf.h | 44 - xtldr/modules/pecoff/CMakeLists.txt | 27 - xtldr/modules/pecoff/includes/pecoff.h | 58 - xtldr/modules/pecoff/pecoff.c | 608 ---------- .../modules/pecoff_o/CMakeLists.txt | 0 .../modules/pecoff_o/includes/pecoff.h | 0 {xtldr2 => xtldr}/modules/pecoff_o/pecoff.c | 0 xtldr/modules/xtos/CMakeLists.txt | 27 - xtldr/modules/xtos/includes/xtos.h | 54 - xtldr/modules/xtos/xtos.c | 548 --------- .../modules/xtos_o/CMakeLists.txt | 0 .../modules/xtos_o/amd64/memory.c | 0 .../modules/xtos_o/i686/memory.c | 0 .../modules/xtos_o/includes/xtos.h | 0 {xtldr2 => xtldr}/modules/xtos_o/memory.c | 0 {xtldr2 => xtldr}/modules/xtos_o/xtos.c | 0 {xtldr2 => xtldr}/protocol.c | 0 {xtldr2 => xtldr}/shell.c | 0 xtldr/string.c | 190 ++- xtldr/system.c | 77 -- {xtldr2 => xtldr}/textui.c | 0 xtldr/volume.c | 239 +++- xtldr/xtldr.c | 614 +++++----- xtldr2/CMakeLists.txt | 54 - xtldr2/README.md | 14 - xtldr2/console.c | 297 ----- xtldr2/globals.c | 43 - xtldr2/memory.c | 155 --- xtldr2/modules/CMakeLists.txt | 4 - xtldr2/string.c | 444 ------- xtldr2/volume.c | 1019 ----------------- xtldr2/xtldr.c | 433 ------- 65 files changed, 927 insertions(+), 6751 deletions(-) delete mode 100644 xtldr/amd64/memory.c delete mode 100644 xtldr/blproto.c rename {xtldr2 => xtldr}/config.c (100%) rename {xtldr2 => xtldr}/debug.c (100%) delete mode 100644 xtldr/efiutil.c rename {xtldr2 => xtldr}/efiutils.c (100%) rename {xtldr2 => xtldr}/hardware.c (100%) delete mode 100644 xtldr/i686/memory.c delete mode 100644 xtldr/includes/bldefs.h delete mode 100644 xtldr/includes/blmod.h delete mode 100644 xtldr/includes/blproto.h rename {xtldr2 => xtldr}/includes/globals.h (100%) delete mode 100644 xtldr/includes/xtbl.h rename {xtldr2 => xtldr}/includes/xtldr.h (100%) rename {xtldr2 => xtldr}/library/modproto.c (100%) rename {xtldr2 => xtldr}/modules/dummy/CMakeLists.txt (100%) rename {xtldr2 => xtldr}/modules/dummy/dummy.c (100%) rename {xtldr2 => xtldr}/modules/dummy/globals.c (100%) rename {xtldr2 => xtldr}/modules/dummy/includes/globals.h (100%) rename {xtldr2 => xtldr}/modules/fb_o/CMakeLists.txt (100%) rename {xtldr2 => xtldr}/modules/fb_o/framebuf.c (100%) rename {xtldr2 => xtldr}/modules/fb_o/gop.c (100%) rename {xtldr2 => xtldr}/modules/fb_o/includes/framebuf.h (100%) delete mode 100644 xtldr/modules/framebuf/CMakeLists.txt delete mode 100644 xtldr/modules/framebuf/framebuf.c delete mode 100644 xtldr/modules/framebuf/gop.c delete mode 100644 xtldr/modules/framebuf/includes/framebuf.h delete mode 100644 xtldr/modules/pecoff/CMakeLists.txt delete mode 100644 xtldr/modules/pecoff/includes/pecoff.h delete mode 100644 xtldr/modules/pecoff/pecoff.c rename {xtldr2 => xtldr}/modules/pecoff_o/CMakeLists.txt (100%) rename {xtldr2 => xtldr}/modules/pecoff_o/includes/pecoff.h (100%) rename {xtldr2 => xtldr}/modules/pecoff_o/pecoff.c (100%) delete mode 100644 xtldr/modules/xtos/CMakeLists.txt delete mode 100644 xtldr/modules/xtos/includes/xtos.h delete mode 100644 xtldr/modules/xtos/xtos.c rename {xtldr2 => xtldr}/modules/xtos_o/CMakeLists.txt (100%) rename {xtldr2 => xtldr}/modules/xtos_o/amd64/memory.c (100%) rename {xtldr2 => xtldr}/modules/xtos_o/i686/memory.c (100%) rename {xtldr2 => xtldr}/modules/xtos_o/includes/xtos.h (100%) rename {xtldr2 => xtldr}/modules/xtos_o/memory.c (100%) rename {xtldr2 => xtldr}/modules/xtos_o/xtos.c (100%) rename {xtldr2 => xtldr}/protocol.c (100%) rename {xtldr2 => xtldr}/shell.c (100%) delete mode 100644 xtldr/system.c rename {xtldr2 => xtldr}/textui.c (100%) delete mode 100644 xtldr2/CMakeLists.txt delete mode 100644 xtldr2/README.md delete mode 100644 xtldr2/console.c delete mode 100644 xtldr2/globals.c delete mode 100644 xtldr2/memory.c delete mode 100644 xtldr2/modules/CMakeLists.txt delete mode 100644 xtldr2/string.c delete mode 100644 xtldr2/volume.c delete mode 100644 xtldr2/xtldr.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b9bf79e..bc2200c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,5 +70,5 @@ set_disk_image_size(128) # Build all subprojects add_subdirectory(bootdata) -add_subdirectory(xtldr2) +add_subdirectory(xtldr) add_subdirectory(xtoskrnl) diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index 17184ba..275b9ff 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -1,4 +1,4 @@ -# XT Boot Loader +# XT Boot Manager PROJECT(XTLDR) # Build XTLDR modules @@ -9,19 +9,29 @@ include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk ${XTLDR_SOURCE_DIR}/includes) +# Specify list of library source code files +list(APPEND LIBXTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/library/modproto.c) + # Specify list of source code files list(APPEND XTLDR_SOURCE - ${XTLDR_SOURCE_DIR}/${ARCH}/memory.c - ${XTLDR_SOURCE_DIR}/blproto.c + ${XTLDR_SOURCE_DIR}/config.c ${XTLDR_SOURCE_DIR}/console.c - ${XTLDR_SOURCE_DIR}/efiutil.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}/shell.c ${XTLDR_SOURCE_DIR}/string.c - ${XTLDR_SOURCE_DIR}/system.c + ${XTLDR_SOURCE_DIR}/textui.c ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) +# Link static XTLDR library +add_library(libxtldr ${LIBXTLDR_SOURCE}) + # Link bootloader executable add_executable(xtldr ${XTLDR_SOURCE}) @@ -38,6 +48,7 @@ set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi) set_install_target(xtldr efi/boot) # Set loader entrypoint and subsystem -set_imagebase(xtldr ${BASEADDRESS_XTLDR}) set_entrypoint(xtldr "BlStartXtLoader") +set_imagebase(xtldr ${BASEADDRESS_XTLDR}) +set_linker_map(xtldr TRUE) set_subsystem(xtldr efi_application) diff --git a/xtldr/README.md b/xtldr/README.md index 3d0b51b..ae4fe9f 100644 --- a/xtldr/README.md +++ b/xtldr/README.md @@ -1,4 +1,4 @@ -## XT Loader (XTLDR) +## XT Boot Manager (XTLDR) The XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS. As an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems, like old and deprecated BIOS. diff --git a/xtldr/amd64/memory.c b/xtldr/amd64/memory.c deleted file mode 100644 index ee29723..0000000 --- a/xtldr/amd64/memory.c +++ /dev/null @@ -1,310 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/amd64/memory.c - * DESCRIPTION: EFI memory management for AMD64 target - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @param VirtualAddress - * Supplies a pointer to the next valid, free and available virtual address. - * - * @param ImageProtocol - * A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed. - * - * @param PtePointer - * Supplies a pointer to memory area containing a Page Table Entries (PTE). - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEnablePaging(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, - IN PVOID *PtePointer) -{ - PLOADER_MEMORY_MAPPING Mapping; - EFI_PHYSICAL_ADDRESS Address; - PEFI_MEMORY_MAP MemoryMap; - PLIST_ENTRY ListEntry; - EFI_STATUS Status; - - /* Allocate pages for PML4 */ - Status = BlEfiMemoryAllocatePages(1, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Assign and zero-fill memory used by page mappings */ - *PtePointer = (PVOID)(UINT_PTR)Address; - RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE); - - /* Map XTLDR code */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, - EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping the boot loader code failed */ - return Status; - } - - /* Add page mapping itself to memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping PML4 failed */ - return Status; - } - - /* Iterate through and map all the mappings*/ - BlDbgPrint(L"Mapping and dumping EFI memory:\n"); - ListEntry = MemoryMappings->Flink; - while(ListEntry != MemoryMappings) - { - /* Take mapping from the list */ - Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); - - /* Check if virtual address is set */ - if(Mapping->VirtualAddress) - { - /* Dump memory mapping */ - BlDbgPrint(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType, - Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); - - /* Map memory */ - Status = BlMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failed */ - return Status; - } - } - - /* Take next element */ - ListEntry = ListEntry->Flink; - } - - /* Map zero page as well */ - BlMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer); - - /* Allocate and zero-fill buffer for EFI memory map */ - BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); - - /* Get EFI memory map and prepare for exiting boot services */ - BlDbgPrint(L"Exiting EFI boot services\n"); - Status = BlGetMemoryMap(MemoryMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get memory map */ - return Status; - } - - /* Exit EFI Boot Services */ - Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); - if(Status != STATUS_EFI_SUCCESS) - { - /* Retry as UEFI spec says to do it twice */ - Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); - } - - /* Check if exitted boot services successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to exit boot services */ - BlDbgPrint(L"Failed to exit boot services (Status code: %lx)\n", Status); - return STATUS_EFI_ABORTED; - } - - /* Write PML4 to CR3 */ - ArWriteControlRegister(3, (UINT_PTR)*PtePointer); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine does the actual virtual memory mapping. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @param VirtualAddress - * Supplies a virtual address of the mapping. - * - * @param PhysicalAddress - * Supplies a physical address of the mapping. - * - * @param NumberOfPages - * Supplies a number of the pages of the mapping. - * - * @param PaeExtension - * Specifies whether Physical Address Extension (PAE) is supported by the hardware. Not used on AMD64. - * - * @param PtePointer - * Supplies a pointer to an array of pointers to page table entries. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, - IN UINT_PTR VirtualAddress, - IN UINT_PTR PhysicalAddress, - IN UINT NumberOfPages, - IN OUT PVOID *PtePointer) -{ - PHARDWARE_PTE PageDirectoryPointTable, PageDirectory, PageTable; - UINT Pml4Index, PdpIndex, PdIndex, PtIndex; - EFI_PHYSICAL_ADDRESS Address; - UINT_PTR PageFrameNumber; - EFI_STATUS Status; - UINT64 Pointer; - - /* Set the PFN */ - PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; - - /* Do the recursive mapping */ - while(NumberOfPages > 0) - { - /* Calculate indices from a virtual address */ - Pml4Index = (VirtualAddress >> 39) & 0x1FF; - PdpIndex = (VirtualAddress >> 30) & 0x1FF; - PdIndex = (VirtualAddress >> 21) & 0x1FF; - PtIndex = (VirtualAddress >> 12) & 0x1FF; - - /* Validate Page Map Level 4 (PML4) */ - if(!((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid) - { - /* Allocate pages for the PDPT */ - Status = BlEfiMemoryAllocatePages(1, &Address); - if (Status != STATUS_EFI_SUCCESS) { - /* Memory allocation failure */ - return Status; - } - - /* Add new memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); - if(Status != STATUS_EFI_SUCCESS) { - /* Memory mapping failed */ - return Status; - } - - /* Fill allocated memory with zeros */ - RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); - - /* Set paging entry settings */ - ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber = Address / EFI_PAGE_SIZE; - ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid = 1; - ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Write = 1; - PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Address; - } - else - { - /* Find Page Directory Point Table (PDPT) */ - Pointer = ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber; - Pointer <<= EFI_PAGE_SHIFT; - PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; - } - - /* Validate Page Directory Point Table (PDPT)*/ - if(!PageDirectoryPointTable[PdpIndex].Valid) - { - /* Allocate pages for the PD */ - Status = BlEfiMemoryAllocatePages(1, &Address); - if (Status != STATUS_EFI_SUCCESS) { - /* Memory allocation failure */ - return Status; - } - - /* Add new memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); - if (Status != STATUS_EFI_SUCCESS) { - /* Memory mapping failed */ - return Status; - } - - /* Fill allocated memory with zeros */ - RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); - - /* Set paging entry settings */ - PageDirectoryPointTable[PdpIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; - PageDirectoryPointTable[PdpIndex].Valid = 1; - PageDirectoryPointTable[PdpIndex].Write = 1; - PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Address; - } - else - { - /* Find Page Directory (PD) */ - Pointer = PageDirectoryPointTable[PdpIndex].PageFrameNumber; - Pointer <<= EFI_PAGE_SHIFT; - PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Pointer; - } - - /* Validate Page Directory (PD)*/ - if(!PageDirectory[PdIndex].Valid) - { - /* Allocate pages for the PT */ - Status = BlEfiMemoryAllocatePages(1, &Address); - if (Status != STATUS_EFI_SUCCESS) { - /* Memory allocation failure */ - return Status; - } - - /* Add new memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); - if (Status != STATUS_EFI_SUCCESS) { - /* Memory mapping failed */ - return Status; - } - - /* Fill allocated memory with zeros */ - RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); - - /* Set paging entry settings */ - PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; - PageDirectory[PdIndex].Valid = 1; - PageDirectory[PdIndex].Write = 1; - PageTable = (PHARDWARE_PTE)(UINT_PTR)Address; - } - else - { - /* Find Page Table (PT) */ - Pointer = PageDirectory[PdIndex].PageFrameNumber; - Pointer <<= EFI_PAGE_SHIFT; - PageTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; - } - - /* Set paging entry settings */ - PageTable[PtIndex].PageFrameNumber = PageFrameNumber; - PageTable[PtIndex].Valid = 1; - PageTable[PtIndex].Write = 1; - - /* Take next virtual address and PFN */ - VirtualAddress += EFI_PAGE_SIZE; - PageFrameNumber++; - - /* Decrease number of pages left */ - NumberOfPages--; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} diff --git a/xtldr/blproto.c b/xtldr/blproto.c deleted file mode 100644 index 9d27404..0000000 --- a/xtldr/blproto.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/blproto.c - * DESCRIPTION: EFI XTLDR protocol API - * DEVELOPERS: Rafal Kupiec - */ - -#include -#include - - -/** - * This routine locates and opens the XT boot loader protocol. - * - * @param LdrProtocol - * Supplies the address where a pointer to the loader protocol is returned. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlGetXtLoaderProtocol(OUT PXT_BOOT_LOADER_PROTOCOL *LdrProtocol) -{ - EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; - - /* Load XTLDR protocol */ - return BlLoadXtProtocol((PVOID *)LdrProtocol, &Guid); -} - -/** - * This routine locates and opens the requested XT 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 -BlLoadXtProtocol(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; -} diff --git a/xtldr2/config.c b/xtldr/config.c similarity index 100% rename from xtldr2/config.c rename to xtldr/config.c diff --git a/xtldr/console.c b/xtldr/console.c index 52fc096..e41b8ce 100644 --- a/xtldr/console.c +++ b/xtldr/console.c @@ -6,9 +6,37 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include +/** + * Clears a specified line on the UEFI text console. + * + * @param LineNo + * Supplies a line number to clear. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlClearConsoleLine(IN ULONGLONG LineNo) +{ + UINT_PTR Index, ResX, ResY; + + /* Query console mode */ + BlQueryConsoleMode(&ResX, &ResY); + + /* Set cursor position and clear line */ + BlSetCursorPosition(0, LineNo); + for(Index = 0; Index < ResX; Index++) + { + /* Clear line */ + BlConsoleWrite(L" "); + } +} + /** * This routine clears the UEFI console screen. * @@ -18,34 +46,205 @@ */ XTCDECL VOID -BlConsoleClearScreen() +BlClearConsoleScreen() { + /* Clear screen */ EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); } /** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * + * Disables the cursor on the UEFI console. + * + * @return This routine does not return any value. + * * @since XT 1.0 */ XTCDECL VOID -BlConsoleInitialize() +BlDisableConsoleCursor() { - /* Clear console buffers */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); - EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); - EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); +} - /* Clear screen */ - BlConsoleClearScreen(); - - /* Enable cursor */ +/** + * Enables the cursor on the UEFI console. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlEnableConsoleCursor() +{ EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); } +/** + * This routine formats the input string and prints it out to the stdout and serial console. + * + * @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 +BlConsolePrint(IN PUINT16 Format, + IN ...) +{ + VA_LIST Arguments; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Format and print the string to the stdout */ + BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + + /* Print to serial console only if not running under OVMF */ + if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) + { + /* Check if debugging enabled and if EFI serial port is fully initialized */ + if(DEBUG && (BlpStatus.SerialPort.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); +} + +/** + * Displays the string on the device at the current cursor location. + * + * @param String + * The string to be displayed. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlConsoleWrite(IN PUSHORT String) +{ + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); +} + +/** + * Queries information concerning the output device’s supported text mode. + * + * @param ResX + * Supplies a buffer to receive the horizontal resolution. + * + * @param ResY + * Supplies a buffer to receive the vertical resolution. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlQueryConsoleMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY) +{ + EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); +} + +/** + * Reads a keystroke from the input device. + * + * @param Key + * Supplies a pointer to the EFI_INPUT_KEY structure that will receive the keystroke. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) +{ + EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); +} + +/** + * Resets the console input device and clears its input buffer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlResetConsoleInputBuffer() +{ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); +} + +/** + * Sets the foreground and background colors. + * + * @param Attribute + * Specifies the foreground and background colors (bits 0..3 are fg, and bits 4..6 are bg color). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlSetConsoleAttributes(IN ULONGLONG Attributes) +{ + EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); +} + +/** + * Sets the output console device to the requested mode. + * + * @param Mode + * Supplies a text mode number to set. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlSetConsoleMode(IN ULONGLONG Mode) +{ + return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode); +} + +/** + * Sets new coordinates of the console cursor position. + * + * @param PosX + * Specifies the new X coordinate of the cursor. + * + * @param PosY + * Specifies the new Y coordinate of the cursor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlSetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY) +{ + EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); +} + /** * Writes a character to the default EFI console. * @@ -58,7 +257,7 @@ BlConsoleInitialize() */ XTCDECL VOID -BlConsolePutChar(IN USHORT Character) +BlpConsolePrintChar(IN USHORT Character) { USHORT Buffer[2]; @@ -67,3 +266,32 @@ BlConsolePutChar(IN USHORT Character) Buffer[1] = 0; EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); } + +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlpInitializeConsole() +{ + /* Clear console buffers */ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); + EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); + EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + + /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might + * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ + if(EfiSystemTable->ConOut->Mode->Mode != 0) + { + /* Set console mode to 0, which is standard, 80x25 text mode */ + BlSetConsoleMode(0); + } + + /* Clear screen and enable cursor */ + BlClearConsoleScreen(); + BlEnableConsoleCursor(); +} diff --git a/xtldr2/debug.c b/xtldr/debug.c similarity index 100% rename from xtldr2/debug.c rename to xtldr/debug.c diff --git a/xtldr/efiutil.c b/xtldr/efiutil.c deleted file mode 100644 index 39d01a3..0000000 --- a/xtldr/efiutil.c +++ /dev/null @@ -1,364 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/efiutil.c - * DESCRIPTION: EFI utilities - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Enables I/O space access to all serial controllers found on the PCI(E) root bridge. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlActivateSerialControllerIO() -{ - EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; - PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; - USHORT Bus, Device, Function, Command; - UINT_PTR Index, PciHandleSize; - PEFI_HANDLE PciHandle = NULL; - PCI_COMMON_HEADER PciHeader; - EFI_STATUS Status; - UINT64 Address; - - /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */ - PciHandleSize = sizeof(EFI_HANDLE); - Status = BlEfiMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Get all instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle); - if(Status == STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Reallocate more memory as requested by UEFI */ - BlEfiMemoryFreePool(PciHandle); - Status = BlEfiMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory reallocation failure */ - return Status; - } - - /* Second attempt to get instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle); - } - - /* Make sure successfully obtained PciRootBridgeIo instances */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get PciRootBridgeIo instances */ - return Status; - } - - /* Enumerate all devices for each handle, which decides a segment and a bus number range */ - for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++) - { - /* Get inferface from the protocol */ - Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get interface */ - return Status; - } - - /* Enumerate whole PCI bridge */ - for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++) - { - /* Enumerate all devices for each bus */ - for(Device = 0; Device < PCI_MAX_DEVICES; Device++) - { - /* Enumerate all functions for each devices */ - for(Function = 0; Function < PCI_MAX_FUNCTION; Function++) - { - /* Read configuration space */ - Address = ((UINT64)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) + - (((UINT_PTR) Function) << 8) + ((UINT_PTR) 0))); - PciDev->Pci.Read(PciDev, 2, Address, sizeof (PciHeader) / sizeof (UINT32), &PciHeader); - - /* Check if device exists */ - if(PciHeader.VendorId == PCI_INVALID_VENDORID) - { - /* Skip non-existen device */ - continue; - } - - /* Check if device is serial controller or multiport serial controller */ - if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02)) - { - /* Enable I/O space access */ - Address |= 0x4; - Command = PCI_ENABLE_IO_SPACE; - Status = PciDev->Pci.Write(PciDev, 1, Address, 1, &Command); - } - } - } - } - } - - /* Return SUCCESS */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine initializes the COM port debug console. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlComPortInitialize() -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - ULONG PortAddress, PortNumber, BaudRate; - PWCHAR Argument, CommandLine, LastArg; - EFI_STATUS EfiStatus; - XTSTATUS Status; - - /* Set default serial port options */ - PortAddress = 0; - PortNumber = 0; - BaudRate = 0; - - /* Handle loaded image protocol */ - EfiStatus = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); - if(EfiStatus == STATUS_EFI_SUCCESS) - { - - /* Check if launched from UEFI shell */ - if(LoadedImage && LoadedImage->LoadOptions) - { - /* Store arguments passed from UEFI shell */ - CommandLine = (PWCHAR)LoadedImage->LoadOptions; - - /* Find command in command line */ - Argument = RtlTokenizeWideString(CommandLine, L" ", &LastArg); - - /* Iterate over all arguments passed to boot loader */ - while(Argument != NULL) - { - /* Check if this is DEBUG parameter */ - if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0) - { - /* Skip to the argument value */ - Argument += 6; - - /* Make sure COM port is being used */ - if(RtlCompareWideString(Argument, L"COM", 3)) - { - /* Invalid debug port specified */ - BlEfiPrint(L"ERROR: Invalid debug port specified, falling back to defaults\n"); - break; - } - - /* Read COM port number */ - Argument += 3; - while(*Argument >= '0' && *Argument <= '9') - { - /* Get port number */ - PortNumber *= 10; - PortNumber += *Argument - '0'; - Argument++; - } - - /* Check if custom COM port address supplied */ - if(PortNumber == 0 && RtlCompareWideString(Argument, L":0x", 3) == 0) - { - /* COM port address provided */ - Argument += 3; - while((*Argument >= '0' && *Argument <= '9') || - (*Argument >= 'A' && *Argument <= 'F') || - (*Argument >= 'a' && *Argument <= 'f')) - { - /* Get port address */ - PortAddress *= 16; - if(*Argument >= '0' && *Argument <= '9') - { - PortAddress += *Argument - '0'; - } - else if(*Argument >= 'A' && *Argument <= 'F') - { - PortAddress += *Argument - 'A' + 10; - } - else if(*Argument >= 'a' && *Argument <= 'f') - { - PortAddress += *Argument - 'a' + 10; - } - Argument++; - } - } - - /* Look for additional COM port parameters */ - if(*Argument == ',') - { - /* Baud rate provided */ - Argument++; - while(*Argument >= '0' && *Argument <= '9') - { - /* Get baud rate */ - BaudRate *= 10; - BaudRate += *Argument - '0'; - Argument++; - } - } - - /* No need to check next arguments */ - break; - } - - /* Take next argument */ - Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); - } - } - } - - /* Print debug message depending on port settings */ - if(PortAddress) - { - BlEfiPrint(L"Initializing serial console at COM port address: 0x%lx\n", PortAddress); - } - else - { - BlEfiPrint(L"Initializing serial console at port COM%d\n", PortNumber); - } - - /* Initialize COM port */ - Status = HlInitializeComPort(&EfiSerialPort, 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 = BlActivateSerialControllerIO(); - if(EfiStatus == STATUS_EFI_SUCCESS) - { - /* Try to reinitialize COM port */ - BlEfiPrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); - Status = HlInitializeComPort(&EfiSerialPort, 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 -BlComPortPutChar(IN USHORT Character) -{ - USHORT Buffer[2]; - - /* Write character to the serial console */ - Buffer[0] = Character; - Buffer[1] = 0; - - HlComPortPutByte(&EfiSerialPort, Buffer[0]); -} - -/** - * This routine formats the input string and prints it out to the serial console. - * - * @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 -BlDbgPrint(IN PUINT16 Format, - IN ...) -{ - VA_LIST Arguments; - - /* Check if debugging enabled and if EFI serial port is fully initialized */ - if(DEBUG && (EfiSerialPort.Flags & COMPORT_FLAG_INIT)) - { - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Format and print the string to the serial console */ - BlStringPrint(BlComPortPutChar, Format, Arguments); - - /* Clean up the va_list */ - VA_END(Arguments); - } -} - -/** - * This routine formats the input string and prints it out to the stdout and serial console. - * - * @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 - * - * @todo Check if GOP is active and use it instead of default conout protocol - */ -XTCDECL -VOID -BlEfiPrint(IN PUINT16 Format, - IN ...) -{ - VA_LIST Arguments; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Format and print the string to the stdout */ - BlStringPrint(BlConsolePutChar, Format, Arguments); - - /* Print to serial console only if not running under OVMF */ - if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) - { - /* Check if debugging enabled and if EFI serial port is fully initialized */ - if(DEBUG && (EfiSerialPort.Flags & COMPORT_FLAG_INIT)) - { - /* Format and print the string to the serial console */ - BlStringPrint(BlComPortPutChar, Format, Arguments); - } - } - - /* Clean up the va_list */ - VA_END(Arguments); -} diff --git a/xtldr2/efiutils.c b/xtldr/efiutils.c similarity index 100% rename from xtldr2/efiutils.c rename to xtldr/efiutils.c diff --git a/xtldr/globals.c b/xtldr/globals.c index 04d0740..4a6a286 100644 --- a/xtldr/globals.c +++ b/xtldr/globals.c @@ -6,26 +6,38 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* XT Boot Loader registered boot protocol list */ +LIST_ENTRY BlpBootProtocols; + +/* XT Boot Loader configuration list */ +LIST_ENTRY BlpConfig; + +/* XT Boot Loader loaded configuration */ +LIST_ENTRY BlpConfigSections; + +/* XT Boot Loader hex table */ +STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; + +/* XT Boot Loader protocol */ +XTBL_LOADER_PROTOCOL BlpLdrProtocol; + +/* XT Boot Loader loaded modules list */ +LIST_ENTRY BlpLoadedModules; + +/* XT Boot Loader menu list */ +PLIST_ENTRY BlpMenuList = NULL; + +/* XT Boot Loader status data */ +XTBL_STATUS BlpStatus = {0}; + /* List of available block devices */ LIST_ENTRY EfiBlockDevices; -/* XT Boot Loader hex table */ -STATIC PUINT16 EfiHexTable = L"0123456789ABCDEF"; - /* EFI Image Handle */ EFI_HANDLE EfiImageHandle; -/* XT Boot Loader protocol */ -XT_BOOT_LOADER_PROTOCOL EfiLdrProtocol; - /* EFI System Table */ PEFI_SYSTEM_TABLE EfiSystemTable; - -/* EFI Secure Boot status */ -INT_PTR EfiSecureBoot; - -/* Serial port configuration */ -CPPORT EfiSerialPort; diff --git a/xtldr2/hardware.c b/xtldr/hardware.c similarity index 100% rename from xtldr2/hardware.c rename to xtldr/hardware.c diff --git a/xtldr/i686/memory.c b/xtldr/i686/memory.c deleted file mode 100644 index ae99f4c..0000000 --- a/xtldr/i686/memory.c +++ /dev/null @@ -1,334 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/i686/memory.c - * DESCRIPTION: EFI memory management for i686 target - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @param VirtualAddress - * Supplies a pointer to the next valid, free and available virtual address. - * - * @param ImageProtocol - * A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed. - * - * @param PtePointer - * Supplies a pointer to memory area containing a Page Table Entries (PTE). - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEnablePaging(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, - IN PVOID *PtePointer) -{ - UINT_PTR PhysicalAddress, DescriptorCount; - EFI_PHYSICAL_ADDRESS Address, PDPTAddress = 0; - PCPUID_REGISTERS CpuRegisters = NULL; - PEFI_MEMORY_DESCRIPTOR Descriptor; - PLOADER_MEMORY_MAPPING Mapping; - PEFI_MEMORY_MAP MemoryMap; - PLIST_ENTRY ListEntry; - EFI_STATUS Status; - UINT Index; - - /* Prepare CPUID registers */ - CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; - CpuRegisters->SubLeaf = 0; - CpuRegisters->Eax = 0; - CpuRegisters->Ebx = 0; - CpuRegisters->Ecx = 0; - CpuRegisters->Edx = 0; - - /* Get CPUID */ - ArCpuId(CpuRegisters); - - /* Store PAE status from the CPUID results */ - if(!(CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE)) - { - /* No PAE support */ - BlDbgPrint(L"ERROR: PAE extension not supported by the CPU\n"); - return STATUS_EFI_UNSUPPORTED; - } - - /* Allocate and zero-fill buffer for EFI memory map */ - BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); - - /* Get EFI memory map */ - Status = BlGetMemoryMap(MemoryMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get memory map */ - return Status; - } - - /* Calculate descriptors count and get first one */ - Descriptor = MemoryMap->Map; - DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; - - /* Calculate physical address based on KSEG0 base */ - PhysicalAddress = (UINT_PTR)VirtualAddress - KSEG0_BASE; - - /* Iterate over all descriptors from memory map to find satisfying address for PDPT */ - for(Index = 0; Index < DescriptorCount; Index++) - { - /* Check descriptor if it can be used to store PDPT */ - if((Descriptor->PhysicalStart + ((Descriptor->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) && - (Descriptor->Type == EfiConventionalMemory)) - { - /* Use highest address possible */ - if(PhysicalAddress >= Descriptor->PhysicalStart) - { - /* Use physical address */ - PDPTAddress = PhysicalAddress; - } - else - { - /* Use descriptor physical start as PDPT address */ - PDPTAddress = Descriptor->PhysicalStart; - } - - /* Allocate pages for the PDPT address */ - Status = BlEfiMemoryAllocatePages(1, &PDPTAddress); - if(Status != STATUS_EFI_SUCCESS) { - return Status; - } - break; - } - - /* Get next descriptor */ - Descriptor = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)Descriptor + MemoryMap->DescriptorSize); - } - - /* Make sure PDPT address found */ - if(PDPTAddress == 0) - { - /* No suitable area for PDPT found in EFI memory map */ - return STATUS_EFI_NOT_FOUND; - } - - /* Set virtual address based on new PDPT address mapped to KSEG0 base */ - VirtualAddress = (PVOID)(UINT_PTR)(PDPTAddress + EFI_PAGE_SIZE + KSEG0_BASE); - - /* Set base page frame number */ - Address = 0x100000; - - /* Allocate pages for the PFN */ - Status = BlEfiMemoryAllocatePages(4, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Set and zero memory used by page mappings and CR3 */ - *PtePointer = (PVOID)(UINT_PTR)PDPTAddress; - RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE); - RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE * 4); - - /* Set the page directory into the PDPT and mark it present */ - for(Index = 0; Index < 4; Index++) - { - /* Set paging entry settings */ - ((PHARDWARE_PTE)*PtePointer)[Index].PageFrameNumber = Address / EFI_PAGE_SIZE; - ((PHARDWARE_PTE)*PtePointer)[Index].Valid = 1; - - /* Next valid PFN address */ - Address += EFI_PAGE_SIZE; - } - - /* Map XTLDR code */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, - EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping the boot loader code failed */ - return Status; - } - - /* Add page mapping itself to memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping PD failed */ - return Status; - } - - /* Iterate through and map all the mappings */ - BlDbgPrint(L"Mapping and dumping EFI memory:\n"); - ListEntry = MemoryMappings->Flink; - while(ListEntry != MemoryMappings) - { - /* Take mapping from the list */ - Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); - - /* Check if virtual address is set */ - if(Mapping->VirtualAddress) - { - /* Dump memory mapping */ - BlDbgPrint(L" Type=%02lu, PhysicalBase=0x%08lx, VirtualBase=0x%08lx, Pages=%lu\n", Mapping->MemoryType, - Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); - - /* Map memory */ - Status = BlMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failed */ - return Status; - } - } - - /* Take next element */ - ListEntry = ListEntry->Flink; - } - - /* Map zero page as well */ - BlMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer); - - /* Zero-fill buffer for EFI memory map */ - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); - - /* Get EFI memory map and prepare for exiting boot services */ - BlDbgPrint(L"Exiting EFI boot services\n"); - Status = BlGetMemoryMap(MemoryMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get memory map */ - return Status; - } - - /* Exit EFI Boot Services */ - Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); - if(Status != STATUS_EFI_SUCCESS) - { - /* Retry as UEFI spec says to do it twice */ - Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); - } - - /* Check if exitted boot services successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to exit boot services */ - BlDbgPrint(L"Failed to exit boot services (Status code: %lx)\n", Status); - return STATUS_EFI_ABORTED; - } - - /* Enable Physical Address Extension (PAE) */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE); - - /* Write page mappings to CR3 */ - ArWriteControlRegister(3, (UINT_PTR)*PtePointer); - - /* Enable paging */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine does the actual virtual memory mapping. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @param VirtualAddress - * Supplies a virtual address of the mapping. - * - * @param PhysicalAddress - * Supplies a physical address of the mapping. - * - * @param NumberOfPages - * Supplies a number of the pages of the mapping. - * - * @param PaeExtension - * Specifies whether Physical Address Extension (PAE) is supported by the hardware. - * - * @param PtePointer - * Supplies a pointer to an array of pointers to page table entries. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, - IN UINT_PTR VirtualAddress, - IN UINT_PTR PhysicalAddress, - IN UINT NumberOfPages, - IN OUT PVOID *PtePointer) -{ - EFI_PHYSICAL_ADDRESS Address; - UINT_PTR PageFrameNumber; - PHARDWARE_PTE PageTable, PageDirectory; - EFI_STATUS Status; - unsigned int PdIndex, PtIndex; - - /* Set the PFN */ - PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; - - /* Do the recursive mapping */ - while(NumberOfPages > 0) - { - /* Find Page Directory and calculate indices from a virtual address */ - PageDirectory = (PHARDWARE_PTE)(UINT_PTR)(((PHARDWARE_PTE)(*PtePointer))[VirtualAddress >> 30].PageFrameNumber * EFI_PAGE_SIZE); - PdIndex = (VirtualAddress >> 21) & 0x1FF; - PtIndex = (VirtualAddress & 0x1FF000) >> 12; - - /* Validate Page Directory */ - if(!PageDirectory[PdIndex].Valid) { - /* Allocate pages for new page table */ - Status = BlEfiMemoryAllocatePages(1, &Address); - if(Status != STATUS_EFI_SUCCESS) { - /* Memory allocation failure */ - return Status; - } - - /* Fill allocated memory with zeros */ - RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); - - /* Set paging entry settings */ - PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; - PageDirectory[PdIndex].Valid = 1; - PageDirectory[PdIndex].Write = 1; - - /* Set page table */ - PageTable = (PHARDWARE_PTE)(UINT_PTR)Address; - } - else - { - /* Set page table */ - PageTable = (PHARDWARE_PTE)(UINT_PTR)(PageDirectory[PdIndex].PageFrameNumber * EFI_PAGE_SIZE); - } - /* Set page table settings */ - PageTable[PtIndex].PageFrameNumber = PageFrameNumber; - PageTable[PtIndex].Valid = 1; - PageTable[PtIndex].Write = 1; - - /* Take next virtual address and PFN */ - VirtualAddress += EFI_PAGE_SIZE; - PageFrameNumber++; - - /* Decrease number of pages left */ - NumberOfPages--; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} diff --git a/xtldr/includes/bldefs.h b/xtldr/includes/bldefs.h deleted file mode 100644 index 2ff44cb..0000000 --- a/xtldr/includes/bldefs.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/bldefs.h - * DESCRIPTION: Definitions for the XT boot loader - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BLDEFS_H -#define __XTLDR_BLDEFS_H - -#include - - -/* EFI XT boot devices */ -#define XT_BOOT_DEVICE_UNKNOWN 0x00 -#define XT_BOOT_DEVICE_CDROM 0x01 -#define XT_BOOT_DEVICE_FLOPPY 0x02 -#define XT_BOOT_DEVICE_HARDDISK 0x03 -#define XT_BOOT_DEVICE_RAMDISK 0x04 - -#endif /* __XTLDR_BLDEFS_H */ diff --git a/xtldr/includes/blmod.h b/xtldr/includes/blmod.h deleted file mode 100644 index 4138dba..0000000 --- a/xtldr/includes/blmod.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/blmod.h - * DESCRIPTION: Top level header for XTLDR modules support - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BLMOD_H -#define __XTLDR_BLMOD_H - -#include -#include -#include - - -/* Structures forward declarations */ -typedef struct _XT_BOOT_PROTOCOL XT_BOOT_PROTOCOL, *PXT_BOOT_PROTOCOL; -typedef struct _XT_BOOT_PROTOCOL_PARAMETERS XT_BOOT_PROTOCOL_PARAMETERS, *PXT_BOOT_PROTOCOL_PARAMETERS; -typedef struct _XT_PECOFFF_IMAGE_PROTOCOL XT_PECOFF_IMAGE_PROTOCOL, *PXT_PECOFF_IMAGE_PROTOCOL; - -/* Pointers to the routines provided by the modules */ -typedef EFI_STATUS (*PXT_BOOTPROTO_BOOT_SYSTEM)(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); -typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR *DriverName); -typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); -typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)(); -typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)(); -typedef EFI_STATUS (*PXT_PECOFF_GET_ENTRY_POINT)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PVOID *EntryPoint); -typedef EFI_STATUS (*PXT_PECOFF_GET_MACHINE_TYPE)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PUSHORT MachineType); -typedef EFI_STATUS (*PXT_PECOFF_GET_SUBSYSTEM)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PUSHORT SubSystem); -typedef EFI_STATUS (*PXT_PECOFF_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, - IN PVOID VirtualAddress, OUT PPECOFF_IMAGE_CONTEXT *Image); -typedef EFI_STATUS (*PXT_PECOFF_RELOCATE_IMAGE)(IN PPECOFF_IMAGE_CONTEXT Image, IN EFI_VIRTUAL_ADDRESS Address); - - -/* XT common boot protocols */ -typedef struct _XT_BOOT_PROTOCOL -{ - PXT_BOOTPROTO_BOOT_SYSTEM BootSystem; -} XT_BOOT_PROTOCOL, *PXT_BOOT_PROTOCOL; - -/* XT common boot protocol parameters */ -typedef struct _XT_BOOT_PROTOCOL_PARAMETERS -{ - PEFI_DEVICE_PATH_PROTOCOL DevicePath; - PWCHAR ArcName; - PWCHAR SystemPath; - PWCHAR KernelFile; - PWCHAR InitrdFile; - PWCHAR HalFile; - PWCHAR Arguments; -} XT_BOOT_PROTOCOL_PARAMETERS, *PXT_BOOT_PROTOCOL_PARAMETERS; - -/* XT framebuffer support protocol */ -typedef struct _XT_FRAMEBUFFER_PROTOCOL -{ - PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver; - PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation; - PXT_FRAMEBUFFER_INITIALIZE Initialize; - PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation; -} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL; - -/* XT framebuffer information structure definition */ -typedef struct _XT_FRAMEBUFFER_INFORMATION -{ - BOOLEAN Initialized; - EFI_GRAPHICS_PROTOCOL Protocol; - union - { - PEFI_GRAPHICS_OUTPUT_PROTOCOL GOP; - PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL UGA; - } Adapter; - UINT HorizontalResolution; - UINT VerticalResolution; - UINT BitsPerPixel; - UINT BytesPerPixel; - UINT PixelsPerScanLine; - UINT Pitch; - EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; - EFI_PHYSICAL_ADDRESS FrameBufferBase; - ULONG_PTR FrameBufferSize; -} XT_FRAMEBUFFER_INFORMATION, *PXT_FRAMEBUFFER_INFORMATION; - -/* EFI XT PE/COFF Image Protocol */ -typedef struct _XT_PECOFFF_IMAGE_PROTOCOL -{ - PXT_PECOFF_GET_ENTRY_POINT GetEntryPoint; - PXT_PECOFF_GET_MACHINE_TYPE GetMachineType; - PXT_PECOFF_GET_SUBSYSTEM GetSubSystem; - PXT_PECOFF_LOAD_IMAGE Load; - PXT_PECOFF_RELOCATE_IMAGE Relocate; -} XT_PECOFF_IMAGE_PROTOCOL, *PXT_PECOFF_IMAGE_PROTOCOL; - -#endif /* __XTLDR_BLMOD_H */ diff --git a/xtldr/includes/blproto.h b/xtldr/includes/blproto.h deleted file mode 100644 index 8b82e8c..0000000 --- a/xtldr/includes/blproto.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/blproto.h - * DESCRIPTION: XTLDR boot loader protocol support - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BLPROTO_H -#define __XTLDR_BLPROTO_H - -#include -#include - - -/* Loader protocol routine pointers */ -typedef EFI_STATUS (*PBL_ADD_VIRTUAL_MEMORY_MAPPING)(IN PLIST_ENTRY MemoryMappings, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN UINT NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); -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 EFI_STATUS (*PBL_ENABLE_PAGING)(IN PLIST_ENTRY MemoryMappings, IN PVOID VirtualAddress, IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, IN PVOID *PtePointer); -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_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); -typedef EFI_STATUS (*PBL_GET_VIRTUAL_ADDRESS)(IN PLIST_ENTRY MemoryMappings, IN PVOID PhysicalAddress, OUT PVOID *VirtualAddress); -typedef EFI_STATUS (*PBL_INIT_VIRTUAL_MEMORY)(IN OUT PLIST_ENTRY MemoryMappings, IN OUT PVOID *MemoryMapAddress); -typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN PLIST_ENTRY MemoryMappings, IN UINT_PTR VirtualAddress, IN UINT_PTR PhysicalAddress, IN UINT NumberOfPages, IN OUT PVOID *PtePointer); -typedef VOID (*PBL_GET_STACK)(OUT PVOID *Stack); -typedef VOID (*PBL_DBG_PRINT)(IN PUINT16 Format, IN ...); -typedef VOID (*PBL_EFI_PRINT)(IN PUINT16 Format, IN ...); -typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); -typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); - -/* EFI XT Boot Loader Protocol */ -typedef struct _XT_BOOT_LOADER_PROTOCOL -{ - PBL_ADD_VIRTUAL_MEMORY_MAPPING AddVirtualMemoryMapping; - PBL_ALLOCATE_PAGES AllocatePages; - PBL_ALLOCATE_POOL AllocatePool; - PBL_FREE_PAGES FreePages; - PBL_FREE_POOL FreePool; - PBL_ENABLE_PAGING EnablePaging; - PBL_GET_MEMORY_MAP GetMemoryMap; - PBL_GET_VIRTUAL_ADDRESS GetVirtualAddress; - PBL_INIT_VIRTUAL_MEMORY InitializeVirtualMemory; - PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory; - PBL_DBG_PRINT DbgPrint; - PBL_EFI_PRINT EfiPrint; - PBL_CLOSE_VOLUME CloseVolume; - PBL_OPEN_VOLUME OpenVolume; -} XT_BOOT_LOADER_PROTOCOL, *PXT_BOOT_LOADER_PROTOCOL; - -/* Loader protocol related routines forward references */ -XTCDECL -EFI_STATUS -BlGetXtLoaderProtocol(OUT PXT_BOOT_LOADER_PROTOCOL *LdrProtocol); - -XTCDECL -EFI_STATUS -BlLoadXtProtocol(OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); - -#endif /* __XTLDR_BLPROTO_H */ diff --git a/xtldr2/includes/globals.h b/xtldr/includes/globals.h similarity index 100% rename from xtldr2/includes/globals.h rename to xtldr/includes/globals.h diff --git a/xtldr/includes/xtbl.h b/xtldr/includes/xtbl.h deleted file mode 100644 index 40ccc62..0000000 --- a/xtldr/includes/xtbl.h +++ /dev/null @@ -1,264 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/xtbl.h - * DESCRIPTION: Top level header for XTLDR - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_XTBL_H -#define __XTLDR_XTBL_H - -#include -#include -#include - - -/* List of available block devices */ -EXTERN LIST_ENTRY EfiBlockDevices; - -/* XT Boot Loader hex table */ -EXTERN PUINT16 EfiHexTable; - -/* EFI Image Handle */ -EXTERN EFI_HANDLE EfiImageHandle; - -/* XT Boot Loader protocol */ -EXTERN XT_BOOT_LOADER_PROTOCOL EfiLdrProtocol; - -/* EFI System Table */ -EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; - -/* EFI Secure Boot status */ -EXTERN INT_PTR EfiSecureBoot; - -/* New bootloader stack */ -EXTERN PVOID EfiLoaderStack; - -/* Serial port configuration */ -EXTERN CPPORT EfiSerialPort; - -XTCDECL -EFI_STATUS -BlActivateSerialControllerIO(); - -XTCDECL -EFI_STATUS -BlAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN UINT NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType); - -XTCDECL -EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle); - -XTCDECL -EFI_STATUS -BlComPortInitialize(); - -XTCDECL -VOID -BlComPortPutChar(IN USHORT Character); - -XTCDECL -VOID -BlConsoleClearScreen(); - -XTCDECL -VOID -BlConsoleInitialize(); - -XTCDECL -VOID -BlConsolePutChar(IN USHORT Character); - -XTCDECL -LOADER_MEMORY_TYPE -BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); - -XTCDECL -VOID -BlDbgPrint(IN PUINT16 Format, - IN ...); - -XTCDECL -INT_PTR -BlEfiGetSecureBootStatus(); - -XTCDECL -EFI_STATUS -BlEfiGetSystemConfigurationTable(IN PEFI_GUID TableGuid, - OUT PVOID *Table); - -XTCDECL -EFI_STATUS -BlEfiMemoryAllocatePages(IN UINT64 Size, - OUT PEFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlEfiMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory); - -XTCDECL -EFI_STATUS -BlEfiMemoryFreePages(IN UINT64 Size, - IN EFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlEfiMemoryFreePool(IN PVOID Memory); - -XTCDECL -VOID -BlEfiPrint(IN PUINT16 Format, - IN ...); - -XTCDECL -EFI_STATUS -BlEnablePaging(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, - IN PVOID *PtePointer); - -XTCDECL -EFI_STATUS -BlEnumerateEfiBlockDevices(); - -XTCDECL -EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, - IN CONST PWCHAR FileSystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); - -XTCDECL -EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); - -XTCDECL -EFI_STATUS -BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, - IN PVOID PhysicalAddress, - OUT PVOID *VirtualAddress); - -XTCDECL -EFI_STATUS -BlGetVolumeDevicePath(IN PUCHAR SystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PUCHAR *ArcName, - OUT PUCHAR *Path); - -XTCDECL -EFI_STATUS -BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, - IN OUT PVOID *MemoryMapAddress); - -XTCDECL -EFI_STATUS -BlLoadEfiModules(); - -XTCDECL -EFI_STATUS -BlLoadXtSystem(); - -XTCDECL -EFI_STATUS -BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, - IN UINT_PTR VirtualAddress, - IN UINT_PTR PhysicalAddress, - IN UINT NumberOfPages, - IN OUT PVOID *PtePointer); - -XTCDECL -EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle); - -XTCDECL -EFI_STATUS -BlRegisterXtLoaderProtocol(); - -XTCDECL -EFI_STATUS -BlStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -XTCDECL -INT -BlStringCompareInsensitive(IN PUCHAR String1, - IN PUCHAR String2); - -XTCDECL -VOID -BlStringPrint(IN VOID PutChar(IN USHORT Character), - IN PUINT16 Format, - IN VA_LIST Arguments); - -XTCDECL -EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); - -XTCDECL -EFI_STATUS -BlpDissectVolumeArcPath(IN PUCHAR SystemPath, - OUT PUCHAR *ArcName, - OUT PUCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber); - -XTCDECL -PEFI_DEVICE_PATH_PROTOCOL -BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); - -XTCDECL -EFI_STATUS -BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); - -XTCDECL -BOOLEAN -BlpFindParentEfiBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA ParentNode); - -XTCDECL -VOID -BlpStringFormat(IN VOID PutChar(IN USHORT Character), - IN PUINT16 Format, - IN ...); - -XTCDECL -VOID -BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character), - IN INT32 Number, - IN UINT32 Base); - -XTCDECL -VOID -BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character), - IN INT_PTR Number, - IN UINT_PTR Base); - -XTCDECL -VOID -BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character), - IN UINT32 Number, - IN UINT32 Base, - IN UINT32 Padding); - -XTCDECL -VOID -BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character), - IN UINT_PTR Number, - IN UINT_PTR Base, - IN UINT_PTR Padding); - -XTCDECL -UINT64 -BlpStringReadPadding(IN PUINT16 *Format); - -#endif /* __XTLDR_XTBL_H */ diff --git a/xtldr2/includes/xtldr.h b/xtldr/includes/xtldr.h similarity index 100% rename from xtldr2/includes/xtldr.h rename to xtldr/includes/xtldr.h diff --git a/xtldr2/library/modproto.c b/xtldr/library/modproto.c similarity index 100% rename from xtldr2/library/modproto.c rename to xtldr/library/modproto.c diff --git a/xtldr/memory.c b/xtldr/memory.c index 6a09dd9..8df0448 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.c @@ -2,315 +2,13 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/memory.c - * DESCRIPTION: EFI memory management + * DESCRIPTION: XT Boot Loader memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include -/** - * Adds a physical to virtual address mapping to the linked list for future processing. - * - * @param MemoryMapping - * Supplies the head of the memory mapping list. - * - * @param VirtualAddress - * Supplies a virtual address where the physical address should be mapped. - * - * @param PhysicalAddress - * Supplies a physical address which will be mapped. - * - * @param NumberOfPages - * Supplies a number of pages which will be mapped. - * - * @param MemoryType - * Supplies the type of memory that will be assigned to the memory descriptor. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN UINT NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType) -{ - PLOADER_MEMORY_MAPPING Mapping1, Mapping2, Mapping3; - PVOID PhysicalAddressEnd, PhysicalAddress2End; - PLIST_ENTRY ListEntry, MappingListEntry; - SIZE_T NumberOfMappedPages; - EFI_STATUS Status; - - /* Allocate memory for new mapping */ - Status = BlEfiMemoryAllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID *)&Mapping1); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Set mapping fields */ - Mapping1->PhysicalAddress = PhysicalAddress; - Mapping1->VirtualAddress = VirtualAddress; - Mapping1->NumberOfPages = NumberOfPages; - Mapping1->MemoryType = MemoryType; - - /* Calculate the end of the physical address */ - PhysicalAddressEnd = (PUINT8)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1; - - /* Iterate through all the mappings already set to insert new mapping at the correct place */ - ListEntry = MemoryMappings->Flink; - while(ListEntry != MemoryMappings) - { - /* Take a mapping from the list and calculate its end of physical address */ - Mapping2 = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); - PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1 ; - - /* Check if they overlap */ - if(PhysicalAddressEnd > Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End) - { - /* Make sure it's memory type is LoaderFree */ - if(Mapping2->MemoryType != LoaderFree) - { - /* LoaderFree memory type is strictly expected */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Calculate number of pages for this mapping */ - NumberOfMappedPages = ((PUINT8)PhysicalAddress2End - (PUINT8)PhysicalAddressEnd) / EFI_PAGE_SIZE; - if(NumberOfMappedPages > 0) - { - /* Pages associated to the mapping, allocate memory for it */ - Status = BlEfiMemoryAllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Set mapping fields and insert it on the top */ - Mapping3->PhysicalAddress = (PUINT8)PhysicalAddressEnd + 1; - Mapping3->VirtualAddress = NULL; - Mapping3->NumberOfPages = NumberOfMappedPages; - Mapping3->MemoryType = Mapping2->MemoryType; - RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); - } - - /* Calculate number of pages and the end of the physical address */ - Mapping2->NumberOfPages = ((PUINT8)PhysicalAddressEnd + 1 - - (PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; - PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; - } - - /* Check if they overlap */ - if(Mapping1->PhysicalAddress > Mapping2->PhysicalAddress && Mapping1->PhysicalAddress < PhysicalAddress2End) - { - /* Make sure it's memory type is LoaderFree */ - if(Mapping2->MemoryType != LoaderFree) - { - /* LoaderFree memory type is strictly expected */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Calculate number of pages for this mapping */ - NumberOfMappedPages = ((PUINT8)PhysicalAddress2End + 1 - (PUINT8)Mapping1->PhysicalAddress) / EFI_PAGE_SIZE; - if(NumberOfMappedPages > 0) - { - /* Pages associated to the mapping, allocate memory for it */ - Status = BlEfiMemoryAllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Set mapping fields and insert it on the top */ - Mapping3->PhysicalAddress = Mapping1->PhysicalAddress; - Mapping3->VirtualAddress = NULL; - Mapping3->NumberOfPages = NumberOfMappedPages; - Mapping3->MemoryType = Mapping2->MemoryType; - RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); - } - - /* Calculate number of pages and the end of the physical address */ - Mapping2->NumberOfPages = ((PUINT8)Mapping1->PhysicalAddress - - (PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; - PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; - } - - /* Check if mapping is really needed */ - if((Mapping2->PhysicalAddress >= Mapping1->PhysicalAddress && PhysicalAddress2End <= PhysicalAddressEnd) || - (Mapping2->NumberOfPages == 0)) - { - /* Make sure it's memory type is LoaderFree */ - if(Mapping2->MemoryType != LoaderFree) - { - /* LoaderFree memory type is strictly expected */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Store address of the next mapping */ - MappingListEntry = ListEntry->Flink; - - /* Remove mapping from the list and free up it's memory */ - RtlRemoveEntryList(&Mapping2->ListEntry); - BlEfiMemoryFreePool(Mapping2); - ListEntry = MappingListEntry; - - /* Go to the next mapping */ - continue; - } - - /* Determine phsical address order */ - if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress) - { - /* Insert new mapping in front */ - RtlInsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); - return STATUS_EFI_SUCCESS; - } - - /* Get next mapping from the list */ - ListEntry = ListEntry->Flink; - } - - /* Insert new mapping to the end of the list and return success */ - RtlInsertTailList(MemoryMappings, &Mapping1->ListEntry); - return STATUS_EFI_SUCCESS; -} - -/** - * Converts an EFI memory type into an XTOS memory type. - * - * @param EfiMemoryType - * Supplies the EFI memory type. - * - * @return Returns a conversion of the memory type. - * - * @since XT 1.0 - */ -XTCDECL -LOADER_MEMORY_TYPE -BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) -{ - LOADER_MEMORY_TYPE MemoryType; - - /* Check EFI memory type and convert to XTOS memory type */ - switch(EfiMemoryType) - { - case EfiACPIMemoryNVS: - case EfiACPIReclaimMemory: - case EfiPalCode: - MemoryType = LoaderSpecialMemory; - break; - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: - MemoryType = LoaderFirmwarePermanent; - break; - case EfiBootServicesData: - case EfiLoaderCode: - case EfiLoaderData: - MemoryType = LoaderFirmwareTemporary; - break; - case EfiUnusableMemory: - MemoryType = LoaderBad; - break; - default: - MemoryType = LoaderFree; - break; - } - - /* Return XTOS memory type */ - return MemoryType; -} - -/** - * This routine allocates one or more 4KB pages. - * - * @param Pages - * The number of contiguous 4KB pages to allocate. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEfiMemoryAllocatePages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); -} - -/** - * This routine allocates a pool memory. - * - * @param Size - * The number of bytes to allocate from the pool. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEfiMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory) -{ - /* Allocate pool */ - return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); -} - -/** - * This routine frees memory pages. - * - * @param Pages - * The number of contiguous 4 KB pages to free. - * - * @param Memory - * The base physical address of the pages to be freed. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEfiMemoryFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->FreePages(Memory, Pages); -} - -/** - * Returns pool memory to the system. - * - * @param Memory - * The pointer to the buffer to free. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEfiMemoryFreePool(IN PVOID Memory) -{ - /* Free pool */ - return EfiSystemTable->BootServices->FreePool(Memory); -} - /** * Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI. * @@ -352,14 +50,14 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) if(MemoryMap->Map) { /* Free allocated memory */ - BlEfiMemoryFreePool(MemoryMap->Map); + BlMemoryFreePool(MemoryMap->Map); } return Status; } /* Allocate the desired amount of memory */ MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; - BlEfiMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); + BlMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); } while(Status == STATUS_EFI_BUFFER_TOO_SMALL); @@ -375,16 +73,13 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) } /** - * Attempts to find a virtual address of the specified physical address in memory mappings. + * This routine allocates one or more 4KB pages. * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. + * @param Pages + * The number of contiguous 4KB pages to allocate. * - * @param PhysicalAddress - * Supplies a physical address to search for in the mappings. - * - * @param VirtualAddress - * Supplies a buffer, where mapped virtual address of the found mapping will be stored. + * @param Memory + * The pointer to a physical address. * * @return This routine returns a status code. * @@ -392,58 +87,20 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) */ XTCDECL EFI_STATUS -BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, - IN PVOID PhysicalAddress, - OUT PVOID *VirtualAddress) +BlMemoryAllocatePages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory) { - PLOADER_MEMORY_MAPPING Mapping; - PLIST_ENTRY ListEntry; - - /* NULLify virtual address */ - *VirtualAddress = NULL; - - /* Iterate over memory mappings in order to find descriptor containing a physical address */ - ListEntry = MemoryMappings->Flink; - while(ListEntry != MemoryMappings) - { - /* Get mapping from linked list */ - Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); - - /* Make sure any virtual address is set */ - if(Mapping->VirtualAddress) - { - /* Check if provided physical address is in range of this mapping */ - if((PhysicalAddress >= Mapping->PhysicalAddress) && - (PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) - { - /* Calculate virtual address based on the mapping */ - *VirtualAddress = PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress; - } - } - - /* Get next element from the list */ - ListEntry = ListEntry->Flink; - } - - /* If virtual address is still NULL, then mapping was not found */ - if(*VirtualAddress == NULL) - { - /* Mapping not found */ - return STATUS_EFI_NOT_FOUND; - } - - /* Mapping found, return success */ - return STATUS_EFI_SUCCESS; + return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); } /** - * Initializes virtual memory by adding known and general mappings. + * This routine allocates a pool memory. * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. + * @param Size + * The number of bytes to allocate from the pool. * - * @param MemoryMapAddress - * Supplies an address of the mapped virtual memory area. + * @param Memory + * The pointer to a physical address. * * @return This routine returns a status code. * @@ -451,80 +108,48 @@ BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, */ XTCDECL EFI_STATUS -BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, - IN OUT PVOID *MemoryMapAddress) +BlMemoryAllocatePool(IN UINT_PTR Size, + OUT PVOID *Memory) { - PEFI_MEMORY_DESCRIPTOR Descriptor; - LOADER_MEMORY_TYPE MemoryType; - PEFI_MEMORY_MAP MemoryMap; - SIZE_T DescriptorCount; - PUCHAR VirtualAddress; - EFI_STATUS Status; - SIZE_T Index; - - /* Set initial virtual address */ - VirtualAddress = *MemoryMapAddress; - - /* Allocate and zero-fill buffer for EFI memory map */ - BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); - - /* Get EFI memory map */ - Status = BlGetMemoryMap(MemoryMap); - if(Status != STATUS_EFI_SUCCESS) - { - return Status; - } - - /* Calculate descriptors count and get first one */ - Descriptor = MemoryMap->Map; - DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; - - /* Iterate through all descriptors from the memory map */ - for(Index = 0; Index < DescriptorCount; Index++) - { - /* Make sure descriptor does not go beyond lowest physical page */ - if((Descriptor->PhysicalStart + (Descriptor->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1) - { - /* Convert EFI memory type into XTOS memory type */ - MemoryType = BlConvertEfiMemoryType(Descriptor->Type); - - /* Do memory mappings depending on memory type */ - if(MemoryType == LoaderFirmwareTemporary) - { - /* Map EFI firmware code */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)Descriptor->PhysicalStart, - (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); - } - else if(MemoryType != LoaderFree) - { - /* Add any non-free memory mapping */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, MemoryType); - - /* Calculate next valid virtual address */ - VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; - } - else - { - /* Map all other memory as loader free */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, LoaderFree); - } - - /* Make sure memory mapping succeeded */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping failed */ - return Status; - } - - /* Grab next descriptor */ - Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize); - } - } - - /* Store next valid virtual address and return success */ - *MemoryMapAddress = VirtualAddress; - return STATUS_EFI_SUCCESS; + /* Allocate pool */ + return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); +} + +/** + * This routine frees memory pages. + * + * @param Pages + * The number of contiguous 4 KB pages to free. + * + * @param Memory + * The base physical address of the pages to be freed. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlMemoryFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory) +{ + return EfiSystemTable->BootServices->FreePages(Memory, Pages); +} + +/** + * Returns pool memory to the system. + * + * @param Memory + * The pointer to the buffer to free. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlMemoryFreePool(IN PVOID Memory) +{ + /* Free pool */ + return EfiSystemTable->BootServices->FreePool(Memory); } diff --git a/xtldr/modules/CMakeLists.txt b/xtldr/modules/CMakeLists.txt index c898f2e..136fbbb 100644 --- a/xtldr/modules/CMakeLists.txt +++ b/xtldr/modules/CMakeLists.txt @@ -1,3 +1,4 @@ -add_subdirectory(framebuf) -add_subdirectory(pecoff) -add_subdirectory(xtos) +add_subdirectory(dummy) +add_subdirectory(fb_o) +add_subdirectory(pecoff_o) +add_subdirectory(xtos_o) diff --git a/xtldr2/modules/dummy/CMakeLists.txt b/xtldr/modules/dummy/CMakeLists.txt similarity index 100% rename from xtldr2/modules/dummy/CMakeLists.txt rename to xtldr/modules/dummy/CMakeLists.txt diff --git a/xtldr2/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c similarity index 100% rename from xtldr2/modules/dummy/dummy.c rename to xtldr/modules/dummy/dummy.c diff --git a/xtldr2/modules/dummy/globals.c b/xtldr/modules/dummy/globals.c similarity index 100% rename from xtldr2/modules/dummy/globals.c rename to xtldr/modules/dummy/globals.c diff --git a/xtldr2/modules/dummy/includes/globals.h b/xtldr/modules/dummy/includes/globals.h similarity index 100% rename from xtldr2/modules/dummy/includes/globals.h rename to xtldr/modules/dummy/includes/globals.h diff --git a/xtldr2/modules/fb_o/CMakeLists.txt b/xtldr/modules/fb_o/CMakeLists.txt similarity index 100% rename from xtldr2/modules/fb_o/CMakeLists.txt rename to xtldr/modules/fb_o/CMakeLists.txt diff --git a/xtldr2/modules/fb_o/framebuf.c b/xtldr/modules/fb_o/framebuf.c similarity index 100% rename from xtldr2/modules/fb_o/framebuf.c rename to xtldr/modules/fb_o/framebuf.c diff --git a/xtldr2/modules/fb_o/gop.c b/xtldr/modules/fb_o/gop.c similarity index 100% rename from xtldr2/modules/fb_o/gop.c rename to xtldr/modules/fb_o/gop.c diff --git a/xtldr2/modules/fb_o/includes/framebuf.h b/xtldr/modules/fb_o/includes/framebuf.h similarity index 100% rename from xtldr2/modules/fb_o/includes/framebuf.h rename to xtldr/modules/fb_o/includes/framebuf.h diff --git a/xtldr/modules/framebuf/CMakeLists.txt b/xtldr/modules/framebuf/CMakeLists.txt deleted file mode 100644 index 41ebc4c..0000000 --- a/xtldr/modules/framebuf/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# XT Boot Loader -PROJECT(XTLDR_FRAMEBUF) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes - ${XTLDR_FRAMEBUF_SOURCE_DIR}/includes) - -# Specify list of source code files -list(APPEND XTLDR_FRAMEBUF_SOURCE - ${XTLDR_SOURCE_DIR}/blproto.c - ${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.c - ${XTLDR_FRAMEBUF_SOURCE_DIR}/gop.c) - -# Link bootloader executable -add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE}) - -# Add linker libraries -target_link_libraries(framebuf libxtos) - -# Set proper binary name and install target -set_target_properties(framebuf PROPERTIES SUFFIX .efi) -set_install_target(framebuf efi/boot/xtldr) - -# Set module entrypoint and subsystem -set_entrypoint(framebuf "BlXtLdrModuleMain") -set_subsystem(framebuf efi_boot_service_driver) diff --git a/xtldr/modules/framebuf/framebuf.c b/xtldr/modules/framebuf/framebuf.c deleted file mode 100644 index 71b764f..0000000 --- a/xtldr/modules/framebuf/framebuf.c +++ /dev/null @@ -1,277 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/framebuf.c - * DESCRIPTION: Boot loader framebuffer support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* EFI Image Handle */ -EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -PEFI_SYSTEM_TABLE EfiSystemTable; - -/* EFI XT Loader Protocol */ -PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; - -/* XT FrameBuffer Information */ -XT_FRAMEBUFFER_INFORMATION FrameBufferInfo; - -/* XT FrameBuffer Protocol */ -XT_FRAMEBUFFER_PROTOCOL XtFramebufferProtocol; - -/** - * Provides a current FrameBuffer driver name. - * - * @param DriverName - * Supplies a pointer to the memory area where FB driver name will be stored. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -FbGetDisplayDriver(OUT PWCHAR *DriverName) -{ - switch(FrameBufferInfo.Protocol) - { - case GOP: - *DriverName = L"GOP"; - break; - case UGA: - *DriverName = L"UGA"; - break; - default: - *DriverName = L"NONE"; - break; - } -} - -/** - * Returns information about frame buffer in XTOS compatible format. - * - * @param InformationBlock - * A pointer to memory area containing XT structure where all the information will be stored. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock) -{ - InformationBlock->Initialized = FrameBufferInfo.Initialized; - InformationBlock->Protocol = FrameBufferInfo.Protocol; - InformationBlock->Address = (PVOID)(ULONG_PTR)FrameBufferInfo.FrameBufferBase; - InformationBlock->BufferSize = FrameBufferInfo.FrameBufferSize; - InformationBlock->Width = FrameBufferInfo.HorizontalResolution; - InformationBlock->Height = FrameBufferInfo.VerticalResolution; - InformationBlock->BitsPerPixel = FrameBufferInfo.BitsPerPixel; - InformationBlock->PixelsPerScanLine = FrameBufferInfo.PixelsPerScanLine; - InformationBlock->Pitch = FrameBufferInfo.Pitch; -} - -/** - * Initializes FrameBuffer device on GOP and UGA compatible adapters. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbInitializeDisplay() -{ - EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; - UINT32 Parameter1, Parameter2; - EFI_STATUS Status; - - /* Check if framebuffer already initialized */ - if(!FrameBufferInfo.Initialized) - { - /* Initialize framebuffer */ - XtLdrProtocol->DbgPrint(L"Initializing framebuffer device\n"); - FrameBufferInfo.Protocol = NONE; - FrameBufferInfo.Initialized = FALSE; - - /* Check if GOP already in use */ - Status = EfiSystemTable->BootServices->HandleProtocol(EfiSystemTable->ConsoleOutHandle, &GopGuid, - (PVOID*)&FrameBufferInfo.Adapter.GOP); - if(Status != STATUS_EFI_SUCCESS) - { - /* Locate GOP protocol */ - Status = EfiSystemTable->BootServices->LocateProtocol(&GopGuid, NULL, (PVOID *)&FrameBufferInfo.Adapter.GOP); - } - - /* Check if Graphics Output Protocol is available */ - if(Status == STATUS_EFI_SUCCESS) - { - /* Found GOP */ - XtLdrProtocol->DbgPrint(L"Found GOP compatible display adapter\n"); - - /* Set framebuffer parameters */ - FrameBufferInfo.HorizontalResolution = FrameBufferInfo.Adapter.GOP->Mode->Info->HorizontalResolution; - FrameBufferInfo.VerticalResolution = FrameBufferInfo.Adapter.GOP->Mode->Info->VerticalResolution; - FrameBufferInfo.BitsPerPixel = GoppGetBitsPerPixel(); - FrameBufferInfo.BytesPerPixel = FrameBufferInfo.BitsPerPixel >> 3; - FrameBufferInfo.PixelsPerScanLine = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelsPerScanLine; - FrameBufferInfo.PixelFormat = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelFormat; - FrameBufferInfo.Pitch = FrameBufferInfo.PixelsPerScanLine * (FrameBufferInfo.BitsPerPixel / 8); - FrameBufferInfo.FrameBufferBase = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferBase; - FrameBufferInfo.FrameBufferSize = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferSize; - FrameBufferInfo.Protocol = GOP; - FrameBufferInfo.Initialized = TRUE; - } - else - { - /* GOP is unavailable */ - FrameBufferInfo.Adapter.GOP = NULL; - - /* Check if UGA already in use */ - Status = EfiSystemTable->BootServices->HandleProtocol(EfiSystemTable->ConsoleOutHandle, &UgaGuid, - (PVOID*)&FrameBufferInfo.Adapter.UGA); - if(Status != STATUS_EFI_SUCCESS) - { - /* Locate UGA protocol */ - Status = EfiSystemTable->BootServices->LocateProtocol(&UgaGuid, NULL, - (PVOID*)&FrameBufferInfo.Adapter.UGA); - } - - /* Check if Universal Graphics Adapter is available */ - if(Status == STATUS_EFI_SUCCESS) - { - /* Found UGA */ - XtLdrProtocol->DbgPrint(L"Found UGA compatible display adapter\n"); - - /* Get current mode */ - Status = FrameBufferInfo.Adapter.UGA->GetMode(FrameBufferInfo.Adapter.UGA, - &FrameBufferInfo.HorizontalResolution, - &FrameBufferInfo.VerticalResolution, - &Parameter1, &Parameter2); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get current UGA mode */ - XtLdrProtocol->DbgPrint(L"Failed to get current UGA mode (Status code: %lx)\n", Status); - FrameBufferInfo.Adapter.UGA = NULL; - } - else - { - /* Set framebuffer parameters */ - FrameBufferInfo.BitsPerPixel = 32; - FrameBufferInfo.BytesPerPixel = 4; - FrameBufferInfo.PixelsPerScanLine = FrameBufferInfo.HorizontalResolution; - FrameBufferInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; - FrameBufferInfo.Pitch = FrameBufferInfo.PixelsPerScanLine * (FrameBufferInfo.BitsPerPixel / 8); - FrameBufferInfo.FrameBufferBase = 0; - FrameBufferInfo.FrameBufferSize = FrameBufferInfo.HorizontalResolution * - FrameBufferInfo.VerticalResolution * - FrameBufferInfo.BytesPerPixel + 1024; - FrameBufferInfo.Protocol = UGA; - - /* Temporarily set this to FALSE, as we don't set FB base and we cannot use it anyway */ - FrameBufferInfo.Initialized = FALSE; - } - } - } - - /* Make sure framebuffer initialized properly */ - if(!FrameBufferInfo.Initialized) - { - /* GOP and UGA unavailable */ - XtLdrProtocol->DbgPrint(L"No display adapter found\n"); - return STATUS_EFI_NOT_FOUND; - } - } - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Prints important information about framebuffer. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -FbPrintDisplayInformation() -{ - PWCHAR DriverName; - - /* Make sure frame buffer is initialized */ - if(!FrameBufferInfo.Initialized) - { - /* No FrameBuffer */ - XtLdrProtocol->DbgPrint(L"No display adapters initialized, unable to print video information\n"); - return; - } - - /* Get display driver name */ - FbGetDisplayDriver(&DriverName); - - /* Print video information */ - XtLdrProtocol->DbgPrint(L"XTLDR Framebuffer information:\n" - L" FrameBuffer Address: 0x%lx\n" - L" FrameBuffer Size: %lu\n" - L" FrameBuffer Driver: %S\n" - L" Current Resolution: %ux%ux%u\n" - L" Pixel Format: %u\n" - L" Pixels Per ScanLine: %u\n", - FrameBufferInfo.FrameBufferBase, FrameBufferInfo.FrameBufferSize, DriverName, - FrameBufferInfo.HorizontalResolution, FrameBufferInfo.VerticalResolution, - FrameBufferInfo.BitsPerPixel, FrameBufferInfo.PixelFormat, - FrameBufferInfo.PixelsPerScanLine); -} - -/** - * This routine is the entry point of the XT EFI boot loader module. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param SystemTable - * Provides the EFI system table. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable) -{ - EFI_GUID Guid = XT_FRAMEBUFFER_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; - EFI_STATUS Status; - - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Open the XTLDR protocol */ - Status = BlGetXtLoaderProtocol(&XtLdrProtocol); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open loader protocol */ - return STATUS_EFI_PROTOCOL_ERROR; - } - - XtFramebufferProtocol.GetDisplayDriver = FbGetDisplayDriver; - XtFramebufferProtocol.GetDisplayInformation = FbGetDisplayInformation; - XtFramebufferProtocol.Initialize = FbInitializeDisplay; - XtFramebufferProtocol.PrintDisplayInformation = FbPrintDisplayInformation; - - /* Register XTOS boot protocol */ - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, - &XtFramebufferProtocol); -} diff --git a/xtldr/modules/framebuf/gop.c b/xtldr/modules/framebuf/gop.c deleted file mode 100644 index ea9c732..0000000 --- a/xtldr/modules/framebuf/gop.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/gop.c - * DESCRIPTION: Graphical Output Protocol (GOP) support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Returns a number of bits per pixel (BPP) in the current video mode. - * - * @return A number of bits per pixel. - * - * @since XT 1.0 - */ -XTCDECL -UINT32 -GoppGetBitsPerPixel() -{ - UINT32 BitsPerPixel, CompoundMask; - - switch(FrameBufferInfo.Adapter.GOP->Mode->Info->PixelFormat) - { - case PixelBlueGreenRedReserved8BitPerColor: - case PixelRedGreenBlueReserved8BitPerColor: - case PixelBltOnly: - BitsPerPixel = 32; - break; - case PixelBitMask: - BitsPerPixel = 32; - CompoundMask = FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.RedMask | - FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.GreenMask | - FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.BlueMask | - FrameBufferInfo.Adapter.GOP->Mode->Info->PixelInformation.ReservedMask; - while((CompoundMask & (1 << 31)) == 0) - { - BitsPerPixel--; - CompoundMask <<= 1; - } - break; - default: - BitsPerPixel = 0; - break; - } - - /* Return bpp */ - return BitsPerPixel; -} diff --git a/xtldr/modules/framebuf/includes/framebuf.h b/xtldr/modules/framebuf/includes/framebuf.h deleted file mode 100644 index 12f54c3..0000000 --- a/xtldr/modules/framebuf/includes/framebuf.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/includes/framebuf.h - * DESCRIPTION: Framebuffer support module header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_FRAMEBUF_H -#define __XTLDR_MODULES_FRAMEBUF_H - -#include - - -/* XT FrameBuffer Information */ -EXTERN XT_FRAMEBUFFER_INFORMATION FrameBufferInfo; - -/* FrameBuffer support protocol related routines forward references */ -XTCDECL -VOID -FbGetDisplayDriver(OUT PWCHAR *DriverName); - -XTCDECL -VOID -FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); - -XTCDECL -EFI_STATUS -FbInitializeDisplay(); - -XTCDECL -VOID -FbPrintDisplayInformation(); - -XTCDECL -UINT32 -GoppGetBitsPerPixel(); - -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_MODULES_FRAMEBUF_H */ diff --git a/xtldr/modules/pecoff/CMakeLists.txt b/xtldr/modules/pecoff/CMakeLists.txt deleted file mode 100644 index c556bc8..0000000 --- a/xtldr/modules/pecoff/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# XT Boot Loader -PROJECT(XTLDR_PECOFF) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes - ${XTLDR_PECOFF_SOURCE_DIR}/includes) - -# Specify list of source code files -list(APPEND XTLDR_PECOFF_SOURCE - ${XTLDR_SOURCE_DIR}/blproto.c - ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c) - -# Link bootloader executable -add_executable(pecoff ${XTLDR_PECOFF_SOURCE}) - -# Add linker libraries -target_link_libraries(pecoff libxtos) - -# Set proper binary name and install target -set_target_properties(pecoff PROPERTIES SUFFIX .efi) -set_install_target(pecoff efi/boot/xtldr) - -# Set module entrypoint and subsystem -set_entrypoint(pecoff "BlXtLdrModuleMain") -set_subsystem(pecoff efi_boot_service_driver) diff --git a/xtldr/modules/pecoff/includes/pecoff.h b/xtldr/modules/pecoff/includes/pecoff.h deleted file mode 100644 index b026fc0..0000000 --- a/xtldr/modules/pecoff/includes/pecoff.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff/includes/pecoff.h - * DESCRIPTION: PE/COFF executable file format support header - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_PECOFF_H -#define __XTLDR_MODULES_PECOFF_H - -#include - - -/* PE/COFF image protocol related routines forward references */ -XTCDECL -EFI_STATUS -PeGetEntryPoint(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PVOID *EntryPoint); - -XTCDECL -EFI_STATUS -PeGetMachineType(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PUSHORT MachineType); - -XTCDECL -EFI_STATUS -PeGetSubSystem(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PUSHORT SubSystem); - -XTCDECL -EFI_STATUS -PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, - IN LOADER_MEMORY_TYPE MemoryType, - IN PVOID VirtualAddress, - OUT PPECOFF_IMAGE_CONTEXT *Image); - -XTCDECL -EFI_STATUS -PeRelocateImage(IN PPECOFF_IMAGE_CONTEXT Image, - IN EFI_VIRTUAL_ADDRESS Address); - -XTCDECL -EFI_STATUS -PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image); - -XTCDECL -EFI_STATUS -PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, - IN PPECOFF_IMAGE_PE_HEADER PeHeader, - IN SIZE_T FileSize); - -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_MODULES_PECOFF_H */ diff --git a/xtldr/modules/pecoff/pecoff.c b/xtldr/modules/pecoff/pecoff.c deleted file mode 100644 index 8ec7bfb..0000000 --- a/xtldr/modules/pecoff/pecoff.c +++ /dev/null @@ -1,608 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff/pecoff.c - * DESCRIPTION: PE/COFF executable file format support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* EFI Image Handle */ -EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -PEFI_SYSTEM_TABLE EfiSystemTable; - -/* EFI XT Loader Protocol */ -PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; - -/* XTOS PE/COFF Image Protocol */ -XT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol; - -/** - * Returns the address of the entry point. - * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. - * - * @param EntryPoint - * A pointer to the memory area where address of the image entry point will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PeGetEntryPoint(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PVOID *EntryPoint) -{ - /* Validate input data */ - if(!Image || !Image->PeHeader) - { - /* Invalid parameter passed */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Get entry point and return success */ - *EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader.AddressOfEntryPoint; - return STATUS_EFI_SUCCESS; -} - -/** - * Returns the machine type of the PE/COFF image. - * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. - * - * @param MachineType - * A pointer to the memory area where a value defined for the 'machine' field will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PeGetMachineType(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PUSHORT MachineType) -{ - /* Validate input data */ - if(!Image || !Image->PeHeader) - { - /* Invalid parameter passed */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Get image machine type and return success */ - *MachineType = Image->PeHeader->FileHeader.Machine; - return STATUS_EFI_SUCCESS; -} - -/** - * Returns an information about subsystem that is required to run PE/COFF image. - * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. - * - * @param SubSystem - * A pointer to the memory area storing a value defined for the 'subsystem' field of the image. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PeGetSubSystem(IN PPECOFF_IMAGE_CONTEXT Image, - OUT PUSHORT SubSystem) -{ - /* Validate input data */ - if(!Image || !Image->PeHeader) - { - /* Invalid parameter passed */ - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Get image subsystem and return success */ - *SubSystem = Image->PeHeader->OptionalHeader.Subsystem; - return STATUS_EFI_SUCCESS; -} - -/** - * Loads a PE/COFF image file. - * - * @param FileHandle - * The handle of the opened portable executable (PE) file. - * - * @param MemoryType - * Supplies the type of memory to be assigned to the memory descriptor. - * - * @param VirtualAddress - * Optional virtual address pointing to the memory area where PE/COFF file will be loaded. - * - * @param Image - * Supplies pointer to the memory area where loaded PE/COFF image context will be stored. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, - IN LOADER_MEMORY_TYPE MemoryType, - IN PVOID VirtualAddress, - OUT PPECOFF_IMAGE_CONTEXT *Image) -{ - EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; - PPECOFF_IMAGE_SECTION_HEADER SectionHeader; - PPECOFF_IMAGE_CONTEXT ImageData; - EFI_PHYSICAL_ADDRESS Address; - PEFI_FILE_INFO FileInfo; - UINT_PTR ReadSize; - EFI_STATUS Status; - UINT SectionSize; - SIZE_T Pages; - PUCHAR Data; - UINT Index; - - /* Set required size for getting file information */ - ReadSize = sizeof(EFI_FILE_INFO) + 32; - - /* Allocate necessary amount of memory */ - Status = XtLdrProtocol->AllocatePool(ReadSize, (PVOID *)&FileInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n"); - return Status; - } - - /* First attempt to get file information */ - Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); - if(Status == STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Buffer it too small, but EFI tells the required size, let's reallocate */ - XtLdrProtocol->FreePool(&FileInfo); - Status = XtLdrProtocol->AllocatePool(ReadSize, (PVOID *)&FileInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n"); - return Status; - } - - /* Second attempt to get file information */ - Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); - } - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get file information */ - XtLdrProtocol->DbgPrint(L"ERROR: Failed to get file information\n"); - return Status; - } - - /* Allocate memory for storing image data */ - Status = XtLdrProtocol->AllocatePool(sizeof(PECOFF_IMAGE_CONTEXT), (PVOID *)&ImageData); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n"); - return Status; - } - - /* Store file size and memory type, nullify data and free up memory */ - ImageData->Data = NULL; - ImageData->FileSize = FileInfo->FileSize; - ImageData->MemoryType = MemoryType; - XtLdrProtocol->FreePool(FileInfo); - - /* Calculate number of pages */ - Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize); - - /* Allocate pages */ - Status = XtLdrProtocol->AllocatePages(Pages, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Pages allocation failure */ - XtLdrProtocol->DbgPrint(L"ERROR: Pages allocation failure\n"); - XtLdrProtocol->FreePool(ImageData); - return Status; - } - - /* Read PE/COFF image */ - ReadSize = Pages * EFI_PAGE_SIZE; - Data = (PUCHAR)(UINT_PTR)Address; - Status = FileHandle->Read(FileHandle, &ReadSize, Data); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read data */ - XtLdrProtocol->DbgPrint(L"ERROR: Unable to read PE/COFF image file\n"); - XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); - XtLdrProtocol->FreePool(ImageData); - return Status; - } - - /* Extract DOS and PE headers */ - ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data; - ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUINT8)Data + ImageData->DosHeader->e_lfanew); - - /* Validate headers */ - Status = PepValidateImageHeaders(ImageData->DosHeader, ImageData->PeHeader, ImageData->FileSize); - if(Status != STATUS_EFI_SUCCESS) - { - /* Header validation failed, probably broken or invalid PE/COFF image */ - XtLdrProtocol->DbgPrint(L"ERROR: Invalid PE/COFF image headers\n"); - XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); - XtLdrProtocol->FreePool(ImageData); - return Status; - } - - /* Make sure image is executable */ - if (!(ImageData->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_EXECUTABLE_IMAGE)) - { - /* Loaded image is not executable */ - XtLdrProtocol->DbgPrint(L"ERROR: Non-executable PE/COFF image loaded\n"); - XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); - XtLdrProtocol->FreePool(ImageData); - return STATUS_EFI_LOAD_ERROR; - } - - /* Store image size and calculate number of image pages */ - ImageData->ImageSize = ImageData->PeHeader->OptionalHeader.SizeOfImage; - ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize); - - /* Allocate image pages */ - Status = XtLdrProtocol->AllocatePages(ImageData->ImagePages, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Pages reallocation failure */ - XtLdrProtocol->DbgPrint(L"ERROR: Pages reallocation failure\n"); - XtLdrProtocol->FreePool(ImageData); - return Status; - } - - /* Store image data and virtual address */ - ImageData->Data = (PUINT8)(UINT_PTR)Address; - ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address; - if(VirtualAddress) - { - /* Virtual address passed to this routine */ - ImageData->VirtualAddress = VirtualAddress; - } - else - { - /* Virtual address not specified, use physical address */ - ImageData->VirtualAddress = (PVOID)(UINT_PTR)Address; - } - - /* Copy all sections */ - RtlCopyMemory(ImageData->Data, Data, ImageData->PeHeader->OptionalHeader.SizeOfHeaders); - - /* Find section header */ - SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&ImageData->PeHeader->OptionalHeader + - ImageData->PeHeader->FileHeader.SizeOfOptionalHeader); - - /* Load each section into memory */ - for(Index = 0; Index < ImageData->PeHeader->FileHeader.NumberOfSections; Index++) - { - /* Check section raw data size and section virtual size */ - if(SectionHeader[Index].SizeOfRawData < SectionHeader[Index].Misc.VirtualSize) - { - /* Use raw data size if it is smaller than virtual size */ - SectionSize = SectionHeader[Index].SizeOfRawData; - } - else - { - /* User virtual size otherwise */ - SectionSize = SectionHeader[Index].Misc.VirtualSize; - } - - /* Make sure section is available */ - if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0) - { - /* Copy section */ - RtlCopyMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress, - Data + SectionHeader[Index].PointerToRawData, SectionSize); - } - - /* Check if raw size is shorter than virtual size */ - if(SectionSize < SectionHeader[Index].Misc.VirtualSize) - { - /* Fill remaining space with zeroes */ - RtlZeroMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize, - SectionHeader[Index].Misc.VirtualSize - SectionSize); - } - } - - /* Free pages */ - XtLdrProtocol->FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages); - - /* Perform relocation fixups */ - Status = PepRelocateLoadedImage(ImageData); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to relocate image */ - XtLdrProtocol->DbgPrint(L"ERROR: PE/COFF image relocation failed\n"); - return Status; - } - - /* Store image data */ - *Image = ImageData; - - /* Return SUCCESS */ - return STATUS_EFI_SUCCESS; -} - -/** - * Relocates PE/COFF image to the specified address. - * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. - * - * @param Address - * Destination address of memory region, where image should be relocated. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PeRelocateImage(IN PPECOFF_IMAGE_CONTEXT Image, - IN EFI_VIRTUAL_ADDRESS Address) -{ - UINT64 ImageBase, OldVirtualAddress; - EFI_STATUS Status; - - /* Store original virtual address */ - OldVirtualAddress = (UINT_PTR)Image->VirtualAddress; - - /* Check PE/COFF image type */ - if(Image->PeHeader->OptionalHeader.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) - { - /* This is 64-bit PE32+, store its image base address */ - ImageBase = Image->PeHeader->OptionalHeader.ImageBase64; - } - else - { - /* This is 32-bit PE32, store its image base address */ - ImageBase = Image->PeHeader->OptionalHeader.ImageBase32; - } - - /* Overwrite virtual address and relocate image once again */ - Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase); - Status = PepRelocateLoadedImage(Image); - if(Status != STATUS_EFI_SUCCESS) - { - /* Relocation failed */ - return Status; - } - - /* Store new image virtual address */ - Image->VirtualAddress = (PVOID)Address; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Relocates a loaded PE/COFF image. - * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) -{ - PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory; - USHORT Offset, Type, Count; - PUSHORT TypeOffset; - UINT64 ImageBase; - PUINT32 Address; - PUINT64 LongPtr; - PUINT ShortPtr; - - /* Make sure image is not stripped */ - if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED) - { - /* No relocation information found */ - XtLdrProtocol->DbgPrint(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n"); - return STATUS_EFI_SUCCESS; - } - - /* Set relocation data directory */ - DataDirectory = &Image->PeHeader->OptionalHeader.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - - /* Check if loaded image should be relocated */ - if(Image->PeHeader->OptionalHeader.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC || - DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION)) - { - /* No need to relocate the image */ - return STATUS_EFI_SUCCESS; - } - - /* Check PE/COFF image type */ - if(Image->PeHeader->OptionalHeader.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) - { - /* This is 64-bit PE32+, store its image base address */ - ImageBase = Image->PeHeader->OptionalHeader.ImageBase64; - } - else - { - /* This is 32-bit PE32, store its image base address */ - ImageBase = Image->PeHeader->OptionalHeader.ImageBase32; - } - - /* Set relocation pointers */ - RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)Image->Data + DataDirectory->VirtualAddress); - RelocationEnd = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + DataDirectory->Size); - - /* Do relocations */ - while(RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) - { - /* Calculate number of relocations needed, address and type offset */ - Count = (RelocationDir->SizeOfBlock - sizeof(PECOFF_IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - Address = (PUINT)((PUCHAR)Image->Data + RelocationDir->VirtualAddress); - TypeOffset = (PUSHORT)((PUCHAR)RelocationDir + sizeof(PECOFF_IMAGE_BASE_RELOCATION)); - - /* Do relocations */ - while(Count--) - { - /* Calculate offset and relocation type */ - Offset = *TypeOffset & 0xFFF; - Type = *TypeOffset >> 12; - - /* Check if end of the loaded address reached */ - if((PVOID)(PUSHORT)(Address + Offset) >= Image->Data + Image->ImageSize) - { - /* Do not relocate after the end of loaded image */ - break; - } - - /* Make sure we are not going to relocate into .reloc section */ - if((ULONG_PTR)(Address + Offset) < (ULONG_PTR)RelocationDir || - (ULONG_PTR)(Address + Offset) >= (ULONG_PTR)RelocationEnd) - { - /* Apply relocation fixup */ - switch (Type) - { - case PECOFF_IMAGE_REL_BASED_ABSOLUTE: - /* No relocation required */ - break; - case PECOFF_IMAGE_REL_BASED_DIR64: - /* 64-bit relocation */ - LongPtr = (PULONGLONG)((PUCHAR)Address + Offset); - *LongPtr = *LongPtr - ImageBase + (UINT_PTR)Image->VirtualAddress; - break; - case PECOFF_IMAGE_REL_BASED_HIGHLOW: - /* 32-bit relocation of hight and low half of address */ - ShortPtr = (PUINT32)((PUCHAR)Address + Offset); - *ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress; - break; - default: - /* Unknown or unsupported relocation type */ - return STATUS_EFI_UNSUPPORTED; - } - } - /* Increment the type offset */ - TypeOffset++; - } - - /* Next relocation */ - RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((PUCHAR)RelocationDir + RelocationDir->SizeOfBlock); - } - - /* Return SUCCESS */ - return STATUS_EFI_SUCCESS; -} - -/** - * Validates a PE/COFF image headers. - * - * @param DosHeader - * Pointer to the memory area with DOS header stored. - * - * @param PeHeader - * Pointer to the memory area with PE header stored. - * - * @param FileSize - * A PE/COFF image file size. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, - IN PPECOFF_IMAGE_PE_HEADER PeHeader, - IN SIZE_T FileSize) -{ - /* Validate file size */ - if(FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER)) - { - XtLdrProtocol->DbgPrint(L"WARNING: PE/COFF image shorter than DOS header\n"); - return STATUS_EFI_END_OF_FILE; - } - - /* Validate DOS header */ - if(DosHeader->e_magic != PECOFF_IMAGE_DOS_SIGNATURE) - { - XtLdrProtocol->DbgPrint(L"WARNING: Invalid DOS signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Validate PE header */ - if(PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE && PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE) - { - XtLdrProtocol->DbgPrint(L"WARNING: Invalid NT/XT signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Validate optional header */ - if(PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC && - PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) - { - XtLdrProtocol->DbgPrint(L"WARNING: Invalid optional header signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine is the entry point of the XT EFI boot loader module. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param SystemTable - * Provides the EFI system table. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable) -{ - EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; - EFI_STATUS Status; - - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Open the XTLDR protocol */ - Status = BlGetXtLoaderProtocol(&XtLdrProtocol); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open loader protocol */ - return STATUS_EFI_PROTOCOL_ERROR; - } - - /* Set routines available via PE/COFF image protocol */ - XtPeCoffProtocol.GetEntryPoint = PeGetEntryPoint; - XtPeCoffProtocol.GetMachineType = PeGetMachineType; - XtPeCoffProtocol.GetSubSystem = PeGetSubSystem; - XtPeCoffProtocol.Load = PeLoadImage; - XtPeCoffProtocol.Relocate = PeRelocateImage; - - /* Register PE/COFF protocol */ - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, - &XtPeCoffProtocol); -} diff --git a/xtldr2/modules/pecoff_o/CMakeLists.txt b/xtldr/modules/pecoff_o/CMakeLists.txt similarity index 100% rename from xtldr2/modules/pecoff_o/CMakeLists.txt rename to xtldr/modules/pecoff_o/CMakeLists.txt diff --git a/xtldr2/modules/pecoff_o/includes/pecoff.h b/xtldr/modules/pecoff_o/includes/pecoff.h similarity index 100% rename from xtldr2/modules/pecoff_o/includes/pecoff.h rename to xtldr/modules/pecoff_o/includes/pecoff.h diff --git a/xtldr2/modules/pecoff_o/pecoff.c b/xtldr/modules/pecoff_o/pecoff.c similarity index 100% rename from xtldr2/modules/pecoff_o/pecoff.c rename to xtldr/modules/pecoff_o/pecoff.c diff --git a/xtldr/modules/xtos/CMakeLists.txt b/xtldr/modules/xtos/CMakeLists.txt deleted file mode 100644 index 695c2b6..0000000 --- a/xtldr/modules/xtos/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# XT Boot Loader -PROJECT(XTLDR_XTOS) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes - ${XTLDR_XTOS_SOURCE_DIR}/includes) - -# Specify list of source code files -list(APPEND XTLDR_XTOS_SOURCE - ${XTLDR_SOURCE_DIR}/blproto.c - ${XTLDR_XTOS_SOURCE_DIR}/xtos.c) - -# Link bootloader executable -add_executable(xtos ${XTLDR_XTOS_SOURCE}) - -# Add linker libraries -target_link_libraries(xtos libxtos) - -# Set proper binary name and install target -set_target_properties(xtos PROPERTIES SUFFIX .efi) -set_install_target(xtos efi/boot/xtldr) - -# Set module entrypoint and subsystem -set_entrypoint(xtos "BlXtLdrModuleMain") -set_subsystem(xtos efi_boot_service_driver) diff --git a/xtldr/modules/xtos/includes/xtos.h b/xtldr/modules/xtos/includes/xtos.h deleted file mode 100644 index 272b93f..0000000 --- a/xtldr/modules/xtos/includes/xtos.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/xtos/includes/xtos.h - * DESCRIPTION: XTOS boot protocol support header - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_XTOS_H -#define __XTLDR_MODULES_XTOS_H - -#include - - -/* EFI XT Loader Protocol */ -EXTERN PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; - -/* XTOS kernel entry point */ -typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); - -/* XTOS boot protocol related routines forward references */ -XTCDECL -EFI_STATUS -XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); - -XTCDECL -EFI_STATUS -XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, - IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); - - -XTCDECL -EFI_STATUS -XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings); - -XTCDECL -EFI_STATUS -XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, - IN PVOID *VirtualAddress); - -XTCDECL -EFI_STATUS -XtpLoadModule(IN PEFI_FILE_HANDLE BootDir, - IN PWCHAR FileName, - IN PVOID VirtualAddress, - IN LOADER_MEMORY_TYPE MemoryType, - OUT PPECOFF_IMAGE_CONTEXT *ImageContext); - -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_MODULES_XTOS_H */ diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c deleted file mode 100644 index c663e6a..0000000 --- a/xtldr/modules/xtos/xtos.c +++ /dev/null @@ -1,548 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/xtos/xtos.c - * DESCRIPTION: XTOS boot protocol support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* EFI Image Handle */ -EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -PEFI_SYSTEM_TABLE EfiSystemTable; - -/* EFI XT Loader Protocol */ -PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; - -/* XTOS PE/COFF Image Protocol */ -PXT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol; - -/* XTOS Boot Protocol */ -XT_BOOT_PROTOCOL XtBootProtocol; - -/* XTOS Page Map */ -PVOID XtPageMap; - -/** - * Starts the operating system according to the provided parameters using XTOS boot protocol. - * - * @param Parameters - * Input parameters with detailed system configuration like boot device or kernel path. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters) -{ - EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; - EFI_HANDLE DiskHandle; - PEFI_FILE_HANDLE FsHandle, BootDir; - PWCHAR SystemPath; - EFI_STATUS Status; - - /* Print debug message */ - XtLdrProtocol->DbgPrint(L"XTOS boot protocol activated\n"); - - /* Open the XT PE/COFF protocol */ - Status = BlLoadXtProtocol((PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open loader protocol */ - XtLdrProtocol->DbgPrint(L"ERROR: Unable to load PE/COFF image protocol\n"); - return STATUS_EFI_PROTOCOL_ERROR; - } - - /* Check device path */ - if(Parameters->DevicePath == NULL) - { - /* No device path set */ - XtLdrProtocol->DbgPrint(L"ERROR: No device path provided, unable to boot system\n"); - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Check if system path is set */ - if(Parameters->SystemPath != NULL) - { - /* Make sure system path begins with backslash, the only separator supported by EFI */ - if(Parameters->SystemPath[0] == '/') - { - /* Replace directory separator if needed */ - Parameters->SystemPath[0] = '\\'; - } - - /* Validate system path */ - SystemPath = &Parameters->SystemPath[1]; - while(*SystemPath) - { - /* Make sure it does not point to any subdirectory and not contains special characters */ - if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10)) - { - /* Invalid path specified */ - XtLdrProtocol->DbgPrint(L"ERROR: System path does not point to the valid XTOS installation\n"); - return STATUS_EFI_INVALID_PARAMETER; - } - /* Check next character in the path */ - SystemPath++; - } - } - else - { - /* Fallback to '/ExectOS' by default */ - XtLdrProtocol->DbgPrint(L"WARNING: No system path set, falling back to defaults\n"); - Parameters->SystemPath = L"\\ExectOS"; - } - - /* Check if kernel file is set */ - if(Parameters->KernelFile == NULL) - { - /* No kernel filename set, fallback to default */ - XtLdrProtocol->DbgPrint(L"WARNING: No kernel file specified, falling back to defaults\n"); - Parameters->KernelFile = L"xtoskrnl.exe"; - } - - /* Check if provided any kernel boot arguments */ - if(Parameters->Arguments == NULL) - { - /* No argument supplied */ - Parameters->Arguments = L""; - } - - /* Print a debug message */ - XtLdrProtocol->DbgPrint(L"[XTOS] ARC Path: %S\n" - L"[XTOS] System Path: %S\n" - L"[XTOS] Kernel File: %S\n" - L"[XTOS] Boot Arguments: %S\n", - Parameters->ArcName, Parameters->SystemPath, - Parameters->KernelFile, Parameters->Arguments); - - /* Open EFI volume */ - Status = XtLdrProtocol->OpenVolume(NULL, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open a volume */ - XtLdrProtocol->DbgPrint(L"ERROR: Unable to open boot volume\n"); - return Status; - } - - /* System path has to point to the boot directory */ - RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0); - - /* Open XTOS system boot directory */ - Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); - FsHandle->Close(FsHandle); - - /* Check if system path directory opened successfully */ - if(Status == STATUS_EFI_NOT_FOUND) - { - /* Directory not found, nothing to load */ - XtLdrProtocol->DbgPrint(L"ERROR: System boot directory not found\n"); - - /* Close volume */ - XtLdrProtocol->CloseVolume(DiskHandle); - return Status; - } - else if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - XtLdrProtocol->DbgPrint(L"ERROR: Unable to open system boot directory\n"); - XtLdrProtocol->CloseVolume(DiskHandle); - return Status; - } - - /* Start boot sequence */ - return XtpBootSequence(BootDir, Parameters); -} - -/** - * This routine initiates an XTOS boot sequence. - * - * @param BootDir - * An EFI handle to the XTOS boot directory. - * - * @param Parameters - * Input parameters with detailed system configuration like boot device or kernel path. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, - IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters) -{ - EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PKERNEL_INITIALIZATION_BLOCK KernelParameters; - PPECOFF_IMAGE_CONTEXT ImageContext = NULL; - PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; - PVOID VirtualAddress, VirtualMemoryArea; - PXT_ENTRY_POINT KernelEntryPoint; - LIST_ENTRY MemoryMappings; - EFI_STATUS Status; - - /* Initialize XTOS startup sequence */ - XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n"); - - /* Set base virtual memory area for the kernel mappings */ - VirtualMemoryArea = (PVOID)KSEG0_BASE; - VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE); - - /* Initialize memory mapping linked list */ - RtlInitializeListHead(&MemoryMappings); - - /* Initialize virtual memory mappings */ - Status = XtLdrProtocol->InitializeVirtualMemory(&MemoryMappings, &VirtualMemoryArea); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to initialize virtual memory */ - return Status; - } - - /* Load the kernel */ - Status = XtpLoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load the kernel */ - return Status; - } - - /* Add kernel image memory mapping */ - Status = XtLdrProtocol->AddVirtualMemoryMapping(&MemoryMappings, ImageContext->VirtualAddress, - ImageContext->PhysicalAddress, ImageContext->ImagePages, 0); - if(Status != STATUS_EFI_SUCCESS) - { - return Status; - } - - /* Set next valid virtual address right after the kernel */ - VirtualAddress += ImageContext->ImagePages * EFI_PAGE_SIZE; - - /* Store virtual address of kernel initialization block for future kernel call */ - KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress; - - /* Setup and map kernel initialization block */ - Status = XtpInitializeLoaderBlock(&MemoryMappings, &VirtualAddress); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to setup kernel initialization block */ - XtLdrProtocol->DbgPrint(L"Failed to setup kernel initialization block (Status Code: %lx)\n", Status); - return Status; - } - - /* Find and map APIC base address */ - Status = XtpInitializeApicBase(&MemoryMappings); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to setup kernel initialization block */ - XtLdrProtocol->DbgPrint(L"Failed to initialize APIC (Status Code: %lx)\n", Status); - return Status; - } - - /* Get kernel entry point */ - XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint); - - /* Close boot directory handle */ - BootDir->Close(BootDir); - - /* Enable paging */ - EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageGuid, (PVOID*)&ImageProtocol); - Status = XtLdrProtocol->EnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to enable paging */ - XtLdrProtocol->DbgPrint(L"Failed to enable paging (Status Code: %lx)\n", Status); - return Status; - } - - /* Call XTOS kernel */ - XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n"); - KernelEntryPoint(KernelParameters); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Checks if APIC is present in the system and finds its base address. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @return This routine returns an EFI status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings) -{ - PCPUID_REGISTERS CpuRegisters = NULL; - PVOID ApicBaseAddress; - - /* Get CPU features list */ - CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; - CpuRegisters->SubLeaf = 0; - CpuRegisters->Eax = 0; - CpuRegisters->Ebx = 0; - CpuRegisters->Ecx = 0; - CpuRegisters->Edx = 0; - ArCpuId(CpuRegisters); - - /* Check if APIC is present */ - if((CpuRegisters->Edx & CPUID_FEATURES_EDX_APIC) == 0) - { - /* APIC is not supported by the CPU */ - return STATUS_EFI_UNSUPPORTED; - } - - /* Get APIC base address */ - ApicBaseAddress = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000); - - /* Map APIC base address */ - XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent); - return STATUS_EFI_SUCCESS; -} - -/** - * Initializes and maps the kernel initialization block. - * - * @param MemoryMappings - * Supplies a pointer to linked list containing all memory mappings. - * - * @param VirtualAddress - * Supplies a pointer to the next valid, free and available virtual address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, - IN PVOID *VirtualAddress) -{ - EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID; - PXT_FRAMEBUFFER_PROTOCOL FrameBufProtocol; - PKERNEL_INITIALIZATION_BLOCK LoaderBlock; - EFI_PHYSICAL_ADDRESS Address; - PVOID RuntimeServices; - EFI_STATUS Status; - UINT BlockPages, FrameBufferPages; - - /* Calculate number of pages needed for initialization block */ - BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); - - /* Allocate memory for kernel initialization block */ - Status = XtLdrProtocol->AllocatePages(BlockPages, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Initialize and zero-fill kernel initialization block */ - LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; - RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK)); - - /* Set basic loader block properties */ - LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK); - LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION; - LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION; - - /* Set LoaderInformation block properties */ - LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->DbgPrint; - - /* Load FrameBuffer protocol */ - Status = BlLoadXtProtocol((PVOID *)&FrameBufProtocol, &FrameBufGuid); - if(Status == STATUS_EFI_SUCCESS) - { - /* Make sure FrameBuffer is initialized */ - FrameBufProtocol->Initialize(); - FrameBufProtocol->PrintDisplayInformation(); - - /* Store information about FrameBuffer device */ - FrameBufProtocol->GetDisplayInformation(&LoaderBlock->LoaderInformation.FrameBuffer); - } - else - { - /* No FrameBuffer available */ - LoaderBlock->LoaderInformation.FrameBuffer.Initialized = FALSE; - LoaderBlock->LoaderInformation.FrameBuffer.Protocol = NONE; - } - - /* Attempt to find virtual address of the EFI Runtime Services */ - Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); - if(Status == STATUS_EFI_SUCCESS) - { - /* Set FirmwareInformation block properties */ - LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; - LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision; - LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = RuntimeServices; - } - else - { - /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */ - LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid; - } - - /* Map kernel initialization block */ - XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock, - BlockPages, LoaderSystemBlock); - - /* Calculate next valid virtual address */ - *VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); - - /* Check if framebuffer initialized */ - if(LoaderBlock->LoaderInformation.FrameBuffer.Initialized) - { - /* Calculate pages needed to map framebuffer */ - FrameBufferPages = EFI_SIZE_TO_PAGES(LoaderBlock->LoaderInformation.FrameBuffer.BufferSize); - - /* Map frame buffer memory */ - XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, - LoaderBlock->LoaderInformation.FrameBuffer.Address, - FrameBufferPages, LoaderFirmwarePermanent); - - /* Rewrite framebuffer address by using virtual address */ - LoaderBlock->LoaderInformation.FrameBuffer.Address = *VirtualAddress; - - /* Calcualate next valid virtual address */ - *VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE); - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Loads XTOS PE/COFF module. - * - * @param SystemDir - * An EFI handle to the opened system directory containing a module that will be loaded. - * - * @param FileName - * An on disk filename of the module that will be loaded. - * - * @param VirtualAddress - * Optional virtual address pointing to the memory area where PE/COFF file will be loaded. - * - * @param MemoryType - * Supplies the type of memory to be assigned to the memory descriptor. - * - * @param ImageContext - * Supplies pointer to the memory area where loaded PE/COFF image context will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, - IN PWCHAR FileName, - IN PVOID VirtualAddress, - IN LOADER_MEMORY_TYPE MemoryType, - OUT PPECOFF_IMAGE_CONTEXT *ImageContext) -{ - PEFI_FILE_HANDLE ModuleHandle; - USHORT MachineType, SubSystem; - EFI_STATUS Status; - - /* Print debug message */ - XtLdrProtocol->DbgPrint(L"Loading %S ... \n", FileName); - - /* Open module file */ - Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to open the file */ - XtLdrProtocol->DbgPrint(L"ERROR: Failed to open '%S'\n", FileName); - return Status; - } - - /* Load the PE/COFF image file */ - Status = XtPeCoffProtocol->Load(ModuleHandle, MemoryType, VirtualAddress, ImageContext); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to load the file */ - XtLdrProtocol->DbgPrint(L"ERROR: Failed to load '%S'\n", FileName); - return Status; - } - - /* Close image file */ - ModuleHandle->Close(ModuleHandle); - - /* Check PE/COFF image machine type compatibility */ - XtPeCoffProtocol->GetMachineType(*ImageContext, &MachineType); - if(MachineType != _ARCH_IMAGE_MACHINE_TYPE) - { - /* Machine type mismatch */ - XtLdrProtocol->DbgPrint(L"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Check PE/COFF image subsystem */ - XtPeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem); - if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL && - SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION && - SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER) - { - XtLdrProtocol->DbgPrint(L"WARNING: Loaded PE/COFF image with non-XT subsystem set\n"); - } - - /* Print debug message */ - XtLdrProtocol->DbgPrint(L"Loaded %S at PA: 0x%lx, VA: 0x%lx\n", FileName, - (*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine is the entry point of the XT EFI boot loader module. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param SystemTable - * Provides the EFI system table. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable) -{ - EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; - EFI_STATUS Status; - - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Open the XTLDR protocol */ - Status = BlGetXtLoaderProtocol(&XtLdrProtocol); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open loader protocol */ - return STATUS_EFI_PROTOCOL_ERROR; - } - - /* Set routines available via XTOS boot protocol */ - XtBootProtocol.BootSystem = XtBootSystem; - - /* Register XTOS boot protocol */ - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, - &XtBootProtocol); -} diff --git a/xtldr2/modules/xtos_o/CMakeLists.txt b/xtldr/modules/xtos_o/CMakeLists.txt similarity index 100% rename from xtldr2/modules/xtos_o/CMakeLists.txt rename to xtldr/modules/xtos_o/CMakeLists.txt diff --git a/xtldr2/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.c similarity index 100% rename from xtldr2/modules/xtos_o/amd64/memory.c rename to xtldr/modules/xtos_o/amd64/memory.c diff --git a/xtldr2/modules/xtos_o/i686/memory.c b/xtldr/modules/xtos_o/i686/memory.c similarity index 100% rename from xtldr2/modules/xtos_o/i686/memory.c rename to xtldr/modules/xtos_o/i686/memory.c diff --git a/xtldr2/modules/xtos_o/includes/xtos.h b/xtldr/modules/xtos_o/includes/xtos.h similarity index 100% rename from xtldr2/modules/xtos_o/includes/xtos.h rename to xtldr/modules/xtos_o/includes/xtos.h diff --git a/xtldr2/modules/xtos_o/memory.c b/xtldr/modules/xtos_o/memory.c similarity index 100% rename from xtldr2/modules/xtos_o/memory.c rename to xtldr/modules/xtos_o/memory.c diff --git a/xtldr2/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c similarity index 100% rename from xtldr2/modules/xtos_o/xtos.c rename to xtldr/modules/xtos_o/xtos.c diff --git a/xtldr2/protocol.c b/xtldr/protocol.c similarity index 100% rename from xtldr2/protocol.c rename to xtldr/protocol.c diff --git a/xtldr2/shell.c b/xtldr/shell.c similarity index 100% rename from xtldr2/shell.c rename to xtldr/shell.c diff --git a/xtldr/string.c b/xtldr/string.c index c555999..f082232 100644 --- a/xtldr/string.c +++ b/xtldr/string.c @@ -2,73 +2,17 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/string.c - * DESCRIPTION: EFI string operations support + * DESCRIPTION: EFI string manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include -/** - * Compares two strings without sensitivity to case. - * - * @param String1 - * First string to be compared. - * - * @param String2 - * Second string to be compared. - * - * @return This routine returns a value indicating the relationship between the two strings. - * - * @since XT 1.0 - */ -XTCDECL -INT -BlStringCompareInsensitive(IN PUCHAR String1, - IN PUCHAR String2) -{ - UCHAR Character1; - UCHAR Character2; - ULONG Index = 0; - - /* Iterate through the strings */ - while(String1[Index] != '\0' && String2[Index] != '\0') - { - /* Get the characters */ - Character1 = String1[Index]; - Character2 = String2[Index]; - - /* Lowercase string1 character if needed */ - if(String1[Index] >= 'A' && String1[Index] <= 'Z') - { - Character1 = String1[Index] - 'A' + 'a'; - } - - /* Lowercase string2 character if needed */ - if(String2[Index] >= 'A' && String2[Index] <= 'Z') - { - Character2 = String2[Index] - 'A' + 'a'; - } - - /* Compare the characters */ - if(Character1 != Character2) - { - /* Strings are not equal */ - return Character1 > Character2 ? 1 : -1; - } - - /* Get next character */ - Index++; - } - - /* Strings are equal */ - return 0; -} - /** * This routine formats the input string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Format @@ -83,9 +27,9 @@ BlStringCompareInsensitive(IN PUCHAR String1, */ XTCDECL VOID -BlStringPrint(IN VOID PutChar(IN USHORT Character), - IN PUINT16 Format, - IN VA_LIST Arguments) +BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, + IN PUINT16 Format, + IN VA_LIST Arguments) { PEFI_GUID Guid; PUCHAR String; @@ -102,20 +46,20 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), { case L'b': /* Boolean */ - BlpStringFormat(PutChar, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); + BlpStringFormat(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); break; case L'c': /* Character */ - PutChar(VA_ARG(Arguments, INT)); + PrintCharRoutine(VA_ARG(Arguments, INT)); break; case L'd': /* Signed 32-bit integer */ - BlpStringPrintSigned32(PutChar, VA_ARG(Arguments, INT32), 10); + BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); break; case L'g': /* EFI GUID */ Guid = VA_ARG(Arguments, PEFI_GUID); - BlpStringFormat(PutChar, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, + BlpStringFormat(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]); break; @@ -125,48 +69,48 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), { case L'd': /* Signed 64-bit integer */ - BlpStringPrintSigned64(PutChar, VA_ARG(Arguments, INT_PTR), 10); + BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); break; case L'u': /* Unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 10, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); break; case L'x': /* Unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); break; default: /* Unknown by default */ - PutChar(L'?'); + PrintCharRoutine(L'?'); break; } break; case L'p': /* Pointer address */ - BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); break; case L's': /* String of characters */ String = VA_ARG(Arguments, PUCHAR); while(*String) { - PutChar(*String++); + PrintCharRoutine(*String++); } break; case L'S': WideString = VA_ARG(Arguments, PWCHAR); while(*WideString) { - PutChar((UCHAR)*WideString++); + PrintCharRoutine((UCHAR)*WideString++); } break; case L'u': /* Unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 10, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0); break; case L'x': /* Unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 16, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0); break; case L'0': /* Zero padded numbers */ @@ -176,7 +120,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), { case L'd': /* Zero-padded, signed 32-bit integer */ - BlpStringPrintSigned32(PutChar, VA_ARG(Arguments, INT32), 10); + BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); break; case L'l': /* 64-bit numbers */ @@ -184,43 +128,43 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), { case L'd': /* Zero-padded, signed 64-bit integer */ - BlpStringPrintSigned64(PutChar, VA_ARG(Arguments, INT_PTR), 10); + BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); break; case L'u': /* Zero-padded, unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); break; case L'x': /* Zero-padded, unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); + BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); break; default: /* Unknown by default */ - PutChar(L'?'); + PrintCharRoutine(L'?'); break; } break; case L'u': /* Zero-padded, unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 10, PaddingCount); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount); break; case L'x': /* Zero-padded, unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 16, PaddingCount); + BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount); break; default: /* Unknown by default */ - PutChar(L'?'); + PrintCharRoutine(L'?'); break; } break; case L'%': /* Percent character */ - PutChar(L'%'); + PrintCharRoutine(L'%'); break; default: /* Unknown by default */ - PutChar(L'?'); + PrintCharRoutine(L'?'); break; } break; @@ -229,12 +173,12 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), break; case L'\n': /* New line together with carriage return */ - PutChar(L'\r'); - PutChar(L'\n'); + PrintCharRoutine(L'\r'); + PrintCharRoutine(L'\n'); break; default: /* Put character by default */ - PutChar(*Format); + PrintCharRoutine(*Format); break; } } @@ -243,7 +187,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), /** * This routine formats the input string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Format @@ -258,7 +202,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character), */ XTCDECL VOID -BlpStringFormat(IN VOID PutChar(IN USHORT Character), +BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...) { @@ -268,7 +212,7 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character), VA_START(Arguments, Format); /* Format and print the string to the desired output */ - BlStringPrint(PutChar, Format, Arguments); + BlpStringPrint(PrintCharRoutine, Format, Arguments); /* Clean up the va_list */ VA_END(Arguments); @@ -277,7 +221,7 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character), /** * This routine converts 32-bit integer as string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Number @@ -292,25 +236,25 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character), */ XTCDECL VOID -BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character), - IN INT32 Number, - IN UINT32 Base) +BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, + IN INT Number, + IN UINT Base) { /* Print - (minus) if this is negative value */ if(Number < 0) { - PutChar(L'-'); + PrintCharRoutine(L'-'); Number *= -1; } /* Print the integer value */ - BlpStringPrintUnsigned32(PutChar, Number, Base, 0); + BlpStringPrintUnsigned32(PrintCharRoutine, Number, Base, 0); } /** * This routine converts 64-bit integer as string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Number @@ -325,25 +269,25 @@ BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character), */ XTCDECL VOID -BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character), +BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, IN INT_PTR Number, IN UINT_PTR Base) { /* Print - (minus) if this is negative value */ if(Number < 0) { - PutChar(L'-'); + PrintCharRoutine(L'-'); Number *= -1; } /* Print the integer value */ - BlpStringPrintUnsigned64(PutChar, Number, Base, 0); + BlpStringPrintUnsigned64(PrintCharRoutine, Number, Base, 0); } /** * This routine converts 32-bit unsigned integer as string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Number @@ -361,23 +305,27 @@ BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character), */ XTCDECL VOID -BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character), - IN UINT32 Number, - IN UINT32 Base, - IN UINT32 Padding) +BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, + IN UINT Number, + IN UINT Base, + IN UINT Padding) { - UINT32 Buffer[20]; - PUINT32 Pointer = Buffer + ARRAY_SIZE(Buffer); + UINT Buffer[20]; + UINT NumberLength; + PUINT Pointer; + + /* Set pointer to the end of buffer */ + Pointer = Buffer + ARRAY_SIZE(Buffer); /* Convert value to specified base system */ *--Pointer = 0; do { - *--Pointer = EfiHexTable[Number % Base]; + *--Pointer = BlpHexTable[Number % Base]; } while(Pointer >= Buffer && (Number /= Base)); /* Calculate number length */ - UINT32 NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; + NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; /* Check if leading zeros are needed */ if(NumberLength < Padding) @@ -386,21 +334,21 @@ BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character), while(Padding--) { /* Write leading zeroes */ - PutChar(L'0'); + PrintCharRoutine(L'0'); } } /* Print value to the console */ for(; *Pointer; ++Pointer) { - PutChar(*Pointer); + PrintCharRoutine(*Pointer); } } /** * This routine converts 64-bit unsigned integer as string and prints it using specified routine. * - * @param PutChar + * @param PrintCharRoutine * Pointer to the routine that writes an input data to specific device. * * @param Number @@ -418,23 +366,27 @@ BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character), */ XTCDECL VOID -BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character), +BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, IN UINT_PTR Number, IN UINT_PTR Base, IN UINT_PTR Padding) { UINT16 Buffer[20]; - PUINT16 Pointer = Buffer + ARRAY_SIZE(Buffer); + UINT_PTR NumberLength; + PUINT16 Pointer; + + /* Set pointer to the end of buffer */ + Pointer = Buffer + ARRAY_SIZE(Buffer); /* Convert value to specified base system */ *--Pointer = 0; do { - *--Pointer = EfiHexTable[Number % Base]; + *--Pointer = BlpHexTable[Number % Base]; } while(Pointer >= Buffer && (Number /= Base)); /* Calculate number length */ - UINT_PTR NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; + NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; /* Check if leading zeros are needed */ if(NumberLength < Padding) @@ -443,14 +395,14 @@ BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character), while(Padding--) { /* Write leading zeroes */ - PutChar(L'0'); + PrintCharRoutine(L'0'); } } /* Print value to the console */ for(; *Pointer; ++Pointer) { - PutChar(*Pointer); + PrintCharRoutine(*Pointer); } } diff --git a/xtldr/system.c b/xtldr/system.c deleted file mode 100644 index 52b83da..0000000 --- a/xtldr/system.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/system.c - * DESCRIPTION: EFI system information - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * This routine checks whether SecureBoot is enabled or not. - * - * @return Numeric representation of SecureBoot status (0 = Disabled, >0 = Enabled, <0 SetupMode). - * - * @since XT 1.0 - */ -XTCDECL -INT_PTR -BlEfiGetSecureBootStatus() -{ - EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; - INT_PTR SecureBootStatus = 0; - UCHAR VarValue = 0; - UINT_PTR Size; - - Size = sizeof(VarValue); - if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid, - NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) - { - SecureBootStatus = (INT_PTR)VarValue; - - if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid, - NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0) - { - SecureBootStatus = -1; - } - } - - /* Return SecureBoot status */ - return SecureBootStatus; -} - -/** - * Read system configuration from a specified table. - * - * @param TableGuid - * Supplies a pointer to the GUID to search for. - * - * @param Table - * Supplies a pointer that will point to the configuration table. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEfiGetSystemConfigurationTable(IN PEFI_GUID TableGuid, - OUT PVOID *Table) -{ - SIZE_T Size = sizeof(EFI_GUID); - UINT_PTR Index; - - for(Index = 0; Index < EfiSystemTable->NumberOfTableEntries; Index++) - { - if(RtlCompareMemory((PVOID)&EfiSystemTable->ConfigurationTable[Index].VendorGuid, TableGuid, Size) == Size) - { - *Table = EfiSystemTable->ConfigurationTable[Index].VendorTable; - return STATUS_EFI_SUCCESS; - } - } - - /* Table not found */ - return STATUS_EFI_NOT_FOUND; -} diff --git a/xtldr2/textui.c b/xtldr/textui.c similarity index 100% rename from xtldr2/textui.c rename to xtldr/textui.c diff --git a/xtldr/volume.c b/xtldr/volume.c index c6609cf..32cfed7 100644 --- a/xtldr/volume.c +++ b/xtldr/volume.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -45,7 +45,7 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle) */ XTCDECL EFI_STATUS -BlEnumerateEfiBlockDevices() +BlEnumerateBlockDevices() { PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; @@ -70,7 +70,7 @@ BlEnumerateEfiBlockDevices() Status = BlpDiscoverEfiBlockDevices(&BlockDevices); if(Status != STATUS_EFI_SUCCESS) { - BlDbgPrint(L"ERROR: Failed to discover EFI block devices (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%lx)\n", Status); return Status; } @@ -82,16 +82,16 @@ BlEnumerateEfiBlockDevices() BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); /* Find last node */ - Status = BlpFindLastEfiBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); + Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); if(Status != STATUS_EFI_SUCCESS) { - BlDbgPrint(L"WARNING: Block device last node not found\n"); + BlDebugPrint(L"WARNING: Block device last node not found\n"); ListEntry = ListEntry->Flink; continue; } /* Set drive type to 'unknown' by default */ - DriveType = XT_BOOT_DEVICE_UNKNOWN; + DriveType = XTBL_BOOT_DEVICE_UNKNOWN; /* Check last node type */ if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP) @@ -102,12 +102,12 @@ BlEnumerateEfiBlockDevices() { /* Floppy drive found */ Media = BlockDeviceData->BlockIo->Media; - DriveType = XT_BOOT_DEVICE_FLOPPY; + DriveType = XTBL_BOOT_DEVICE_FLOPPY; DriveNumber = FDCount++; PartitionNumber = 0; /* Print debug message */ - BlDbgPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", + BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", DriveNumber, Media->MediaPresent, Media->ReadOnly); } } @@ -118,12 +118,12 @@ BlEnumerateEfiBlockDevices() { /* Optical drive found */ Media = BlockDeviceData->BlockIo->Media; - DriveType = XT_BOOT_DEVICE_CDROM; + DriveType = XTBL_BOOT_DEVICE_CDROM; DriveNumber = CDCount++; PartitionNumber = 0; /* Print debug message */ - BlDbgPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", + BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); } else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) @@ -131,13 +131,13 @@ BlEnumerateEfiBlockDevices() /* Hard disk partition found */ Media = BlockDeviceData->BlockIo->Media; HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode; - DriveType = XT_BOOT_DEVICE_HARDDISK; + DriveType = XTBL_BOOT_DEVICE_HARDDISK; DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1; PartitionNumber = HDPath->PartitionNumber; PartitionGuid = (PEFI_GUID)HDPath->Signature; /* Print debug message */ - BlDbgPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " + BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " L"MBRType: %u, GUID: {%g}, PartSize: %luB)\n", DriveNumber, PartitionNumber, HDPath->MBRType, PartitionGuid, HDPath->PartitionSize * Media->BlockSize); @@ -146,30 +146,30 @@ BlEnumerateEfiBlockDevices() { /* RAM disk found */ Media = BlockDeviceData->BlockIo->Media; - DriveType = XT_BOOT_DEVICE_RAMDISK; + DriveType = XTBL_BOOT_DEVICE_RAMDISK; DriveNumber = RDCount++; PartitionNumber = 0; /* Print debug message */ - BlDbgPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", + BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", DriveNumber, Media->MediaPresent); } - if(!BlpFindParentEfiBlockDevice(&BlockDevices, BlockDeviceData, ParentNode)) + if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode)) { - BlDbgPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); + BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); continue; } } /* Make sure the device found has valid type set */ - if(DriveType != XT_BOOT_DEVICE_UNKNOWN) + if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) { /* Allocate memory for block device */ - Status = BlEfiMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); + Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { - BlDbgPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); return STATUS_EFI_OUT_OF_RESOURCES; } @@ -248,7 +248,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); /* Allocate memory pool for device path */ - Status = BlEfiMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), + Status = BlMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), (PVOID *)DevicePath); if(Status != STATUS_EFI_SUCCESS) { @@ -294,16 +294,16 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, */ XTCDECL EFI_STATUS -BlGetVolumeDevicePath(IN PUCHAR SystemPath, +BlGetVolumeDevicePath(IN PWCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PUCHAR *ArcName, - OUT PUCHAR *Path) + OUT PWCHAR *ArcName, + OUT PWCHAR *Path) { PEFI_BLOCK_DEVICE Device; USHORT DriveType; ULONG DriveNumber; ULONG PartNumber; - PUCHAR Volume; + PWCHAR Volume; ULONG PathLength; PLIST_ENTRY ListEntry; EFI_STATUS Status; @@ -333,13 +333,13 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath, if(PathLength == GUID_STRING_LENGTH) { /* This is EFI GUID */ - BlDbgPrint(L"EFI/GPT GUID in system path is not supported yet\n"); + BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else if(PathLength == PARTUUID_STRING_LENGTH) { /* This is MBR UUID */ - BlDbgPrint(L"MBR partition UUID in system path is not supported yet\n"); + BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else @@ -358,7 +358,7 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse system path */ - BlDbgPrint(L"Failed to parse system path: '%s' with status code: %lx\n", SystemPath, Status); + BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%lx)\n", SystemPath, Status); return Status; } @@ -382,7 +382,7 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath, if(*DevicePath == NULL) { /* Failed to find volume */ - BlDbgPrint(L"Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", + BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", DriveType, DriveNumber, PartNumber); return STATUS_EFI_NOT_FOUND; } @@ -470,6 +470,125 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, return STATUS_EFI_SUCCESS; } +/** + * Reads data from the file. + * + * @param DirHandle + * Supplies a handle of the opened filesystem directory. + * + * @param FileName + * Supplies the name of the file to read. + * + * @param FileData + * Provides a buffer to store the data read from the file. + * + * @param FileSize + * Provides a pointer to the variable to store a size of the buffer. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN CONST PWCHAR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize) +{ + EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; + EFI_PHYSICAL_ADDRESS Address; + PEFI_FILE_HANDLE FileHandle; + PEFI_FILE_INFO FileInfo; + EFI_STATUS Status; + UINT_PTR ReadSize; + SIZE_T Pages; + + Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ, + EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open file */ + return Status; + } + + /* Set required size for getting file information */ + ReadSize = sizeof(EFI_FILE_INFO) + 32; + + /* Allocate necessary amount of memory */ + Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + FileHandle->Close(FileHandle); + return Status; + } + + /* First attempt to get file information */ + FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + if(Status == STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Buffer is too small, but EFI tells the required size, so reallocate */ + BlMemoryFreePool(&FileInfo); + Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + FileHandle->Close(FileHandle); + return Status; + } + + /* Second attempt to get file information */ + Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); + } + + /* Check if file information got successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get file information */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + return Status; + } + + /* Store file size and calculate number of pages */ + *FileSize = FileInfo->FileSize; + Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); + + /* Allocate pages */ + Status = BlMemoryAllocatePages(Pages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Pages allocation failure */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + return Status; + } + + /* Calculate number of bytes to read and zero memory*/ + ReadSize = Pages * EFI_PAGE_SIZE; + *FileData = (PCHAR)(UINT_PTR)Address; + RtlZeroMemory(*FileData, ReadSize); + + /* Read data from the file */ + Status = FileHandle->Read(FileHandle, &ReadSize, *FileData); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read data */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + BlMemoryFreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); + return Status; + } + + /* Close handle and free memory */ + FileHandle->Close(FileHandle); + BlMemoryFreePool(&FileInfo); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Gets a list of block devices from an EFI enabled BIOS. * @@ -498,7 +617,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS) { /* Failed to locate handles */ - BlDbgPrint(L"ERROR: Failed to locate block devices handles (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%lx)\n", Status); return Status; } @@ -506,7 +625,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) for(Index = 0; Index < HandlesCount; Index++) { /* Print debug message */ - BlDbgPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); + BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); /* Open I/O protocol for given handle */ Io = NULL; @@ -515,7 +634,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS || Io == NULL) { /* Failed to open I/O protocol, skip it */ - BlDbgPrint(L"WARNING: Failed to open EFI Block I/O protocol (status code: %lx)\n", Status); + BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%lx)\n", Status); continue; } @@ -523,7 +642,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) { /* Skip stub as it is non-functional */ - BlDbgPrint(L"WARNING: iPXE stub block I/O protocol"); + BlDebugPrint(L"WARNING: iPXE stub block I/O protocol"); continue; } @@ -533,17 +652,17 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) { /* Device failed to handle DP protocol */ - BlDbgPrint(L"WARNING: Unable to open DevicePath protocol (status code: %lx)\n", Status); + BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%lx)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); continue; } /* Allocate memory for block device */ - Status = BlEfiMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); + Status = BlMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - BlDbgPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); return Status; @@ -556,7 +675,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) } /* Free handles buffer */ - BlEfiMemoryFreePool(Handles); + BlMemoryFreePool(Handles); /* Return success */ return STATUS_EFI_SUCCESS; @@ -586,36 +705,36 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) */ XTCDECL EFI_STATUS -BlpDissectVolumeArcPath(IN PUCHAR SystemPath, - OUT PUCHAR *ArcName, - OUT PUCHAR *Path, +BlpDissectVolumeArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, OUT PUSHORT DriveType, OUT PULONG DriveNumber, OUT PULONG PartNumber) { - PUCHAR ArcPath, LocalArcName; + PWCHAR ArcPath, LocalArcName; ULONG ArcLength = 0; /* Set default values */ - *DriveType = XT_BOOT_DEVICE_UNKNOWN; + *DriveType = XTBL_BOOT_DEVICE_UNKNOWN; *DriveNumber = 0; *PartNumber = 0; /* Look for the ARC path */ - if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"ramdisk(0)") == 0) + if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0) { /* This is RAM disk */ ArcLength = 10; - *DriveType = XT_BOOT_DEVICE_RAMDISK; + *DriveType = XTBL_BOOT_DEVICE_RAMDISK; } - else if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"multi(0)disk(0)") == 0) + else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) { /* This is a multi-disk port */ ArcLength = 15; ArcPath = SystemPath + ArcLength; /* Check for disk type */ - if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"cdrom(") == 0) + if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0) { /* This is an optical drive */ ArcLength += 6; @@ -633,10 +752,10 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath, } /* Set proper drive type */ - *DriveType = XT_BOOT_DEVICE_CDROM; + *DriveType = XTBL_BOOT_DEVICE_CDROM; ArcLength++; } - else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"fdisk(") == 0) + else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) { /* This is a floppy drive */ ArcLength += 6; @@ -654,10 +773,10 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath, } /* Set proper drive type */ - *DriveType = XT_BOOT_DEVICE_FLOPPY; + *DriveType = XTBL_BOOT_DEVICE_FLOPPY; ArcLength++; } - else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"rdisk(") == 0) + else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) { /* This is a hard disk */ ArcLength += 6; @@ -675,12 +794,12 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath, } /* Set proper drive type */ - *DriveType = XT_BOOT_DEVICE_HARDDISK; + *DriveType = XTBL_BOOT_DEVICE_HARDDISK; ArcLength++; ArcPath = SystemPath + ArcLength; /* Look for a partition */ - if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"partition(") == 0) + if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) { /* Partition information found */ ArcLength += 10; @@ -720,8 +839,8 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath, /* Store ARC name if possible */ if(ArcName) { - BlEfiMemoryAllocatePool(ArcLength, (PVOID *)&LocalArcName); - RtlCopyMemory(LocalArcName, SystemPath, ArcLength); + BlMemoryAllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); + RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); LocalArcName[ArcLength] = '\0'; *ArcName = LocalArcName; } @@ -770,11 +889,11 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) } /* Allocate memory for the new device path */ - Status = BlEfiMemoryAllocatePool(Length, (PVOID *)&DevicePathClone); + Status = BlMemoryAllocatePool(Length, (PVOID *)&DevicePathClone); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ - BlDbgPrint(L"ERROR: Unable to allocate memory pool for device path duplicate\n"); + BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%lx)\n", Status); return NULL; } @@ -800,8 +919,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) */ XTCDECL EFI_STATUS -BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) +BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) { PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; @@ -846,9 +965,9 @@ BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL BOOLEAN -BlpFindParentEfiBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA ParentNode) +BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA ParentNode) { PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; PEFI_BLOCK_DEVICE_DATA BlockDeviceData; diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index dd9abee..85e7902 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -2,216 +2,160 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/xtldr.c - * DESCRIPTION: UEFI XT Bootloader + * DESCRIPTION: XTOS UEFI Boot Loader * DEVELOPERS: Rafal Kupiec */ -#include +#include /** - * This routine loads XTLDR EFI modules. + * Initializes EFI Boot Loader (XTLDR). * - * @return This routine returns status code. + * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL -EFI_STATUS -BlLoadEfiModules() +VOID +BlInitializeBootLoader() { - CONST PWCHAR ModulesDirPath = L"\\EFI\\BOOT\\XTLDR\\"; - EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_DEVICE_PATH_PROTOCOL VolumeDevicePath, DevicePath; + EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - PEFI_FILE_HANDLE FsHandle, ModulesDir; - EFI_HANDLE DiskHandle, ModuleHandle; - SIZE_T Length; EFI_STATUS Status; - UINT_PTR DirSize; - CHAR Buffer[1024]; - WCHAR ModulePath[1024]; - PWCHAR ModuleName; - /* Open EFI volume */ - Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) + /* Set current XTLDR's EFI BootServices status */ + BlpStatus.BootServices = TRUE; + + /* Initialize console */ + BlpInitializeConsole(); + + /* Print XTLDR version */ + BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + + /* Initialize XTLDR configuration linked lists */ + RtlInitializeListHead(&BlpBootProtocols); + RtlInitializeListHead(&BlpConfig); + RtlInitializeListHead(&BlpLoadedModules); + + /* Store SecureBoot status */ + BlpStatus.SecureBoot = BlGetSecureBootStatus(); + + /* Check if debug is enabled */ + if(DEBUG) { - /* Failed to open a volume */ - return Status; + /* Attempt to open EFI LoadedImage protocol */ + Status = BlOpenProtocol((PVOID *)&LoadedImage, &LipGuid); + if(Status == STATUS_EFI_SUCCESS) + { + /* Protocol opened successfully, print useful debug information */ + BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" + L"Pointer Size : %d\n" + L"Image Base Address: 0x%lx\n" + L"Image Base Size : 0x%lx\n" + L"Image Revision : 0x%lx\n" + L"--------------------------------------\n", + sizeof(PVOID), + LoadedImage->ImageBase, + LoadedImage->ImageSize, + LoadedImage->Revision); + BlSleepExecution(3000); + } } - - /* Open EFI/BOOT/XTLDR directory, which contains all the modules and close the FS immediately */ - Status = FsHandle->Open(FsHandle, &ModulesDir, ModulesDirPath, EFI_FILE_MODE_READ, 0); - FsHandle->Close(FsHandle); - - /* Check if modules directory opened successfully */ - if(Status == STATUS_EFI_NOT_FOUND) - { - /* Directory not found, nothing to load */ - BlDbgPrint(L"WARNING: Boot loader directory (EFI/BOOT/XTLDR) not found\n"); - - /* Close volume */ - BlCloseVolume(DiskHandle); - return STATUS_EFI_SUCCESS; - } - else if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - BlDbgPrint(L"ERROR: Unable to open XTLDR directory (EFI/BOOT/XTLDR)\n"); - BlCloseVolume(DiskHandle); - return Status; - } - - /* Open EFI device path protocol */ - Status = EfiSystemTable->BootServices->HandleProtocol(DiskHandle, &DevicePathGuid, (PVOID *)&DevicePath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Close volume */ - BlCloseVolume(DiskHandle); - return Status; - } - - /* Iterate through files inside XTLDR directory */ - while(TRUE) - { - /* Read directory */ - DirSize = sizeof(Buffer); - Status = ModulesDir->Read(ModulesDir, &DirSize, Buffer); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read directory */ - BlDbgPrint(L"\n"); - - /* Close directory and volume */ - ModulesDir->Close(ModulesDir); - BlCloseVolume(DiskHandle); - return Status; - } - - /* Check if read anything */ - if(DirSize == 0) - { - /* Already read all contents, break loop execution */ - break; - } - - /* Take filename and its length */ - ModuleName = ((PEFI_FILE_INFO)Buffer)->FileName; - Length = RtlWideStringLength(ModuleName, 0); - - /* Make sure we deal with .EFI executable file */ - if(Length < 4 || ModuleName[Length - 4] != '.' || - (ModuleName[Length - 3] != 'E' && ModuleName[Length - 3] != 'e') || - (ModuleName[Length - 2] != 'F' && ModuleName[Length - 2] != 'f') || - (ModuleName[Length - 1] != 'I' && ModuleName[Length - 1] != 'i')) - { - /* Skip non .EFI file */ - continue; - } - - /* Print debug message */ - BlDbgPrint(L"Loading module '%S' ... ", ModuleName); - - /* Set correct path to the module file */ - RtlCopyMemory(ModulePath, ModulesDirPath, sizeof(ModulePath) / sizeof(WCHAR)); - RtlConcatenateWideString(ModulePath, ModuleName, 0); - - /* Find valid device path */ - Status = BlFindVolumeDevicePath(DevicePath, ModulePath, &VolumeDevicePath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to set path */ - BlDbgPrint(L"FAIL\n"); - BlDbgPrint(L"ERROR: Unable to set valid device path\n"); - - /* Close directory and volume */ - ModulesDir->Close(ModulesDir); - BlCloseVolume(DiskHandle); - return Status; - } - - /* Load the module into memory */ - Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, VolumeDevicePath, - NULL, 0, &ModuleHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Module failed */ - BlDbgPrint(L"FAIL\n"); - - /* Check if caused by secure boot */ - if(Status == STATUS_EFI_ACCESS_DENIED && EfiSecureBoot >= 1) - { - BlDbgPrint(L"ERROR: SecureBoot signature validation failed\n"); - } - else - { - BlDbgPrint(L"ERROR: Unable to load module (Status code: %lx)\n", Status); - } - - /* Free memory and skip module */ - BlEfiMemoryFreePool(VolumeDevicePath); - continue; - } - - /* Free memory */ - BlEfiMemoryFreePool(VolumeDevicePath); - - /* Access module interface for further module type check */ - Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open protocol */ - BlDbgPrint(L"FAIL\n"); - BlDbgPrint(L"ERROR: Unable to access module interface\n"); - - /* Skip to the next module */ - continue; - } - - /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ - if(LoadedImage->ImageCodeType != EfiBootServicesCode) - { - /* Different type set, probably 'runtime driver', refuse to load it */ - BlDbgPrint(L"FAIL\n"); - BlDbgPrint(L"ERROR: Loaded module is not a boot system driver\n"); - - /* Close protocol and skip module */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - continue; - } - - /* Close loaded image protocol */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - - /* Start the module */ - Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Module failed */ - BlDbgPrint(L"FAIL\n"); - BlDbgPrint(L"ERROR: Unable to start module\n"); - - /* Skip module */ - continue; - } - - /* Module loaded successfully */ - BlDbgPrint(L"OK\n"); - } - - /* Close directory and volume */ - ModulesDir->Close(ModulesDir); - BlCloseVolume(DiskHandle); - - /* Return success */ - return STATUS_EFI_SUCCESS; } /** - * This routine attempts to start XT Operating System. + * Initializes a list of operating systems for XTLDR boot menu. + * + * @param MenuEntries + * Supplies a pointer to memory area where operating systems list will be stored. + * + * @param EntriesCount + * Supplies a pointer to memory area where number of menu entries will be stored. + * + * @param DefaultId + * Supplies a pointer to memory area where ID of default menu entry will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId) +{ + PWCHAR DefaultMenuEntry, MenuEntryName; + PLIST_ENTRY MenuEntrySectionList, MenuEntryList; + PXTBL_CONFIG_SECTION MenuEntrySection; + PXTBL_CONFIG_ENTRY MenuEntryOption; + PXTBL_BOOTMENU_ITEM OsList; + ULONG DefaultOS, NumberOfEntries; + + /* Set default values */ + DefaultOS = 0; + NumberOfEntries = 0; + OsList = NULL; + + /* Get default menu entry from configuration */ + DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); + + /* Iterate through all menu sections */ + MenuEntrySectionList = BlpMenuList->Flink; + while(MenuEntrySectionList != BlpMenuList) + { + /* NULLify menu entry name */ + MenuEntryName = NULL; + + /* Get menu section */ + MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); + + /* Check if this is the default menu entry */ + if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0) + { + /* Set default OS ID */ + DefaultOS = NumberOfEntries; + } + + /* Iterate through all entry parameters */ + MenuEntryList = MenuEntrySection->Options.Flink; + while(MenuEntryList != &MenuEntrySection->Options) + { + /* Get menu entry parameter */ + MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); + + /* Check if this is the menu entry display name */ + if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) + { + /* Set menu entry display name */ + MenuEntryName = MenuEntryOption->Value; + } + + /* Get next parameter for this menu entry */ + MenuEntryList = MenuEntryList->Flink; + } + + /* Add OS to the boot menu list */ + OsList[NumberOfEntries].EntryName = MenuEntryName; + OsList[NumberOfEntries].Options = &MenuEntrySection->Options; + + /* Get next menu entry */ + MenuEntrySectionList = MenuEntrySectionList->Flink; + NumberOfEntries++; + } + + /* Set return values */ + *DefaultId = DefaultOS; + *EntriesCount = NumberOfEntries; + MenuEntries = OsList; +} + +/** + * Loads all necessary modules and invokes boot protocol. + * + * @param OptionsList + * Supplies a pointer to list of options associated with chosen boot menu entry. * * @return This routine returns a status code. * @@ -219,90 +163,117 @@ BlLoadEfiModules() */ XTCDECL EFI_STATUS -BlLoadXtSystem() +BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) { - EFI_GUID ProtocolGuid = XT_XTOS_BOOT_PROTOCOL_GUID; - XT_BOOT_PROTOCOL_PARAMETERS BootParameters; - PXT_BOOT_PROTOCOL BootProtocol; - PUCHAR ArcName, SystemPath; + XTBL_BOOT_PARAMETERS BootParameters; + PXTBL_BOOT_PROTOCOL BootProtocol; + PLIST_ENTRY OptionsListEntry; + PXTBL_CONFIG_ENTRY Option; + EFI_GUID BootProtocolGuid; + SIZE_T ModuleListLength; + PWCHAR ModulesList; EFI_STATUS Status; - PCHAR ArcPath; - SIZE_T Length; - /* Set ARC path */ - ArcPath = "multi(0)disk(0)rdisk(0)partition(1)/ExectOS"; + /* Initialize boot parameters and a list of modules */ + RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); + ModulesList = NULL; - /* Zero boot parameters structure to NULLify all pointers */ - RtlZeroMemory(&BootParameters, sizeof(XT_BOOT_PROTOCOL_PARAMETERS)); - - /* Get boot volume path */ - Status = BlGetVolumeDevicePath((PUCHAR)ArcPath, &BootParameters.DevicePath, &ArcName, &SystemPath); - if(Status != STATUS_EFI_SUCCESS) + /* Iterate through all options provided by boot menu entry and propagate boot parameters */ + OptionsListEntry = OptionsList->Flink; + while(OptionsListEntry != OptionsList) { - /* Failed to find volume */ - BlDbgPrint(L"ERROR: Unable to find volume device path\n"); - return Status; + /* Get option */ + Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Look for boot protocol and modules list */ + if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) + { + /* Check a length of modules list */ + ModuleListLength = RtlWideStringLength(Option->Value, 0); + + Status = BlMemoryAllocatePool(sizeof(PWCHAR) * ModuleListLength, (PVOID *)&ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory, print error message and return status code */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n"); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Make a copy of modules list */ + RtlCopyMemory(ModulesList, Option->Value, sizeof(PWCHAR) * ModuleListLength); + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) + { + /* Boot protocol found */ + BootParameters.SystemType = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) + { + /* System path found, get volume device path */ + Status = BlGetVolumeDevicePath((PWCHAR)Option->Value, &BootParameters.DevicePath, &BootParameters.ArcName, &BootParameters.SystemPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to find volume */ + BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%lx)\n", Status); + return Status; + } + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) + { + /* Kernel file name found */ + BootParameters.KernelFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) + { + /* Initrd file name found */ + BootParameters.InitrdFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) + { + /* Hal file name found */ + BootParameters.HalFile = Option->Value; + } + else if(RtlCompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) + { + /* Kernel parameters found */ + BootParameters.Parameters = Option->Value; + } + + /* Move to the next option entry */ + OptionsListEntry = OptionsListEntry->Flink; } - /* Store ARC name in boot parameters */ - Length = RtlStringLength(ArcName, 0); - BlEfiMemoryAllocatePool(Length + 1, (PVOID *)&BootParameters.ArcName); - RtlStringToWideString(BootParameters.ArcName, &ArcName, Length * 2); + /* Load all necessary modules */ + Status = BlLoadModules(ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load modules, print error message and return status code */ + BlDebugPrint(L"ERROR: Failed to load XTLDR modules\n"); + return STATUS_EFI_NOT_READY; + } - /* Store system path in boot parameters */ - Length = RtlStringLength(SystemPath, 0); - BlEfiMemoryAllocatePool(Length + 1, (PVOID *)&BootParameters.SystemPath); - RtlStringToWideString(BootParameters.SystemPath, &SystemPath, Length + 1); + /* Attempt to get boot protocol GUID */ + Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get boot protocol GUID */ + BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%lx)\n", Status); + return STATUS_EFI_UNSUPPORTED; + } - /* Open the XT boot protocol */ - Status = BlLoadXtProtocol((PVOID *)&BootProtocol, &ProtocolGuid); + /* Open boot protocol */ + Status = BlOpenProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open boot protocol */ - BlDbgPrint(L"ERROR: Unable to load boot protocol\n"); - return STATUS_EFI_PROTOCOL_ERROR; + BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%lx)\n", Status); + return Status; } - /* Boot operating system */ + /* Boot Operating System */ return BootProtocol->BootSystem(&BootParameters); } -/** - * This routine registers XTLDR protocol for further usage by modules. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlRegisterXtLoaderProtocol() -{ - EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; - EFI_HANDLE Handle = NULL; - - /* Set all routines available via loader protocol */ - EfiLdrProtocol.AddVirtualMemoryMapping = BlAddVirtualMemoryMapping; - EfiLdrProtocol.AllocatePages = BlEfiMemoryAllocatePages; - EfiLdrProtocol.AllocatePool = BlEfiMemoryAllocatePool; - EfiLdrProtocol.FreePages = BlEfiMemoryFreePages; - EfiLdrProtocol.FreePool = BlEfiMemoryFreePool; - EfiLdrProtocol.EnablePaging = BlEnablePaging; - EfiLdrProtocol.GetMemoryMap = BlGetMemoryMap; - EfiLdrProtocol.GetVirtualAddress = BlGetVirtualAddress; - EfiLdrProtocol.InitializeVirtualMemory = BlInitializeVirtualMemory; - EfiLdrProtocol.MapVirtualMemory = BlMapVirtualMemory; - EfiLdrProtocol.DbgPrint = BlDbgPrint; - EfiLdrProtocol.EfiPrint = BlEfiPrint; - EfiLdrProtocol.CloseVolume = BlCloseVolume; - EfiLdrProtocol.OpenVolume = BlOpenVolume; - - /* Register loader protocol */ - BlDbgPrint(L"Registering XT loader protocol\n"); - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, - &EfiLdrProtocol); -} - /** * This routine is the entry point of the XT EFI boot loader. * @@ -327,71 +298,136 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; - /* Initialize EFI console */ - BlConsoleInitialize(); - BlEfiPrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + /* Initialize XTLDR and */ + BlInitializeBootLoader(); - /* Early initialize COM port for debugging */ + /* Parse configuration options passed from UEFI shell */ + Status = BlpParseCommandLine(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to parse command line options */ + BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); + } + + /* Attempt to early initialize debug console */ if(DEBUG) { - Status = BlComPortInitialize(); + Status = BlpInitializeDebugConsole(); if(Status != STATUS_EFI_SUCCESS) { - /* Initialization failed, try printing error to stdout and serial console */ - BlEfiPrint(L"ERROR: Failed to initialize serial console\n"); + /* Initialization failed, notify user on stdout */ + BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); } } - /* Check SecureBoot status */ - EfiSecureBoot = BlEfiGetSecureBootStatus(); + /* Load XTLDR configuration file */ + Status = BlpLoadConfiguration(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load/parse config file */ + BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file."); + } - /* Print firmware information */ - BlDbgPrint(L"UEFI v%d.%d (%S 0x%08x), SecureBoot %S\n", EfiSystemTable->Hdr.Revision >> 16, - EfiSystemTable->Hdr.Revision & 0xFFFF, EfiSystemTable->FirmwareVendor, EfiSystemTable->FirmwareRevision, - EfiSecureBoot == 0 ? L"DISABLED" : EfiSecureBoot > 0 ? L"ENABLED" : L"SETUP"); + /* Reinitialize debug console if it was not initialized earlier */ + if(DEBUG) + { + Status = BlpInitializeDebugConsole(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Initialization failed, notify user on stdout */ + BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); + } + } /* Disable watchdog timer */ Status = EfiSystemTable->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULL); if(Status != STATUS_EFI_SUCCESS) { /* Failed to disable the timer, print message */ - BlDbgPrint(L"WARNING: Failed to disable watchdog timer\n"); + BlDebugPrint(L"WARNING: Failed to disable watchdog timer\n"); } /* Register loader protocol */ - Status = BlRegisterXtLoaderProtocol(); + Status = BlpRegisterXtLoaderProtocol(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to register loader protocol */ - BlDbgPrint(L"ERROR: Failed to register XTLDR loader protocol\n"); + BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol\n"); + return Status; } - /* Load XTLDR modules */ - Status = BlLoadEfiModules(); + /* Load boot loader modules */ + Status = BlLoadModules(BlGetConfigValue(L"MODULES")); if(Status != STATUS_EFI_SUCCESS) { - BlDbgPrint(L"ERROR: Failed to load XTLDR modules\n"); + /* Failed to load modules */ + BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status); + BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); } /* Discover and enumerate EFI block devices */ - BlEnumerateEfiBlockDevices(); - - /* Boot XTOS */ - Status = BlLoadXtSystem(); + Status = BlEnumerateBlockDevices(); if(Status != STATUS_EFI_SUCCESS) { - /* Boot process failed */ - BlEfiPrint(L"Failed to start XT OS (Status code: %lx)!\n", Status); + /* Failed to enumerate block devices */ + BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); + return Status; } - /* Infinite bootloader loop */ - BlEfiPrint(L"System halted!"); - for(;;) + + // BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); + // PLIST_ENTRY ModuleListEntry; + // PXTBL_MODULE_INFO ModuleInfo; + + // ModuleListEntry = BlpLoadedModules.Flink; + // while(ModuleListEntry != &BlpLoadedModules) + // { + // /* Get module information */ + // ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + // /* Module already loaded */ + // BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); + // if(ModuleInfo->ModuleDescription != 0) + // { + // BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); + // } + + // PLIST_ENTRY DepsListEntry; + // PXTBL_MODULE_DEPS DepsInfo; + // BlConsolePrint(L"\n - Uses: "); + // DepsListEntry = ModuleInfo->Dependencies.Flink; + // while(DepsListEntry != &ModuleInfo->Dependencies) + // { + // DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); + // BlConsolePrint(L"%S ", DepsInfo->ModuleName); + // DepsListEntry = DepsListEntry->Flink; + // } + + // /* Move to the module */ + // ModuleListEntry = ModuleListEntry->Flink; + // } + + // BlConsolePrint(L"\n\n END OF LIST\n"); + + /* Main boot loader loop */ + while(TRUE) { - ArClearInterruptFlag(); - ArHalt(); + /* Check if custom boot menu registered */ + if(BlpStatus.BootMenu != NULL) + { + /* Display alternative boot menu */ + BlpStatus.BootMenu(); + } + else + { + /* Display default boot menu */ + BlDisplayBootMenu(); + } + + /* Fallback to shell, if boot menu returned */ + BlStartLoaderShell(); } - /* Return success */ - return STATUS_EFI_SUCCESS; + /* This point should be never reached, if this happen return error code */ + return STATUS_EFI_LOAD_ERROR; } diff --git a/xtldr2/CMakeLists.txt b/xtldr2/CMakeLists.txt deleted file mode 100644 index 275b9ff..0000000 --- a/xtldr2/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# XT Boot Manager -PROJECT(XTLDR) - -# Build XTLDR modules -add_subdirectory(modules) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes) - -# Specify list of library source code files -list(APPEND LIBXTLDR_SOURCE - ${XTLDR_SOURCE_DIR}/library/modproto.c) - -# Specify list of source code files -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}/shell.c - ${XTLDR_SOURCE_DIR}/string.c - ${XTLDR_SOURCE_DIR}/textui.c - ${XTLDR_SOURCE_DIR}/volume.c - ${XTLDR_SOURCE_DIR}/xtldr.c) - -# Link static XTLDR library -add_library(libxtldr ${LIBXTLDR_SOURCE}) - -# Link bootloader executable -add_executable(xtldr ${XTLDR_SOURCE}) - -# Add linker libraries -target_link_libraries(xtldr libxtos) - -# Set proper binary name and install target -if(ARCH STREQUAL "i686") - set(BINARY_NAME "bootia32") -elseif(ARCH STREQUAL "amd64") - set(BINARY_NAME "bootx64") -endif() -set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi) -set_install_target(xtldr efi/boot) - -# Set loader entrypoint and subsystem -set_entrypoint(xtldr "BlStartXtLoader") -set_imagebase(xtldr ${BASEADDRESS_XTLDR}) -set_linker_map(xtldr TRUE) -set_subsystem(xtldr efi_application) diff --git a/xtldr2/README.md b/xtldr2/README.md deleted file mode 100644 index ae4fe9f..0000000 --- a/xtldr2/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## XT Boot Manager (XTLDR) -The XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS. -As an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems, -like old and deprecated BIOS. - -One of the notable features of XTLDR is its modular design. The boot loader is divided into different modules, with only -the essential core being loaded during the boot process. This modular approach allows for a more efficient and -streamlined boot experience, as only the necessary functionality is loaded, reducing the boot time and system resource -usage. - -XTLDR includes various modules that provide specific functionalities required for the boot process. For example, there is -a module dedicated to supporting the XTOS boot protocol, which is the specific protocol used by XTOS for loading and -executing the OS kernel. Additionally, there is a module for handling PE/COFF (Portable Executable) binaries, which is -a commonly used format of executable files used by the XTOS. diff --git a/xtldr2/console.c b/xtldr2/console.c deleted file mode 100644 index e41b8ce..0000000 --- a/xtldr2/console.c +++ /dev/null @@ -1,297 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/console.c - * DESCRIPTION: EFI console support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Clears a specified line on the UEFI text console. - * - * @param LineNo - * Supplies a line number to clear. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlClearConsoleLine(IN ULONGLONG LineNo) -{ - UINT_PTR Index, ResX, ResY; - - /* Query console mode */ - BlQueryConsoleMode(&ResX, &ResY); - - /* Set cursor position and clear line */ - BlSetCursorPosition(0, LineNo); - for(Index = 0; Index < ResX; Index++) - { - /* Clear line */ - BlConsoleWrite(L" "); - } -} - -/** - * This routine clears the UEFI console screen. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlClearConsoleScreen() -{ - /* Clear screen */ - EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); -} - -/** - * Disables the cursor on the UEFI console. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlDisableConsoleCursor() -{ - EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); -} - -/** - * Enables the cursor on the UEFI console. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlEnableConsoleCursor() -{ - EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); -} - -/** - * This routine formats the input string and prints it out to the stdout and serial console. - * - * @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 -BlConsolePrint(IN PUINT16 Format, - IN ...) -{ - VA_LIST Arguments; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Format and print the string to the stdout */ - BlpStringPrint(BlpConsolePrintChar, Format, Arguments); - - /* Print to serial console only if not running under OVMF */ - if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) - { - /* Check if debugging enabled and if EFI serial port is fully initialized */ - if(DEBUG && (BlpStatus.SerialPort.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); -} - -/** - * Displays the string on the device at the current cursor location. - * - * @param String - * The string to be displayed. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlConsoleWrite(IN PUSHORT String) -{ - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); -} - -/** - * Queries information concerning the output device’s supported text mode. - * - * @param ResX - * Supplies a buffer to receive the horizontal resolution. - * - * @param ResY - * Supplies a buffer to receive the vertical resolution. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlQueryConsoleMode(OUT PUINT_PTR ResX, - OUT PUINT_PTR ResY) -{ - EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); -} - -/** - * Reads a keystroke from the input device. - * - * @param Key - * Supplies a pointer to the EFI_INPUT_KEY structure that will receive the keystroke. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) -{ - EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); -} - -/** - * Resets the console input device and clears its input buffer. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlResetConsoleInputBuffer() -{ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); -} - -/** - * Sets the foreground and background colors. - * - * @param Attribute - * Specifies the foreground and background colors (bits 0..3 are fg, and bits 4..6 are bg color). - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlSetConsoleAttributes(IN ULONGLONG Attributes) -{ - EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); -} - -/** - * Sets the output console device to the requested mode. - * - * @param Mode - * Supplies a text mode number to set. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlSetConsoleMode(IN ULONGLONG Mode) -{ - return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode); -} - -/** - * Sets new coordinates of the console cursor position. - * - * @param PosX - * Specifies the new X coordinate of the cursor. - * - * @param PosY - * Specifies the new Y coordinate of the cursor. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlSetCursorPosition(IN ULONGLONG PosX, - IN ULONGLONG PosY) -{ - EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); -} - -/** - * Writes a character to the default EFI 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 -BlpConsolePrintChar(IN USHORT Character) -{ - USHORT Buffer[2]; - - /* Write character to the screen console */ - Buffer[0] = Character; - Buffer[1] = 0; - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); -} - -/** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpInitializeConsole() -{ - /* Clear console buffers */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); - EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); - EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); - - /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might - * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ - if(EfiSystemTable->ConOut->Mode->Mode != 0) - { - /* Set console mode to 0, which is standard, 80x25 text mode */ - BlSetConsoleMode(0); - } - - /* Clear screen and enable cursor */ - BlClearConsoleScreen(); - BlEnableConsoleCursor(); -} diff --git a/xtldr2/globals.c b/xtldr2/globals.c deleted file mode 100644 index 4a6a286..0000000 --- a/xtldr2/globals.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/globals.c - * DESCRIPTION: XT Boot Loader global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* XT Boot Loader registered boot protocol list */ -LIST_ENTRY BlpBootProtocols; - -/* XT Boot Loader configuration list */ -LIST_ENTRY BlpConfig; - -/* XT Boot Loader loaded configuration */ -LIST_ENTRY BlpConfigSections; - -/* XT Boot Loader hex table */ -STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF"; - -/* XT Boot Loader protocol */ -XTBL_LOADER_PROTOCOL BlpLdrProtocol; - -/* XT Boot Loader loaded modules list */ -LIST_ENTRY BlpLoadedModules; - -/* XT Boot Loader menu list */ -PLIST_ENTRY BlpMenuList = NULL; - -/* XT Boot Loader status data */ -XTBL_STATUS BlpStatus = {0}; - -/* List of available block devices */ -LIST_ENTRY EfiBlockDevices; - -/* EFI Image Handle */ -EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -PEFI_SYSTEM_TABLE EfiSystemTable; diff --git a/xtldr2/memory.c b/xtldr2/memory.c deleted file mode 100644 index 8df0448..0000000 --- a/xtldr2/memory.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/memory.c - * DESCRIPTION: XT Boot Loader memory management - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI. - * - * @param MemoryMap - * Supplies a pointer to the buffer where memory map will be written. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) -{ - EFI_STATUS Status; - - if(MemoryMap == NULL) - { - return STATUS_EFI_INVALID_PARAMETER; - } - - MemoryMap->Map = NULL; - MemoryMap->MapSize = 0; - - /* Get memory map */ - do - { - /* Attempt do get EFI memory map */ - Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMap->MapSize, MemoryMap->Map, &MemoryMap->MapKey, - &MemoryMap->DescriptorSize, &MemoryMap->DescriptorVersion); - if(Status == STATUS_EFI_SUCCESS) - { - /* Go further if succeeded */ - break; - } - else if(Status != STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Some error occurred */ - if(MemoryMap->Map) - { - /* Free allocated memory */ - BlMemoryFreePool(MemoryMap->Map); - } - return Status; - } - - /* Allocate the desired amount of memory */ - MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; - BlMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); - } - while(Status == STATUS_EFI_BUFFER_TOO_SMALL); - - /* Make sure memory map is set */ - if(MemoryMap->Map == NULL) - { - /* Something went wrong */ - return STATUS_EFI_NO_MAPPING; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine allocates one or more 4KB pages. - * - * @param Pages - * The number of contiguous 4KB pages to allocate. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMemoryAllocatePages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); -} - -/** - * This routine allocates a pool memory. - * - * @param Size - * The number of bytes to allocate from the pool. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory) -{ - /* Allocate pool */ - return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); -} - -/** - * This routine frees memory pages. - * - * @param Pages - * The number of contiguous 4 KB pages to free. - * - * @param Memory - * The base physical address of the pages to be freed. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMemoryFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->FreePages(Memory, Pages); -} - -/** - * Returns pool memory to the system. - * - * @param Memory - * The pointer to the buffer to free. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMemoryFreePool(IN PVOID Memory) -{ - /* Free pool */ - return EfiSystemTable->BootServices->FreePool(Memory); -} diff --git a/xtldr2/modules/CMakeLists.txt b/xtldr2/modules/CMakeLists.txt deleted file mode 100644 index 136fbbb..0000000 --- a/xtldr2/modules/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_subdirectory(dummy) -add_subdirectory(fb_o) -add_subdirectory(pecoff_o) -add_subdirectory(xtos_o) diff --git a/xtldr2/string.c b/xtldr2/string.c deleted file mode 100644 index f082232..0000000 --- a/xtldr2/string.c +++ /dev/null @@ -1,444 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/string.c - * DESCRIPTION: EFI string manipulation support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * This routine formats the input string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Format - * The formatted string that is to be written to the specified device. - * - * @param Arguments - * A value identifying a variable arguments list initialized with VA_START. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN VA_LIST Arguments) -{ - PEFI_GUID Guid; - PUCHAR String; - PWCHAR WideString; - ULONG PaddingCount; - - /* Read the variable arguments */ - for(; *Format; ++Format) - { - switch(*Format) - { - case L'%': - switch(*++Format) - { - case L'b': - /* Boolean */ - BlpStringFormat(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE"); - break; - case L'c': - /* Character */ - PrintCharRoutine(VA_ARG(Arguments, INT)); - break; - case L'd': - /* Signed 32-bit integer */ - BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); - break; - case L'g': - /* EFI GUID */ - Guid = VA_ARG(Arguments, PEFI_GUID); - BlpStringFormat(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, - Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], - Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]); - break; - case L'l': - /* 64-bit numbers */ - switch(*++Format) - { - case L'd': - /* Signed 64-bit integer */ - BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); - break; - case L'u': - /* Unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); - break; - case L'x': - /* Unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'p': - /* Pointer address */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); - break; - case L's': - /* String of characters */ - String = VA_ARG(Arguments, PUCHAR); - while(*String) - { - PrintCharRoutine(*String++); - } - break; - case L'S': - WideString = VA_ARG(Arguments, PWCHAR); - while(*WideString) - { - PrintCharRoutine((UCHAR)*WideString++); - } - break; - case L'u': - /* Unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0); - break; - case L'x': - /* Unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0); - break; - case L'0': - /* Zero padded numbers */ - ++Format; - PaddingCount = BlpStringReadPadding(&Format); - switch(*Format) - { - case L'd': - /* Zero-padded, signed 32-bit integer */ - BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10); - break; - case L'l': - /* 64-bit numbers */ - switch(*++Format) - { - case L'd': - /* Zero-padded, signed 64-bit integer */ - BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); - break; - case L'u': - /* Zero-padded, unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); - break; - case L'x': - /* Zero-padded, unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'u': - /* Zero-padded, unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount); - break; - case L'x': - /* Zero-padded, unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'%': - /* Percent character */ - PrintCharRoutine(L'%'); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'\r': - /* Carriage return is ignored */ - break; - case L'\n': - /* New line together with carriage return */ - PrintCharRoutine(L'\r'); - PrintCharRoutine(L'\n'); - break; - default: - /* Put character by default */ - PrintCharRoutine(*Format); - break; - } - } -} - -/** - * This routine formats the input string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Format - * The formatted string that is to be written to the specified device. - * - * @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 -BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, - IN PUINT16 Format, - IN ...) -{ - VA_LIST Arguments; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Format and print the string to the desired output */ - BlpStringPrint(PrintCharRoutine, Format, Arguments); - - /* Clean up the va_list */ - VA_END(Arguments); -} - -/** - * This routine converts 32-bit integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 32-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, - IN INT Number, - IN UINT Base) -{ - /* Print - (minus) if this is negative value */ - if(Number < 0) - { - PrintCharRoutine(L'-'); - Number *= -1; - } - - /* Print the integer value */ - BlpStringPrintUnsigned32(PrintCharRoutine, Number, Base, 0); -} - -/** - * This routine converts 64-bit integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 64-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, - IN INT_PTR Number, - IN UINT_PTR Base) -{ - /* Print - (minus) if this is negative value */ - if(Number < 0) - { - PrintCharRoutine(L'-'); - Number *= -1; - } - - /* Print the integer value */ - BlpStringPrintUnsigned64(PrintCharRoutine, Number, Base, 0); -} - -/** - * This routine converts 32-bit unsigned integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 32-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @param Padding - * Specifies the number of leading zeros to complete the field width. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, - IN UINT Number, - IN UINT Base, - IN UINT Padding) -{ - UINT Buffer[20]; - UINT NumberLength; - PUINT Pointer; - - /* Set pointer to the end of buffer */ - Pointer = Buffer + ARRAY_SIZE(Buffer); - - /* Convert value to specified base system */ - *--Pointer = 0; - do - { - *--Pointer = BlpHexTable[Number % Base]; - } while(Pointer >= Buffer && (Number /= Base)); - - /* Calculate number length */ - NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; - - /* Check if leading zeros are needed */ - if(NumberLength < Padding) - { - Padding -= NumberLength; - while(Padding--) - { - /* Write leading zeroes */ - PrintCharRoutine(L'0'); - } - } - - /* Print value to the console */ - for(; *Pointer; ++Pointer) - { - PrintCharRoutine(*Pointer); - } -} - -/** - * This routine converts 64-bit unsigned integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 64-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @param Padding - * Specifies the number of leading zeros to complete the field width. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, - IN UINT_PTR Number, - IN UINT_PTR Base, - IN UINT_PTR Padding) -{ - UINT16 Buffer[20]; - UINT_PTR NumberLength; - PUINT16 Pointer; - - /* Set pointer to the end of buffer */ - Pointer = Buffer + ARRAY_SIZE(Buffer); - - /* Convert value to specified base system */ - *--Pointer = 0; - do - { - *--Pointer = BlpHexTable[Number % Base]; - } while(Pointer >= Buffer && (Number /= Base)); - - /* Calculate number length */ - NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; - - /* Check if leading zeros are needed */ - if(NumberLength < Padding) - { - Padding -= NumberLength; - while(Padding--) - { - /* Write leading zeroes */ - PrintCharRoutine(L'0'); - } - } - - /* Print value to the console */ - for(; *Pointer; ++Pointer) - { - PrintCharRoutine(*Pointer); - } -} - -/** - * Reads the number of padding characters from the format string. - * - * @param Format - * The format string. - * - * @return Number of padding characters. - * - * @since XT 1.0 - */ -XTCDECL -UINT64 -BlpStringReadPadding(IN PUINT16 *Format) -{ - ULONG Count = 0; - PUINT16 Fmt = *Format; - - /* Read the padding */ - for(;; ++Fmt) - { - switch(*Fmt) - { - case L'0' ... L'9': - /* Check the number of leading zeroes */ - Count = Count * 10 + *Fmt - L'0'; - break; - default: - /* No padding by default */ - *Format = Fmt; - return Count; - } - } - - /* No padding by default */ - return 0; -} diff --git a/xtldr2/volume.c b/xtldr2/volume.c deleted file mode 100644 index 32cfed7..0000000 --- a/xtldr2/volume.c +++ /dev/null @@ -1,1019 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/volume.c - * DESCRIPTION: XTLDR volume support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * This routine closes an EFI volume handle. - * - * @param VolumeHandle - * Specifies a handle of opened volume. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle) -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - - /* Make sure a handle specified */ - if(VolumeHandle != NULL) - { - /* Close a handle */ - return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL); - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Discovers and enumerates a block devices available to EFI system. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlEnumerateBlockDevices() -{ - PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; - PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; - PEFI_BLOCK_DEVICE_DATA BlockDeviceData; - PEFI_BLOCK_DEVICE BlockDevice; - LIST_ENTRY BlockDevices; - PLIST_ENTRY ListEntry; - EFI_STATUS Status; - PEFI_ACPI_HID_DEVICE_PATH AcpiDevice; - PEFI_HARDDRIVE_DEVICE_PATH HDPath; - PEFI_BLOCK_IO_MEDIA Media; - PEFI_GUID PartitionGuid; - ULONG DriveNumber, PartitionNumber; - USHORT DriveType; - ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; - - /* Initialize list entries */ - RtlInitializeListHead(&BlockDevices); - RtlInitializeListHead(&EfiBlockDevices); - - /* Discover EFI block devices and store them in linked list */ - Status = BlpDiscoverEfiBlockDevices(&BlockDevices); - if(Status != STATUS_EFI_SUCCESS) - { - BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%lx)\n", Status); - return Status; - } - - /* Identify all discovered devices */ - ListEntry = BlockDevices.Flink; - while(ListEntry != &BlockDevices) - { - /* Take block device from the list */ - BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); - - /* Find last node */ - Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); - if(Status != STATUS_EFI_SUCCESS) - { - BlDebugPrint(L"WARNING: Block device last node not found\n"); - ListEntry = ListEntry->Flink; - continue; - } - - /* Set drive type to 'unknown' by default */ - DriveType = XTBL_BOOT_DEVICE_UNKNOWN; - - /* Check last node type */ - if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP) - { - /* Check for Floppy EISA identifiers */ - AcpiDevice = (PEFI_ACPI_HID_DEVICE_PATH)LastNode; - if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1) - { - /* Floppy drive found */ - Media = BlockDeviceData->BlockIo->Media; - DriveType = XTBL_BOOT_DEVICE_FLOPPY; - DriveNumber = FDCount++; - PartitionNumber = 0; - - /* Print debug message */ - BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", - DriveNumber, Media->MediaPresent, Media->ReadOnly); - } - } - else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH) - { - /* Media device path found */ - if(LastNode->SubType == EFI_MEDIA_CDROM_DP) - { - /* Optical drive found */ - Media = BlockDeviceData->BlockIo->Media; - DriveType = XTBL_BOOT_DEVICE_CDROM; - DriveNumber = CDCount++; - PartitionNumber = 0; - - /* Print debug message */ - BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", - DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); - } - else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) - { - /* Hard disk partition found */ - Media = BlockDeviceData->BlockIo->Media; - HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode; - DriveType = XTBL_BOOT_DEVICE_HARDDISK; - DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1; - PartitionNumber = HDPath->PartitionNumber; - PartitionGuid = (PEFI_GUID)HDPath->Signature; - - /* Print debug message */ - BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " - L"MBRType: %u, GUID: {%g}, PartSize: %luB)\n", - DriveNumber, PartitionNumber, HDPath->MBRType, - PartitionGuid, HDPath->PartitionSize * Media->BlockSize); - } - else if(LastNode->SubType == EFI_MEDIA_RAMDISK_DP) - { - /* RAM disk found */ - Media = BlockDeviceData->BlockIo->Media; - DriveType = XTBL_BOOT_DEVICE_RAMDISK; - DriveNumber = RDCount++; - PartitionNumber = 0; - - /* Print debug message */ - BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", - DriveNumber, Media->MediaPresent); - } - - if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode)) - { - BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); - continue; - } - } - - /* Make sure the device found has valid type set */ - if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) - { - /* Allocate memory for block device */ - Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); - if(Status != STATUS_EFI_SUCCESS) - { - BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Initialize block device */ - BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); - BlockDevice->DriveType = DriveType; - BlockDevice->DriveNumber = DriveNumber; - BlockDevice->PartitionNumber = PartitionNumber; - BlockDevice->PartitionGuid = PartitionGuid; - - /* Add block device to global list */ - RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); - } - - /* Get next entry from linked list */ - ListEntry = ListEntry->Flink; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Finds an EFI device path for a specified path on a given file system. - * - * @param FsHandle - * The handle of the corresponding file system. - * - * @param FileSystemPath - * Specifies a path on the corresponding file system. - * - * @param DevicePath - * Specifies a pointer to the memory area, where found device path will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, - IN CONST PWCHAR FileSystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) -{ - EFI_STATUS Status; - SIZE_T FsPathLength, DevicePathLength = 0; - PEFI_FILEPATH_DEVICE_PATH FilePath = NULL; - PEFI_DEVICE_PATH_PROTOCOL EndDevicePath; - PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle; - - /* Set local device path handle */ - DevicePathHandle = FsHandle; - - /* Find the end device path node */ - while(TRUE) { - /* Make sure there is a next node */ - if(*(PUSHORT)DevicePathHandle->Length == 0) - { - /* End device path not found */ - return STATUS_EFI_NOT_FOUND; - } - - /* Check if end device path node found */ - if(DevicePathHandle->Type == EFI_END_DEVICE_PATH) - { - /* End device path node found */ - break; - } - - /* Get next node */ - DevicePathLength += *(PUSHORT)DevicePathHandle->Length; - DevicePathHandle = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathHandle + *(PUSHORT)DevicePathHandle->Length); - } - - /* Check real path length */ - FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); - - /* Allocate memory pool for device path */ - Status = BlMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), - (PVOID *)DevicePath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Set file path */ - RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength); - FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength); - FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH; - FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP; - FilePath->Header.Length[0] = (UCHAR)FsPathLength + FIELD_OFFSET(EFI_FILEPATH_DEVICE_PATH, PathName) + sizeof(WCHAR); - FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8; - - /* Set device path end node */ - RtlCopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR)); - EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1]; - EndDevicePath->Type = EFI_END_DEVICE_PATH; - EndDevicePath->SubType = EFI_END_ENTIRE_DP; - EndDevicePath->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); - EndDevicePath->Length[1] = 0; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Finds a volume device path based on the specified ARC name or UUID. - * - * @param SystemPath - * An input string containing ARC/UUID path. - * - * @param DevicePath - * Supplies a pointer to memory region where device path will be stored. - * - * @param Path - * Supplies a pointer to the memory area, where path on device will be saved. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlGetVolumeDevicePath(IN PWCHAR SystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path) -{ - PEFI_BLOCK_DEVICE Device; - USHORT DriveType; - ULONG DriveNumber; - ULONG PartNumber; - PWCHAR Volume; - ULONG PathLength; - PLIST_ENTRY ListEntry; - EFI_STATUS Status; - - /* Make sure this is not set */ - *DevicePath = NULL; - - /* Find volume path and its length */ - Volume = SystemPath; - while(*Volume != '/' && *Volume != '\\' && *Volume != '\0') - { - Volume++; - } - PathLength = Volume - SystemPath; - - /* Check if valume path specified */ - if(PathLength == 0) - { - /* No volume path available */ - *Path = SystemPath; - return STATUS_EFI_NOT_FOUND; - } - - /* Check system path format */ - if(SystemPath[0] == '{') - { - if(PathLength == GUID_STRING_LENGTH) - { - /* This is EFI GUID */ - BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); - return STATUS_EFI_UNSUPPORTED; - } - else if(PathLength == PARTUUID_STRING_LENGTH) - { - /* This is MBR UUID */ - BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); - return STATUS_EFI_UNSUPPORTED; - } - else - { - /* Invalid UUID format */ - return STATUS_EFI_INVALID_PARAMETER; - } - } - else - { - /* Defaults to ARC path, dissect it */ - Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); - } - - /* Check if volume path parsed successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to parse system path */ - BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%lx)\n", SystemPath, Status); - return Status; - } - - /* Look for block device corresponding to dissected ARC path */ - ListEntry = EfiBlockDevices.Flink; - while(ListEntry != &EfiBlockDevices) - { - /* Check if this is the volume we are looking for */ - Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry); - if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber && - Device->PartitionNumber == PartNumber)) - { - /* Found volume */ - *DevicePath = Device->DevicePath; - break; - } - ListEntry = ListEntry->Flink; - } - - /* Check if volume was found */ - if(*DevicePath == NULL) - { - /* Failed to find volume */ - BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", - DriveType, DriveNumber, PartNumber); - return STATUS_EFI_NOT_FOUND; - } - - /* return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine opens an EFI volume and corresponding filesystem. - * - * @param DevicePath - * Specifies a device path of the volume to open. If not specifies, uses image protocol by default. - * - * @param DiskHandle - * The handle of the opened disk volume. - * - * @param FsHandle - * The handle of the opened file system. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle) -{ - EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL FileSystemProtocol; - PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; - EFI_STATUS Status; - - /* Check if device path has been passed or not */ - if(DevicePath != NULL) - { - /* Locate the device path */ - Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to locate device path */ - return Status; - } - } - else - { - /* Open the image protocol if no device path specified */ - Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open image protocol */ - return Status; - } - - /* Store disk handle */ - *DiskHandle = ImageProtocol->DeviceHandle; - } - - /* Open the filesystem protocol */ - Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); - - /* Check if filesystem protocol opened successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open the filesystem protocol, close volume */ - BlCloseVolume(*DiskHandle); - return Status; - } - - /* Open the corresponding filesystem */ - Status = FileSystemProtocol->OpenVolume(FileSystemProtocol, FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open the filesystem, close volume */ - BlCloseVolume(*DiskHandle); - return Status; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Reads data from the file. - * - * @param DirHandle - * Supplies a handle of the opened filesystem directory. - * - * @param FileName - * Supplies the name of the file to read. - * - * @param FileData - * Provides a buffer to store the data read from the file. - * - * @param FileSize - * Provides a pointer to the variable to store a size of the buffer. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlReadFile(IN PEFI_FILE_HANDLE DirHandle, - IN CONST PWCHAR FileName, - OUT PVOID *FileData, - OUT PSIZE_T FileSize) -{ - EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; - EFI_PHYSICAL_ADDRESS Address; - PEFI_FILE_HANDLE FileHandle; - PEFI_FILE_INFO FileInfo; - EFI_STATUS Status; - UINT_PTR ReadSize; - SIZE_T Pages; - - Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ, - EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open file */ - return Status; - } - - /* Set required size for getting file information */ - ReadSize = sizeof(EFI_FILE_INFO) + 32; - - /* Allocate necessary amount of memory */ - Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - FileHandle->Close(FileHandle); - return Status; - } - - /* First attempt to get file information */ - FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); - if(Status == STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Buffer is too small, but EFI tells the required size, so reallocate */ - BlMemoryFreePool(&FileInfo); - Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - FileHandle->Close(FileHandle); - return Status; - } - - /* Second attempt to get file information */ - Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo); - } - - /* Check if file information got successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get file information */ - FileHandle->Close(FileHandle); - BlMemoryFreePool(&FileInfo); - return Status; - } - - /* Store file size and calculate number of pages */ - *FileSize = FileInfo->FileSize; - Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); - - /* Allocate pages */ - Status = BlMemoryAllocatePages(Pages, &Address); - if(Status != STATUS_EFI_SUCCESS) - { - /* Pages allocation failure */ - FileHandle->Close(FileHandle); - BlMemoryFreePool(&FileInfo); - return Status; - } - - /* Calculate number of bytes to read and zero memory*/ - ReadSize = Pages * EFI_PAGE_SIZE; - *FileData = (PCHAR)(UINT_PTR)Address; - RtlZeroMemory(*FileData, ReadSize); - - /* Read data from the file */ - Status = FileHandle->Read(FileHandle, &ReadSize, *FileData); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read data */ - FileHandle->Close(FileHandle); - BlMemoryFreePool(&FileInfo); - BlMemoryFreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); - return Status; - } - - /* Close handle and free memory */ - FileHandle->Close(FileHandle); - BlMemoryFreePool(&FileInfo); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Gets a list of block devices from an EFI enabled BIOS. - * - * @param BlockDevices - * Supplies a pointer to a variable to receive a list of EFI block devices. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) -{ - EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; - EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; - PEFI_DEVICE_PATH_PROTOCOL DevicePath; - PEFI_BLOCK_DEVICE_DATA BlockDevice; - UINT_PTR HandlesCount, Index; - PEFI_HANDLE Handles = NULL; - PEFI_BLOCK_IO_PROTOCOL Io; - EFI_STATUS Status; - - /* Locate handles which support the disk I/O interface */ - Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, &IoGuid, NULL, &HandlesCount, &Handles); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to locate handles */ - BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%lx)\n", Status); - return Status; - } - - /* Iterate through all handles */ - for(Index = 0; Index < HandlesCount; Index++) - { - /* Print debug message */ - BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); - - /* Open I/O protocol for given handle */ - Io = NULL; - Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], &IoGuid, (PVOID *)&Io, EfiImageHandle, - NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS || Io == NULL) - { - /* Failed to open I/O protocol, skip it */ - BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%lx)\n", Status); - continue; - } - - /* Check if this is iPXE stub */ - if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) - { - /* Skip stub as it is non-functional */ - BlDebugPrint(L"WARNING: iPXE stub block I/O protocol"); - continue; - } - - /* Check if DevicePath protocol is supported by this handle */ - DevicePath = NULL; - Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath); - if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) - { - /* Device failed to handle DP protocol */ - BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%lx)\n", Status); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); - continue; - } - - /* Allocate memory for block device */ - Status = BlMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); - return Status; - } - - /* Store new block device into a linked list */ - BlockDevice->BlockIo = Io; - BlockDevice->DevicePath = DevicePath; - RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry); - } - - /* Free handles buffer */ - BlMemoryFreePool(Handles); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Dissects a specified ARC name and provides detailed information about corresponding device and on disk path. - * - * @param SystemPath - * Supplies an input ARC path. - * - * @param Path - * Specifies a pointer to variable, where on disk path will be saved. - * - * @param DriveType - * Supplies a pointer to the variable that receives a drive type. - * - * @param DriveNumber - * Supplies a pointer to the variable that receives a drive number. - * - * @param PartNumber - * Supplies a pointer to the variable that receives a parition number if applicable, otherwise stores 0 (zero). - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpDissectVolumeArcPath(IN PWCHAR SystemPath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber) -{ - PWCHAR ArcPath, LocalArcName; - ULONG ArcLength = 0; - - /* Set default values */ - *DriveType = XTBL_BOOT_DEVICE_UNKNOWN; - *DriveNumber = 0; - *PartNumber = 0; - - /* Look for the ARC path */ - if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0) - { - /* This is RAM disk */ - ArcLength = 10; - *DriveType = XTBL_BOOT_DEVICE_RAMDISK; - } - else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) - { - /* This is a multi-disk port */ - ArcLength = 15; - ArcPath = SystemPath + ArcLength; - - /* Check for disk type */ - if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0) - { - /* This is an optical drive */ - ArcLength += 6; - - /* Find drive number */ - while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') - { - if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') - { - /* Calculate drive number */ - *DriveNumber *= 10; - *DriveNumber += SystemPath[ArcLength] - '0'; - } - ArcLength++; - } - - /* Set proper drive type */ - *DriveType = XTBL_BOOT_DEVICE_CDROM; - ArcLength++; - } - else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) - { - /* This is a floppy drive */ - ArcLength += 6; - - /* Find drive number */ - while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') - { - if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') - { - /* Calculate drive number */ - *DriveNumber *= 10; - *DriveNumber += SystemPath[ArcLength] - '0'; - } - ArcLength++; - } - - /* Set proper drive type */ - *DriveType = XTBL_BOOT_DEVICE_FLOPPY; - ArcLength++; - } - else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) - { - /* This is a hard disk */ - ArcLength += 6; - - /* Find drive number */ - while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') - { - if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') - { - /* Calculate drive number */ - *DriveNumber *= 10; - *DriveNumber += SystemPath[ArcLength] - '0'; - } - ArcLength++; - } - - /* Set proper drive type */ - *DriveType = XTBL_BOOT_DEVICE_HARDDISK; - ArcLength++; - ArcPath = SystemPath + ArcLength; - - /* Look for a partition */ - if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) - { - /* Partition information found */ - ArcLength += 10; - - /* Find partition number */ - while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\0') - { - if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9') - { - /* Calculate partition number */ - *PartNumber *= 10; - *PartNumber += SystemPath[ArcLength] - '0'; - } - ArcLength++; - } - ArcLength++; - } - } - else - { - /* Unsupported disk type */ - return STATUS_EFI_UNSUPPORTED; - } - } - else - { - /* Unsupported ARC path */ - return STATUS_EFI_UNSUPPORTED; - } - - /* Store the path if possible */ - if(Path) - { - *Path = SystemPath + ArcLength; - } - - /* Store ARC name if possible */ - if(ArcName) - { - BlMemoryAllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); - RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); - LocalArcName[ArcLength] = '\0'; - *ArcName = LocalArcName; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine duplicates a device path object. - * - * @param DevicePath - * An input device path that is going to be clonned. - * - * @return Returns a duplicate of input device path. - * - * @since XT 1.0 - */ -XTCDECL -PEFI_DEVICE_PATH_PROTOCOL -BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) -{ - PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; - PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; - EFI_STATUS Status; - UINT Length = 0; - - DevicePathNode = DevicePath; - - /* Get the device path length */ - while(TRUE) - { - Length += *(PUINT16)DevicePath->Length; - if(DevicePathNode->Type == EFI_END_DEVICE_PATH) - { - break; - } - DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUINT16)DevicePath->Length); - } - - /* Check length */ - if(Length == 0) - { - /* Nothing to duplicate */ - return NULL; - } - - /* Allocate memory for the new device path */ - Status = BlMemoryAllocatePool(Length, (PVOID *)&DevicePathClone); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%lx)\n", Status); - return NULL; - } - - /* Copy the device path */ - RtlCopyMemory(DevicePathClone, DevicePath, Length); - - /* Return the cloned object */ - return DevicePathClone; -} - -/** - * Attempts to find a last node of the EFI block device. - * - * @param DevicePath - * An input device path. - * - * @param LastNode - * A pointer to the buffer where last node will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) -{ - PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; - - /* Make sure end is not reached yet */ - if(DevicePath->Type == EFI_END_DEVICE_PATH) - { - /* End reached, nothing to do */ - LastNode = NULL; - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Fast forward to the last node */ - EndNode = DevicePath; - while(EndNode->Type != EFI_END_DEVICE_PATH) - { - NextNode = EndNode; - EndNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)EndNode + *(PUSHORT)EndNode->Length); - } - - /* Store last node found */ - *LastNode = NextNode; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine attempts to find a parent device of the provided block device. - * - * @param BlockDevice - * A linked list of discovered block devices. - * - * @param ChildNode - * Block device that is looking for a parent device. - * - * @param ParentNode - * A pointer to memory region where pointer to the parent node will be provided. - * - * @return This routine returns TRUE if parent node has been found, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTCDECL -BOOLEAN -BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA ParentNode) -{ - PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; - PEFI_BLOCK_DEVICE_DATA BlockDeviceData; - UINT ChildLength, ParentLength; - PLIST_ENTRY ListEntry; - - ListEntry = BlockDevices->Flink; - while(ListEntry != BlockDevices) - { - /* Take block device from the list */ - BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); - - ChildDevicePath = ChildNode->DevicePath; - ParentDevicePath = BlockDeviceData->DevicePath; - - /* Iterate nodes */ - while(TRUE) - { - /* Check if the parent device is a match */ - if(ParentDevicePath->Type == EFI_END_DEVICE_PATH) - { - /* Parent device is a match */ - ParentNode = BlockDeviceData; - return TRUE; - } - - /* Get child and parent node lengths */ - ChildLength = *(PUINT16)ChildDevicePath->Length; - ParentLength = *(PUINT16)ParentDevicePath->Length; - - /* Check if lengths match */ - if(ChildLength != ParentLength) - { - /* Lengths do not match, this is not a valid parent */ - break; - } - - /* Move to the next child and parent nodes */ - ChildDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ChildDevicePath + ChildLength); - ParentDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ParentDevicePath + ParentLength); - } - - /* Get next entry from linked list */ - ListEntry = ListEntry->Flink; - } - - /* Apparently not found a parent node */ - return FALSE; -} diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c deleted file mode 100644 index 85e7902..0000000 --- a/xtldr2/xtldr.c +++ /dev/null @@ -1,433 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/xtldr.c - * DESCRIPTION: XTOS UEFI Boot Loader - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Initializes EFI Boot Loader (XTLDR). - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlInitializeBootLoader() -{ - EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - EFI_STATUS Status; - - /* Set current XTLDR's EFI BootServices status */ - BlpStatus.BootServices = TRUE; - - /* Initialize console */ - BlpInitializeConsole(); - - /* Print XTLDR version */ - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - - /* Initialize XTLDR configuration linked lists */ - RtlInitializeListHead(&BlpBootProtocols); - RtlInitializeListHead(&BlpConfig); - RtlInitializeListHead(&BlpLoadedModules); - - /* Store SecureBoot status */ - BlpStatus.SecureBoot = BlGetSecureBootStatus(); - - /* Check if debug is enabled */ - if(DEBUG) - { - /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenProtocol((PVOID *)&LoadedImage, &LipGuid); - if(Status == STATUS_EFI_SUCCESS) - { - /* Protocol opened successfully, print useful debug information */ - BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" - L"Pointer Size : %d\n" - L"Image Base Address: 0x%lx\n" - L"Image Base Size : 0x%lx\n" - L"Image Revision : 0x%lx\n" - L"--------------------------------------\n", - sizeof(PVOID), - LoadedImage->ImageBase, - LoadedImage->ImageSize, - LoadedImage->Revision); - BlSleepExecution(3000); - } - } -} - -/** - * Initializes a list of operating systems for XTLDR boot menu. - * - * @param MenuEntries - * Supplies a pointer to memory area where operating systems list will be stored. - * - * @param EntriesCount - * Supplies a pointer to memory area where number of menu entries will be stored. - * - * @param DefaultId - * Supplies a pointer to memory area where ID of default menu entry will be stored. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, - OUT PULONG EntriesCount, - OUT PULONG DefaultId) -{ - PWCHAR DefaultMenuEntry, MenuEntryName; - PLIST_ENTRY MenuEntrySectionList, MenuEntryList; - PXTBL_CONFIG_SECTION MenuEntrySection; - PXTBL_CONFIG_ENTRY MenuEntryOption; - PXTBL_BOOTMENU_ITEM OsList; - ULONG DefaultOS, NumberOfEntries; - - /* Set default values */ - DefaultOS = 0; - NumberOfEntries = 0; - OsList = NULL; - - /* Get default menu entry from configuration */ - DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); - - /* Iterate through all menu sections */ - MenuEntrySectionList = BlpMenuList->Flink; - while(MenuEntrySectionList != BlpMenuList) - { - /* NULLify menu entry name */ - MenuEntryName = NULL; - - /* Get menu section */ - MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); - - /* Check if this is the default menu entry */ - if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0) - { - /* Set default OS ID */ - DefaultOS = NumberOfEntries; - } - - /* Iterate through all entry parameters */ - MenuEntryList = MenuEntrySection->Options.Flink; - while(MenuEntryList != &MenuEntrySection->Options) - { - /* Get menu entry parameter */ - MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); - - /* Check if this is the menu entry display name */ - if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) - { - /* Set menu entry display name */ - MenuEntryName = MenuEntryOption->Value; - } - - /* Get next parameter for this menu entry */ - MenuEntryList = MenuEntryList->Flink; - } - - /* Add OS to the boot menu list */ - OsList[NumberOfEntries].EntryName = MenuEntryName; - OsList[NumberOfEntries].Options = &MenuEntrySection->Options; - - /* Get next menu entry */ - MenuEntrySectionList = MenuEntrySectionList->Flink; - NumberOfEntries++; - } - - /* Set return values */ - *DefaultId = DefaultOS; - *EntriesCount = NumberOfEntries; - MenuEntries = OsList; -} - -/** - * Loads all necessary modules and invokes boot protocol. - * - * @param OptionsList - * Supplies a pointer to list of options associated with chosen boot menu entry. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) -{ - XTBL_BOOT_PARAMETERS BootParameters; - PXTBL_BOOT_PROTOCOL BootProtocol; - PLIST_ENTRY OptionsListEntry; - PXTBL_CONFIG_ENTRY Option; - EFI_GUID BootProtocolGuid; - SIZE_T ModuleListLength; - PWCHAR ModulesList; - EFI_STATUS Status; - - /* Initialize boot parameters and a list of modules */ - RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); - ModulesList = NULL; - - /* Iterate through all options provided by boot menu entry and propagate boot parameters */ - OptionsListEntry = OptionsList->Flink; - while(OptionsListEntry != OptionsList) - { - /* Get option */ - Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Look for boot protocol and modules list */ - if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) - { - /* Check a length of modules list */ - ModuleListLength = RtlWideStringLength(Option->Value, 0); - - Status = BlMemoryAllocatePool(sizeof(PWCHAR) * ModuleListLength, (PVOID *)&ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n"); - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Make a copy of modules list */ - RtlCopyMemory(ModulesList, Option->Value, sizeof(PWCHAR) * ModuleListLength); - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) - { - /* Boot protocol found */ - BootParameters.SystemType = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) - { - /* System path found, get volume device path */ - Status = BlGetVolumeDevicePath((PWCHAR)Option->Value, &BootParameters.DevicePath, &BootParameters.ArcName, &BootParameters.SystemPath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to find volume */ - BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%lx)\n", Status); - return Status; - } - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) - { - /* Kernel file name found */ - BootParameters.KernelFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) - { - /* Initrd file name found */ - BootParameters.InitrdFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) - { - /* Hal file name found */ - BootParameters.HalFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) - { - /* Kernel parameters found */ - BootParameters.Parameters = Option->Value; - } - - /* Move to the next option entry */ - OptionsListEntry = OptionsListEntry->Flink; - } - - /* Load all necessary modules */ - Status = BlLoadModules(ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load modules, print error message and return status code */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules\n"); - return STATUS_EFI_NOT_READY; - } - - /* Attempt to get boot protocol GUID */ - Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get boot protocol GUID */ - BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%lx)\n", Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Open boot protocol */ - Status = BlOpenProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open boot protocol */ - BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%lx)\n", Status); - return Status; - } - - /* Boot Operating System */ - return BootProtocol->BootSystem(&BootParameters); -} - -/** - * This routine is the entry point of the XT EFI boot loader. - * - * @param ImageHandle - * Firmware-allocated handle that identifies the image. - * - * @param SystemTable - * Provides the EFI system table. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable) -{ - EFI_STATUS Status; - - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Initialize XTLDR and */ - BlInitializeBootLoader(); - - /* Parse configuration options passed from UEFI shell */ - Status = BlpParseCommandLine(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to parse command line options */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); - } - - /* Attempt to early initialize debug console */ - if(DEBUG) - { - Status = BlpInitializeDebugConsole(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); - } - } - - /* Load XTLDR configuration file */ - Status = BlpLoadConfiguration(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load/parse config file */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file."); - } - - /* Reinitialize debug console if it was not initialized earlier */ - if(DEBUG) - { - Status = BlpInitializeDebugConsole(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); - } - } - - /* 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 boot protocol\n"); - return Status; - } - - /* Load boot loader modules */ - Status = BlLoadModules(BlGetConfigValue(L"MODULES")); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load modules */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); - } - - /* Discover and enumerate EFI block devices */ - Status = BlEnumerateBlockDevices(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to enumerate block devices */ - BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); - return Status; - } - - - // BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); - // PLIST_ENTRY ModuleListEntry; - // PXTBL_MODULE_INFO ModuleInfo; - - // ModuleListEntry = BlpLoadedModules.Flink; - // while(ModuleListEntry != &BlpLoadedModules) - // { - // /* Get module information */ - // ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - // /* Module already loaded */ - // BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); - // if(ModuleInfo->ModuleDescription != 0) - // { - // BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); - // } - - // PLIST_ENTRY DepsListEntry; - // PXTBL_MODULE_DEPS DepsInfo; - // BlConsolePrint(L"\n - Uses: "); - // DepsListEntry = ModuleInfo->Dependencies.Flink; - // while(DepsListEntry != &ModuleInfo->Dependencies) - // { - // DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); - // BlConsolePrint(L"%S ", DepsInfo->ModuleName); - // DepsListEntry = DepsListEntry->Flink; - // } - - // /* Move to the module */ - // ModuleListEntry = ModuleListEntry->Flink; - // } - - // BlConsolePrint(L"\n\n END OF LIST\n"); - - /* Main boot loader loop */ - while(TRUE) - { - /* Check if custom boot menu registered */ - if(BlpStatus.BootMenu != NULL) - { - /* Display alternative boot menu */ - BlpStatus.BootMenu(); - } - else - { - /* Display default boot menu */ - BlDisplayBootMenu(); - } - - /* Fallback to shell, if boot menu returned */ - BlStartLoaderShell(); - } - - /* This point should be never reached, if this happen return error code */ - return STATUS_EFI_LOAD_ERROR; -} -- 2.45.1 From 5d5f613ef5fe6735553eb6497e436362be321392 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 22:49:44 +0100 Subject: [PATCH 152/182] Update bootloader configuration --- bootdata/xtldr/xtldr.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootdata/xtldr/xtldr.ini b/bootdata/xtldr/xtldr.ini index 124a8f4..31dfdfd 100644 --- a/bootdata/xtldr/xtldr.ini +++ b/bootdata/xtldr/xtldr.ini @@ -32,7 +32,7 @@ Tune=400 880 2 988 2 783 2 392 2 587 3 [ExectOS] SystemName="ExectOS Operating System" SystemType=XTOS -BootModules=xtos +BootModules=xtos_o SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS KernelFile=xtoskrnl.exe Parameters=DEBUG=COM1,115200 -- 2.45.1 From 9443da9817c1153b8d4472b8d45cb6bfac95aab1 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 5 Jan 2024 15:10:34 +0100 Subject: [PATCH 153/182] Always check module mapping status and optionally map xtldr code --- xtldr/modules/xtos_o/amd64/memory.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/xtldr/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.c index cc7a16b..807834b 100644 --- a/xtldr/modules/xtos_o/amd64/memory.c +++ b/xtldr/modules/xtos_o/amd64/memory.c @@ -63,7 +63,7 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); /* Map module code */ - XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + Status = XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) @@ -77,13 +77,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, } /* Map XTLDR code */ - Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, + XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping the boot loader code failed */ - return Status; - } /* Add page mapping itself to memory mapping */ Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); -- 2.45.1 From 0293fb6f286996e18afbd5c4adc715fb834e6da8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 5 Jan 2024 15:13:45 +0100 Subject: [PATCH 154/182] If ExitBootServices() fails, it is mostly caused by map key that is racing with asynchronous events signaled over the back of the timer interrupt. In this case new memory map should be obtained prior to another ExitBootServices() call attempt --- xtldr/modules/xtos_o/amd64/memory.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/xtldr/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.c index 807834b..e227867 100644 --- a/xtldr/modules/xtos_o/amd64/memory.c +++ b/xtldr/modules/xtos_o/amd64/memory.c @@ -140,7 +140,20 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, if(Status != STATUS_EFI_SUCCESS) { /* Failed to exit boot services */ - XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %lx)\n", Status); + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get memory map */ + return Status; + } + + Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey); + } + + /* Check if exitted boot services successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + XtLdrProtocol->Console.Print(L"Failed to exit boot services (Status code: %lx)\n", Status); return STATUS_EFI_ABORTED; } -- 2.45.1 From 3fee69cbdfa34ef246bc1fba67da882abfb096cc Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 5 Jan 2024 23:18:24 +0100 Subject: [PATCH 155/182] Close directory after reading configuration file --- xtldr/config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xtldr/config.c b/xtldr/config.c index 65f74fc..e629e0e 100644 --- a/xtldr/config.c +++ b/xtldr/config.c @@ -520,8 +520,9 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, return Status; } - /* Read configuration file */ + /* Read configuration file and close directory */ Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); + DirHandle->Close(DirHandle); /* Close EFI volume */ BlCloseVolume(DiskHandle); -- 2.45.1 From 2864fdd790b70418b560295ae87704f1b9eb1b9f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 5 Jan 2024 23:24:13 +0100 Subject: [PATCH 156/182] Close directory after reading module file --- xtldr/protocol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xtldr/protocol.c b/xtldr/protocol.c index 98ededc..477aa20 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -145,8 +145,9 @@ BlLoadModule(IN PWCHAR ModuleName) return Status; } - /* Read module file from disk and close EFI volume */ + /* Read module file from disk and close directory and EFI volume */ Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + DirHandle->Close(DirHandle); BlCloseVolume(DiskHandle); /* Make sure module file was read successfully */ -- 2.45.1 From f49966b462040d5542d549fd5b6d381963295172 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Fri, 5 Jan 2024 23:28:12 +0100 Subject: [PATCH 157/182] Allow to read XTLDR data from alternative arch-specific directory; this allows to prepare combined 32 & 64 bit disk --- sdk/xtdk/bltypes.h | 13 +++++++++++++ xtldr/config.c | 7 +++++++ xtldr/protocol.c | 11 +++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index be432d2..97a9e97 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -14,6 +14,19 @@ #include +/* Architecture specific definitions */ +#if defined(__i386__) || defined(__i686__) + #define XTBL_ARCH_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\" + #define XTBL_ARCH_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\MODULES\\" + #define XTBL_ARCH_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\THEMES\\" +#elif defined(__amd64__) || defined(__x86_64__) + #define XTBL_ARCH_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\" + #define XTBL_ARCH_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\MODULES\\" + #define XTBL_ARCH_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\THEMES\\" +#else + #error Unknown architecture +#endif + /* XTLDR directories */ #define XTBL_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\" #define XTBL_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\MODULES\\" diff --git a/xtldr/config.c b/xtldr/config.c index e629e0e..b946700 100644 --- a/xtldr/config.c +++ b/xtldr/config.c @@ -123,6 +123,13 @@ BlpLoadConfiguration() /* Read data from configuration file */ Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read config file, try with architecture specific directory */ + Status = BlpReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); + } + + /* Check if configuration was read successfully */ + if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ BlDebugPrint(L"Failed to load configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n"); diff --git a/xtldr/protocol.c b/xtldr/protocol.c index 477aa20..dbb2b36 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -133,11 +133,18 @@ BlLoadModule(IN PWCHAR ModuleName) return Status; } - /* Open XTLDR modules directory and close the FS immediately */ + /* Open XTLDR modules common directory */ Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + if(Status != STATUS_EFI_SUCCESS) + { + /* Modules directory not found, attempt to open XTLDR architecture specific modules directory */ + Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_ARCH_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + } + + /* Close FS handle */ FsHandle->Close(FsHandle); - /* Check if directory opened successfully */ + /* Check if modules directory opened successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to open directory */ -- 2.45.1 From 602f8c1c0ea39e3f8d6f7fece5685207d82638ba Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 6 Jan 2024 23:04:52 +0100 Subject: [PATCH 158/182] Don't print FB information --- xtldr/modules/xtos_o/xtos.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index 5670c6c..ef4a667 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -364,7 +364,6 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, { /* Make sure FrameBuffer is initialized */ FrameBufProtocol->Initialize(); - FrameBufProtocol->PrintDisplayInformation(); /* Store information about FrameBuffer device */ FrameBufProtocol->GetDisplayInformation(&LoaderBlock->LoaderInformation.FrameBuffer); -- 2.45.1 From 60ce943cab2f56a09a6cbaacbf755891fb7f2c72 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 6 Jan 2024 23:23:52 +0100 Subject: [PATCH 159/182] Fix memory mappings and exiting boot services for i686 --- xtldr/modules/xtos_o/i686/memory.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/xtldr/modules/xtos_o/i686/memory.c b/xtldr/modules/xtos_o/i686/memory.c index 141fe42..3ccf644 100644 --- a/xtldr/modules/xtos_o/i686/memory.c +++ b/xtldr/modules/xtos_o/i686/memory.c @@ -175,13 +175,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, } /* Map XTLDR code */ - Status = XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, + XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase, EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary); - if(Status != STATUS_EFI_SUCCESS) - { - /* Mapping the boot loader code failed */ - return Status; - } /* Add page mapping itself to memory mapping */ Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData); @@ -238,6 +233,20 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings, /* Exit EFI Boot Services */ Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey); + /* Check if exitted boot services successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to exit boot services */ + Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get memory map */ + return Status; + } + + Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey); + } + /* Check if exitted boot services successfully */ if(Status != STATUS_EFI_SUCCESS) { -- 2.45.1 From fd330e9631ea664907f22742cb4ebd97a876a2d9 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 6 Jan 2024 23:40:44 +0100 Subject: [PATCH 160/182] Cleanup --- xtldr/modules/dummy/dummy.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c index d98c845..93b99d5 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.c @@ -12,7 +12,6 @@ /* Dummy module information */ XTBL_MODINFO = L"Dummy XTLDR module"; -// XTBL_MODDEPS = {L"dummy2"}; XTCDECL EFI_STATUS -- 2.45.1 From de2100352d15ef5eee799feda5f5cbc3c4dd0dc0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 00:08:15 +0100 Subject: [PATCH 161/182] Add missing forward reference --- sdk/xtdk/xtstruct.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index a8835f4..dcc19ab 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -270,6 +270,7 @@ typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY; typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION; typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE; +typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL; typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS; -- 2.45.1 From bb09741e0a3bd03092bedacfe1ec153b9c5c2413 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 00:11:34 +0100 Subject: [PATCH 162/182] Cleanup includes --- sdk/xtdk/xtblapi.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index 78b3e7b..c95e689 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -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 @@ -43,7 +43,6 @@ /* Architecture specific XT kernel routines */ #include ARCH_HEADER(arfuncs.h) -// #include ARCH_HEADER(hlfuncs.h) /* Boot Manager specific structures */ #include -- 2.45.1 From 9aab75dae48ae24aed03f5671f02f012fb242279 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 00:12:35 +0100 Subject: [PATCH 163/182] Correct project name --- xtldr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index 275b9ff..680f6fe 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -1,4 +1,4 @@ -# XT Boot Manager +# XT Boot Loader PROJECT(XTLDR) # Build XTLDR modules -- 2.45.1 From d768337b6a33db1cdd93049dda55c071c266da83 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 00:14:45 +0100 Subject: [PATCH 164/182] Update README --- xtldr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtldr/README.md b/xtldr/README.md index ae4fe9f..38cefcd 100644 --- a/xtldr/README.md +++ b/xtldr/README.md @@ -1,4 +1,4 @@ -## XT Boot Manager (XTLDR) +## XT Boot Loader (XTLDR) The XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS. As an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems, like old and deprecated BIOS. -- 2.45.1 From cd03f4fbca3cc708989cac472f29df9b7b78013b Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 12:01:23 +0100 Subject: [PATCH 165/182] Print prompt --- xtldr/shell.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xtldr/shell.c b/xtldr/shell.c index 167165a..5f51cd4 100644 --- a/xtldr/shell.c +++ b/xtldr/shell.c @@ -13,4 +13,12 @@ XTCDECL VOID BlStartLoaderShell() { + /* Clear screen and enable cursor */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); + BlEnableConsoleCursor(); + + /* Print prompt */ + BlConsolePrint(L"XTLDR> "); + for(;;); } -- 2.45.1 From 2d544e5993f120ff2ad2ec86fbc9d844bcb9b9e2 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 14:02:16 +0100 Subject: [PATCH 166/182] Set defaukt colors before clearing console screen --- xtldr/console.c | 59 +++++++++++++++++++++--------------------- xtldr/includes/xtldr.h | 8 +++--- xtldr/xtldr.c | 2 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/xtldr/console.c b/xtldr/console.c index e41b8ce..8d7bca3 100644 --- a/xtldr/console.c +++ b/xtldr/console.c @@ -138,6 +138,36 @@ BlConsoleWrite(IN PUSHORT String) EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); } +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BlInitializeConsole() +{ + /* Clear console buffers */ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); + EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); + EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + + /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might + * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ + if(EfiSystemTable->ConOut->Mode->Mode != 0) + { + /* Set console mode to 0, which is standard, 80x25 text mode */ + BlSetConsoleMode(0); + } + + /* Clear screen and enable cursor */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + BlClearConsoleScreen(); + BlEnableConsoleCursor(); +} + /** * Queries information concerning the output device’s supported text mode. * @@ -266,32 +296,3 @@ BlpConsolePrintChar(IN USHORT Character) Buffer[1] = 0; EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); } - -/** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpInitializeConsole() -{ - /* Clear console buffers */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); - EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); - EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); - - /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might - * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ - if(EfiSystemTable->ConOut->Mode->Mode != 0) - { - /* Set console mode to 0, which is standard, 80x25 text mode */ - BlSetConsoleMode(0); - } - - /* Clear screen and enable cursor */ - BlClearConsoleScreen(); - BlEnableConsoleCursor(); -} diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index b7aaaf3..ea52a22 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -131,6 +131,10 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +XTCDECL +VOID +BlInitializeConsole(); + XTCDECL EFI_STATUS BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); @@ -254,10 +258,6 @@ XTCDECL EFI_STATUS BlpActivateSerialIOController(); -XTCDECL -VOID -BlpInitializeConsole(); - XTCDECL VOID BlpConsolePrintChar(IN USHORT Character); diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 85e7902..c6d4608 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -28,7 +28,7 @@ BlInitializeBootLoader() BlpStatus.BootServices = TRUE; /* Initialize console */ - BlpInitializeConsole(); + BlInitializeConsole(); /* Print XTLDR version */ BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); -- 2.45.1 From 1f9b03b11bec0dd0c9474f1df0c27a66a0514f8f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 14:04:57 +0100 Subject: [PATCH 167/182] Color shell prompt --- xtldr/includes/xtldr.h | 4 ++++ xtldr/shell.c | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index ea52a22..38fd516 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -358,6 +358,10 @@ EFI_STATUS BlpParseConfigFile(IN CONST PCHAR RawConfig, OUT PLIST_ENTRY Configuration); +XTCDECL +VOID +BlpPrintShellPrompt(); + XTCDECL EFI_STATUS BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, diff --git a/xtldr/shell.c b/xtldr/shell.c index 5f51cd4..a9d58b7 100644 --- a/xtldr/shell.c +++ b/xtldr/shell.c @@ -13,12 +13,24 @@ XTCDECL VOID BlStartLoaderShell() { - /* Clear screen and enable cursor */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); - BlEnableConsoleCursor(); + /* Initialize console */ + BlInitializeConsole(); + + /* Print prompt */ + BlpPrintShellPrompt(); + for(;;); +} + +XTCDECL +VOID +BlpPrintShellPrompt() +{ + /* Set prompt color */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); /* Print prompt */ BlConsolePrint(L"XTLDR> "); - for(;;); + + /* Reset standard shell colors */ + BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } -- 2.45.1 From 565339300289016e35bd70238a4abb0bb50b1a7a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 14:40:51 +0100 Subject: [PATCH 168/182] Update help --- xtldr/textui.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/xtldr/textui.c b/xtldr/textui.c index 8f3620e..a2a6aad 100644 --- a/xtldr/textui.c +++ b/xtldr/textui.c @@ -205,7 +205,14 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x0B) { /* F1 key pressed, show help */ - BlDisplayInfoDialog(L"XTLDR", L"XTLDR Boot Loader Help"); + BlDisplayInfoDialog(L"XTLDR", L"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\n" + L" \n" + L"Use arrow keys (Up/Down) to change the highlighted entry and\n" + L"PgUp/PgDown keys to jump to the first/last position.\n" + L" \n" + L"Press ENTER key to boot the highlighted boot menu entry.\n" + L"Press 'e' key to edit the highlighted menu entry.\n" + L"Press 's' key to exit into XTLDR shell (advanced mode).\n"); /* Break from boot menu event loop to redraw whole boot menu */ break; @@ -720,6 +727,7 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, /* Update dialog window width */ Width = LineLength; } + /* Increase dialog window height to fit next line */ Height++; LineLength = 0; -- 2.45.1 From fbcdc0d8d0e06b6993c1be37eb074778330aa49f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 15:20:13 +0100 Subject: [PATCH 169/182] Make a copy of dialog box message as it gets modified by RtlTokenizeWideString() --- xtldr/textui.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/xtldr/textui.c b/xtldr/textui.c index a2a6aad..c9aacef 100644 --- a/xtldr/textui.c +++ b/xtldr/textui.c @@ -1182,19 +1182,34 @@ VOID BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message) { - PWCHAR MsgLine, LastMsgLine; - SIZE_T Index, Length; + PWCHAR Msg, MsgLine, LastMsgLine; + SIZE_T Index, Length, LineLength; + EFI_STATUS Status; ULONG Line; + /* Allocate memory for dialog box message */ + Length = RtlWideStringLength(Message, 0); + Status = BlMemoryAllocatePool(Length * sizeof(WCHAR), (PVOID *)&Msg); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); + return; + } + + /* Make a copy of dialog box message */ + RtlCopyMemory(Msg, Message, Length * sizeof(WCHAR)); + Msg[Length] = 0; + /* Tokenize dialog box message */ - MsgLine = RtlTokenizeWideString(Message, L"\n", &LastMsgLine); + MsgLine = RtlTokenizeWideString(Msg, L"\n", &LastMsgLine); /* Iterate through message lines */ Line = 0; while(MsgLine) { /* Determine line length */ - Length = RtlWideStringLength(Message, 0); + LineLength = RtlWideStringLength(MsgLine, 0); /* Write line in the dialog box */ BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); @@ -1202,10 +1217,10 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, BlConsolePrint(L"%S", MsgLine); /* Check if message line is shorter than the dialog box working area */ - if(Length < Handle->Width - 4) + if(LineLength < Handle->Width - 4) { /* Fill the rest of the line with spaces */ - for(Index = Length; Index < Handle->Width - 4; Index++) + for(Index = LineLength; Index < Handle->Width - 4; Index++) { BlConsolePrint(L" "); } -- 2.45.1 From b8a17a74c16604073d3286fbceeac817302aaff8 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 15:27:36 +0100 Subject: [PATCH 170/182] Cleanup --- xtldr/xtldr.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index c6d4608..dbcf185 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -374,41 +374,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, return Status; } - - // BlConsolePrint(L"\n\n\n\n\n\n\n\nList of loaded modules:"); - // PLIST_ENTRY ModuleListEntry; - // PXTBL_MODULE_INFO ModuleInfo; - - // ModuleListEntry = BlpLoadedModules.Flink; - // while(ModuleListEntry != &BlpLoadedModules) - // { - // /* Get module information */ - // ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - // /* Module already loaded */ - // BlConsolePrint(L"\n%S", ModuleInfo->ModuleName); - // if(ModuleInfo->ModuleDescription != 0) - // { - // BlConsolePrint(L" (%S)", ModuleInfo->ModuleDescription); - // } - - // PLIST_ENTRY DepsListEntry; - // PXTBL_MODULE_DEPS DepsInfo; - // BlConsolePrint(L"\n - Uses: "); - // DepsListEntry = ModuleInfo->Dependencies.Flink; - // while(DepsListEntry != &ModuleInfo->Dependencies) - // { - // DepsInfo = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); - // BlConsolePrint(L"%S ", DepsInfo->ModuleName); - // DepsListEntry = DepsListEntry->Flink; - // } - - // /* Move to the module */ - // ModuleListEntry = ModuleListEntry->Flink; - // } - - // BlConsolePrint(L"\n\n END OF LIST\n"); - /* Main boot loader loop */ while(TRUE) { -- 2.45.1 From b85b5a96559ccc86f5a281c6017295d680f471e5 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 19:26:18 +0100 Subject: [PATCH 171/182] This is no longer an issue --- KNOWN_ISSUES.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md index a13844a..f008157 100644 --- a/KNOWN_ISSUES.md +++ b/KNOWN_ISSUES.md @@ -2,8 +2,5 @@ This is a list of well known bugs that exists in all master branch builds. ### XTLDR - - [ ] In some specific scenarios (most probably EFI by Insyde) XTLDR cannot load modules. Calling the EFI's - BootServices->LoadImage() fails with STATUS_EFI_NOT_FOUND (0x800000000000000E) status code. Possibly this is - a bug in BlFindVolumeDevicePath() routine. - [ ] EFI Runtime Services are not mapped properly into higher half. They are mapped itself, but all pointers inside that structure point to some physical address that is unavailable after paging is enabled. -- 2.45.1 From 2c6525cedd878cdabbabc01b89c3f1591dbd0e17 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 19:35:23 +0100 Subject: [PATCH 172/182] Add shell related routines documentation --- xtldr/shell.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xtldr/shell.c b/xtldr/shell.c index a9d58b7..bd1d159 100644 --- a/xtldr/shell.c +++ b/xtldr/shell.c @@ -9,6 +9,13 @@ #include +/** + * Starts XTLDR shell. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlStartLoaderShell() @@ -21,6 +28,13 @@ BlStartLoaderShell() for(;;); } +/** + * Prints XTLDR shell prompt. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID BlpPrintShellPrompt() -- 2.45.1 From 5106ed7bdcd63f14cdc3b652588034527d0de208 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 20:00:31 +0100 Subject: [PATCH 173/182] Print status code where applicable --- xtldr/config.c | 4 ++-- xtldr/volume.c | 2 +- xtldr/xtldr.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/xtldr/config.c b/xtldr/config.c index b946700..763a03d 100644 --- a/xtldr/config.c +++ b/xtldr/config.c @@ -132,7 +132,7 @@ BlpLoadConfiguration() if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ - BlDebugPrint(L"Failed to load configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n"); + BlDebugPrint(L"Failed to load FS0:/EFI/BOOT/XTLDR.INI configuration file (Status Code: 0x%lx)\n", Status); return Status; } @@ -141,7 +141,7 @@ BlpLoadConfiguration() if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ - BlDebugPrint(L"Failed to parse configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n"); + BlDebugPrint(L"Failed to parse FS0:/EFI/BOOT/XTLDR.INI configuration file (Status Code: 0x%lx)\n", Status); return Status; } diff --git a/xtldr/volume.c b/xtldr/volume.c index 32cfed7..fdfca08 100644 --- a/xtldr/volume.c +++ b/xtldr/volume.c @@ -642,7 +642,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) { /* Skip stub as it is non-functional */ - BlDebugPrint(L"WARNING: iPXE stub block I/O protocol"); + BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol"); continue; } diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index dbcf185..6cf574a 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -195,7 +195,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n"); + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); return STATUS_EFI_OUT_OF_RESOURCES; } @@ -248,7 +248,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) if(Status != STATUS_EFI_SUCCESS) { /* Failed to load modules, print error message and return status code */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules\n"); + BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status); return STATUS_EFI_NOT_READY; } @@ -325,7 +325,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to load/parse config file */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file."); + BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file "); } /* Reinitialize debug console if it was not initialized earlier */ @@ -344,7 +344,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to disable the timer, print message */ - BlDebugPrint(L"WARNING: Failed to disable watchdog timer\n"); + BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%lx)\n", Status); } /* Register loader protocol */ @@ -352,7 +352,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to register loader protocol */ - BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol\n"); + BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol (Status Code: 0x%lx)\n", Status); return Status; } @@ -370,7 +370,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to enumerate block devices */ - BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n"); + BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%lx)\n", Status); return Status; } -- 2.45.1 From 7fd5273476d866f2d67796a3264eb500e27ce094 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 20:54:59 +0100 Subject: [PATCH 174/182] Rename Protocol->Register() to Protocol->Install() --- xtldr/includes/xtldr.h | 10 +++++----- xtldr/modules/dummy/dummy.c | 2 +- xtldr/modules/fb_o/framebuf.c | 2 +- xtldr/modules/pecoff_o/pecoff.c | 2 +- xtldr/modules/xtos_o/xtos.c | 2 +- xtldr/protocol.c | 10 +++++----- xtldr/xtldr.c | 6 +++--- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 38fd516..7a3c4a1 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -204,7 +204,7 @@ BlRegisterBootProtocol(IN PWCHAR SystemType, XTCDECL EFI_STATUS -BlRegisterProtocol(IN PEFI_GUID Guid, +BlInstallProtocol(IN PEFI_GUID Guid, IN PVOID Interface); XTCDECL @@ -345,6 +345,10 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG PortAddress, IN ULONG BaudRate); +XTCDECL +EFI_STATUS +BlpInstallXtLoaderProtocol(); + XTCDECL EFI_STATUS BlpLoadConfiguration(); @@ -368,10 +372,6 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, IN CONST PWCHAR ConfigFile, OUT PCHAR *ConfigData); -XTCDECL -EFI_STATUS -BlpRegisterXtLoaderProtocol(); - XTCDECL VOID BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c index 93b99d5..b68dbc7 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.c @@ -56,5 +56,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid); /* Register DUMMY protocol as XTOS boot protocol */ - return XtLdrProto->Protocol.Register(&DummyGuid, &BlpDummyProtocol); + return XtLdrProto->Protocol.Install(&DummyGuid, &BlpDummyProtocol); } diff --git a/xtldr/modules/fb_o/framebuf.c b/xtldr/modules/fb_o/framebuf.c index bbff477..769da90 100644 --- a/xtldr/modules/fb_o/framebuf.c +++ b/xtldr/modules/fb_o/framebuf.c @@ -251,5 +251,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtFramebufferProtocol.PrintDisplayInformation = FbPrintDisplayInformation; /* Register XTOS boot protocol */ - return XtLdrProtocol->Protocol.Register(&Guid, &XtFramebufferProtocol); + return XtLdrProtocol->Protocol.Install(&Guid, &XtFramebufferProtocol); } diff --git a/xtldr/modules/pecoff_o/pecoff.c b/xtldr/modules/pecoff_o/pecoff.c index d9c87d2..2c48a2e 100644 --- a/xtldr/modules/pecoff_o/pecoff.c +++ b/xtldr/modules/pecoff_o/pecoff.c @@ -603,5 +603,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtPeCoffProtocol.RelocateImage = PeRelocateImage; /* Register PE/COFF protocol */ - return XtLdrProtocol->Protocol.Register(&Guid, &XtPeCoffProtocol); + return XtLdrProtocol->Protocol.Install(&Guid, &XtPeCoffProtocol); } diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index ef4a667..f7248dc 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -542,5 +542,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid); /* Install XTOS protocol */ - return XtLdrProtocol->Protocol.Register(&Guid, &XtBootProtocol); + return XtLdrProtocol->Protocol.Install(&Guid, &XtBootProtocol); } diff --git a/xtldr/protocol.c b/xtldr/protocol.c index dbb2b36..7306f25 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -506,7 +506,7 @@ BlRegisterBootProtocol(IN PWCHAR SystemType, */ XTCDECL EFI_STATUS -BlRegisterProtocol(IN PEFI_GUID Guid, +BlInstallProtocol(IN PEFI_GUID Guid, IN PVOID Interface) { EFI_HANDLE Handle = NULL; @@ -516,7 +516,7 @@ BlRegisterProtocol(IN PEFI_GUID Guid, } /** - * This routine registers XTLDR protocol for further usage by modules. + * This routine installs XTLDR protocol for further usage by modules. * * @return This routine returns a status code. * @@ -524,7 +524,7 @@ BlRegisterProtocol(IN PEFI_GUID Guid, */ XTCDECL EFI_STATUS -BlpRegisterXtLoaderProtocol() +BlpInstallXtLoaderProtocol() { EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; @@ -556,7 +556,7 @@ BlpRegisterXtLoaderProtocol() BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; BlpLdrProtocol.Protocol.Open = BlOpenProtocol; - BlpLdrProtocol.Protocol.Register = BlRegisterProtocol; + BlpLdrProtocol.Protocol.Install = BlInstallProtocol; BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog; @@ -569,5 +569,5 @@ BlpRegisterXtLoaderProtocol() /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); - return BlRegisterProtocol(&Guid, &BlpLdrProtocol); + return BlInstallProtocol(&Guid, &BlpLdrProtocol); } diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 6cf574a..bc23020 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -347,12 +347,12 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%lx)\n", Status); } - /* Register loader protocol */ - Status = BlpRegisterXtLoaderProtocol(); + /* Install loader protocol */ + Status = BlpInstallXtLoaderProtocol(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to register loader protocol */ - BlDebugPrint(L"ERROR: Failed to register XTLDR boot protocol (Status Code: 0x%lx)\n", Status); + BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%lx)\n", Status); return Status; } -- 2.45.1 From 87a586ed687411bf3407cf854a8fb6e31ce4dba3 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sun, 7 Jan 2024 20:58:20 +0100 Subject: [PATCH 175/182] Rename Protocol->Register() to Protocol->Install(), add missing header changes --- sdk/xtdk/bltypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 97a9e97..6113562 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -259,8 +259,8 @@ typedef struct _XTBL_LOADER_PROTOCOL struct { PBL_GET_MODULES_LIST GetModulesList; + PBL_REGISTER_XT_PROTOCOL Install; PBL_OPEN_XT_PROTOCOL Open; - PBL_REGISTER_XT_PROTOCOL Register; } Protocol; struct { -- 2.45.1 From 17c0fdeccea7f10c887eeca995cf1d1df0bc5dfd Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 16:13:18 +0100 Subject: [PATCH 176/182] Improvements to protocol support --- sdk/xtdk/bltypes.h | 8 ++-- xtldr/includes/xtldr.h | 7 +-- xtldr/modules/dummy/dummy.c | 2 +- xtldr/modules/fb_o/framebuf.c | 13 ++++-- xtldr/modules/pecoff_o/pecoff.c | 2 +- xtldr/modules/xtos_o/xtos.c | 15 ++++--- xtldr/protocol.c | 79 ++++++++++++++++++++++----------- xtldr/xtldr.c | 6 ++- 8 files changed, 88 insertions(+), 44 deletions(-) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 6113562..1c5149a 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -66,6 +66,7 @@ typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntr typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); +typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); @@ -89,12 +90,12 @@ typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); typedef PLIST_ENTRY (*PBL_GET_MODULES_LIST)(); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); +typedef EFI_STATUS (*PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid); typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); -typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); -typedef EFI_STATUS (*PBL_REGISTER_XT_PROTOCOL)(IN PEFI_GUID Guid, IN PVOID Interface); typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); @@ -258,8 +259,9 @@ typedef struct _XTBL_LOADER_PROTOCOL } Memory; struct { + PBL_CLOSE_XT_PROTOCOL Close; PBL_GET_MODULES_LIST GetModulesList; - PBL_REGISTER_XT_PROTOCOL Install; + PBL_INSTALL_XT_PROTOCOL Install; PBL_OPEN_XT_PROTOCOL Open; } Protocol; struct diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 7a3c4a1..bcb9a49 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -174,7 +174,8 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, XTCDECL EFI_STATUS -BlOpenProtocol(OUT PVOID *ProtocolHandler, +BlOpenProtocol(OUT PEFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); XTCDECL @@ -204,8 +205,8 @@ BlRegisterBootProtocol(IN PWCHAR SystemType, XTCDECL EFI_STATUS -BlInstallProtocol(IN PEFI_GUID Guid, - IN PVOID Interface); +BlInstallProtocol(IN PVOID Interface, + IN PEFI_GUID Guid); XTCDECL VOID diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c index b68dbc7..a0af50d 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.c @@ -56,5 +56,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid); /* Register DUMMY protocol as XTOS boot protocol */ - return XtLdrProto->Protocol.Install(&DummyGuid, &BlpDummyProtocol); + return XtLdrProto->Protocol.Install(&BlpDummyProtocol, &DummyGuid); } diff --git a/xtldr/modules/fb_o/framebuf.c b/xtldr/modules/fb_o/framebuf.c index 769da90..703e56e 100644 --- a/xtldr/modules/fb_o/framebuf.c +++ b/xtldr/modules/fb_o/framebuf.c @@ -88,6 +88,7 @@ FbInitializeDisplay() EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; UINT32 Parameter1, Parameter2; + EFI_HANDLE Handle; EFI_STATUS Status; /* Check if framebuffer already initialized */ @@ -99,7 +100,7 @@ FbInitializeDisplay() FrameBufferInfo.Initialized = FALSE; /* Attempt to open GOP protocol */ - Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufferInfo.Adapter.GOP, &GopGuid); + Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FrameBufferInfo.Adapter.GOP, &GopGuid); /* Check if Graphics Output Protocol is available */ if(Status == STATUS_EFI_SUCCESS) @@ -119,6 +120,9 @@ FbInitializeDisplay() FrameBufferInfo.FrameBufferSize = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferSize; FrameBufferInfo.Protocol = GOP; FrameBufferInfo.Initialized = TRUE; + + /* Close GOP protocol */ + Status = XtLdrProtocol->Protocol.Close(Handle, &GopGuid); } else { @@ -126,7 +130,7 @@ FbInitializeDisplay() FrameBufferInfo.Adapter.GOP = NULL; /* Attempt to open UGA protocol */ - Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufferInfo.Adapter.UGA, &UgaGuid); + Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FrameBufferInfo.Adapter.UGA, &UgaGuid); /* Check if Universal Graphics Adapter is available */ if(Status == STATUS_EFI_SUCCESS) @@ -162,6 +166,9 @@ FbInitializeDisplay() /* Temporarily set this to FALSE, as we don't set FB base and we cannot use it anyway */ FrameBufferInfo.Initialized = FALSE; } + + /* Close UGA protocol */ + XtLdrProtocol->Protocol.Close(Handle, &UgaGuid); } } @@ -251,5 +258,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtFramebufferProtocol.PrintDisplayInformation = FbPrintDisplayInformation; /* Register XTOS boot protocol */ - return XtLdrProtocol->Protocol.Install(&Guid, &XtFramebufferProtocol); + return XtLdrProtocol->Protocol.Install(&XtFramebufferProtocol, &Guid); } diff --git a/xtldr/modules/pecoff_o/pecoff.c b/xtldr/modules/pecoff_o/pecoff.c index 2c48a2e..36ff2f4 100644 --- a/xtldr/modules/pecoff_o/pecoff.c +++ b/xtldr/modules/pecoff_o/pecoff.c @@ -603,5 +603,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtPeCoffProtocol.RelocateImage = PeRelocateImage; /* Register PE/COFF protocol */ - return XtLdrProtocol->Protocol.Install(&Guid, &XtPeCoffProtocol); + return XtLdrProtocol->Protocol.Install(&XtPeCoffProtocol, &Guid); } diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index f7248dc..3393367 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -40,7 +40,7 @@ EFI_STATUS XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) { EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; - EFI_HANDLE DiskHandle; + EFI_HANDLE DiskHandle, ProtocolHandle; PEFI_FILE_HANDLE FsHandle, BootDir; PWCHAR SystemPath; EFI_STATUS Status; @@ -49,7 +49,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n"); /* Open the XT PE/COFF protocol */ - Status = XtLdrProtocol->Protocol.Open((PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); + Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open loader protocol */ @@ -183,6 +183,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, PVOID VirtualAddress, VirtualMemoryArea; PXT_ENTRY_POINT KernelEntryPoint; LIST_ENTRY MemoryMappings; + EFI_HANDLE ProtocolHandle; EFI_STATUS Status; /* Initialize XTOS startup sequence */ @@ -250,7 +251,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, BootDir->Close(BootDir); /* Enable paging */ - XtLdrProtocol->Protocol.Open((PVOID*)&ImageProtocol, &LoadedImageGuid); + XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid); Status = XtEnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap); if(Status != STATUS_EFI_SUCCESS) { @@ -333,6 +334,7 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, EFI_PHYSICAL_ADDRESS Address; // PVOID RuntimeServices; EFI_STATUS Status; + EFI_HANDLE ProtocolHandle; UINT BlockPages, FrameBufferPages; /* Calculate number of pages needed for initialization block */ @@ -359,7 +361,7 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; /* Load FrameBuffer protocol */ - Status = XtLdrProtocol->Protocol.Open((PVOID*)&FrameBufProtocol, &FrameBufGuid); + Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid); if(Status == STATUS_EFI_SUCCESS) { /* Make sure FrameBuffer is initialized */ @@ -375,6 +377,9 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, LoaderBlock->LoaderInformation.FrameBuffer.Protocol = NONE; } + /* Close FrameBuffer protocol */ + XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid); + /* Attempt to find virtual address of the EFI Runtime Services */ // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); // if(Status == STATUS_EFI_SUCCESS) @@ -542,5 +547,5 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid); /* Install XTOS protocol */ - return XtLdrProtocol->Protocol.Install(&Guid, &XtBootProtocol); + return XtLdrProtocol->Protocol.Install(&XtBootProtocol, &Guid); } diff --git a/xtldr/protocol.c b/xtldr/protocol.c index 7306f25..fc71f1f 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -9,6 +9,27 @@ #include +/** + * Closes a protocol on a provided handle. + * + * @param Handle + * Supplies a handle for the protocol interface that was previously opened. + * + * @param ProtocolGuid + * Supplies a unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlCloseProtocol(IN PEFI_HANDLE Handle, + IN PEFI_GUID ProtocolGuid) +{ + return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULL); +} + /** * Finds a boot protocol for specified system type. * @@ -69,6 +90,30 @@ BlGetModulesList() return &BlpLoadedModules; } +/** + * Installs XTLDR protocol interface. + * + * @param Guid + * Specifies a unique protocol GUID. + * + * @param Interface + * Supplies a pointer to the protocol interface, or NULL if there is no structure associated. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlInstallProtocol(IN PVOID Interface, + IN PEFI_GUID Guid) +{ + EFI_HANDLE Handle = NULL; + + /* Install protocol interface */ + return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); +} + /** * Loads a specified XTLDR module from disk. * @@ -355,6 +400,9 @@ BlLoadModules(IN PWCHAR ModulesList) /** * This routine locates and opens the requested XT Boot Loader or EFI protocol. * + * @param Handle + * Supplies the address where a pointer to the handle for the protocol interface. + * * @param ProtocolHandler * Supplies the address where a pointer to the opened protocol is returned. * @@ -367,7 +415,8 @@ BlLoadModules(IN PWCHAR ModulesList) */ XTCDECL EFI_STATUS -BlOpenProtocol(OUT PVOID *ProtocolHandler, +BlOpenProtocol(OUT PEFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid) { PEFI_HANDLE Handles = NULL; @@ -398,6 +447,7 @@ BlOpenProtocol(OUT PVOID *ProtocolHandler, if(Status == STATUS_EFI_SUCCESS) { /* Protocol found and successfully opened */ + *Handle = Handles[Index]; break; } } @@ -491,30 +541,6 @@ BlRegisterBootProtocol(IN PWCHAR SystemType, return STATUS_EFI_SUCCESS; } -/** - * Installs XTLDR protocol interface. - * - * @param Guid - * Specifies a unique protocol GUID. - * - * @param Interface - * Supplies a pointer to the protocol interface, or NULL if there is no structure associated. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInstallProtocol(IN PEFI_GUID Guid, - IN PVOID Interface) -{ - EFI_HANDLE Handle = NULL; - - /* Install protocol interface */ - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); -} - /** * This routine installs XTLDR protocol for further usage by modules. * @@ -554,6 +580,7 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages; BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool; BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; + BlpLdrProtocol.Protocol.Close = BlCloseProtocol; BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; BlpLdrProtocol.Protocol.Open = BlOpenProtocol; BlpLdrProtocol.Protocol.Install = BlInstallProtocol; @@ -569,5 +596,5 @@ BlpInstallXtLoaderProtocol() /* Register XTLDR loader protocol */ BlDebugPrint(L"Registering XT loader protocol\n"); - return BlInstallProtocol(&Guid, &BlpLdrProtocol); + return BlInstallProtocol(&BlpLdrProtocol, &Guid); } diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index bc23020..33cd8bf 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -22,6 +22,7 @@ BlInitializeBootLoader() { EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + EFI_HANDLE Handle; EFI_STATUS Status; /* Set current XTLDR's EFI BootServices status */ @@ -45,7 +46,7 @@ BlInitializeBootLoader() if(DEBUG) { /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenProtocol((PVOID *)&LoadedImage, &LipGuid); + Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid); if(Status == STATUS_EFI_SUCCESS) { /* Protocol opened successfully, print useful debug information */ @@ -172,6 +173,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) EFI_GUID BootProtocolGuid; SIZE_T ModuleListLength; PWCHAR ModulesList; + EFI_HANDLE Handle; EFI_STATUS Status; /* Initialize boot parameters and a list of modules */ @@ -262,7 +264,7 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) } /* Open boot protocol */ - Status = BlOpenProtocol((PVOID *)&BootProtocol, &BootProtocolGuid); + Status = BlOpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open boot protocol */ -- 2.45.1 From 91b7cd68ba2b298a736ef3d8149cec5ac8e23e3a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 19:36:16 +0100 Subject: [PATCH 177/182] Update dummy module --- xtldr/modules/dummy/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xtldr/modules/dummy/CMakeLists.txt b/xtldr/modules/dummy/CMakeLists.txt index 46bd990..801ad83 100644 --- a/xtldr/modules/dummy/CMakeLists.txt +++ b/xtldr/modules/dummy/CMakeLists.txt @@ -1,4 +1,4 @@ -# XT Boot Loader +# XT Boot Loader Dummy Module PROJECT(XTLDR_DUMMY) # Specify include directories @@ -15,7 +15,7 @@ list(APPEND XTLDR_DUMMY_SOURCE add_executable(dummy ${XTLDR_DUMMY_SOURCE}) # Add linker libraries -target_link_libraries(dummy libxtldr libxtos) +target_link_libraries(dummy libxtldr) # Set proper binary name and install target set_target_properties(dummy PROPERTIES SUFFIX .efi) -- 2.45.1 From 332a9447a3a5aa4bfd53b576839afd7a14fc8792 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 19:56:56 +0100 Subject: [PATCH 178/182] Cleanup dummy module --- xtldr/modules/dummy/dummy.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c index a0af50d..0468380 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.c @@ -2,7 +2,7 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/modules/dummy/dummy.c - * DESCRIPTION: Dummy XTLDR module + * DESCRIPTION: XTLDR Dummy Module * DEVELOPERS: Rafal Kupiec */ @@ -11,8 +11,18 @@ /* Dummy module information */ -XTBL_MODINFO = L"Dummy XTLDR module"; +XTBL_MODINFO = L"XTLDR Dummy Module"; +/** + * Stub boot routine. + * + * @param Parameters + * Supplies all parameters associated with the chosen boot menu entry. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ XTCDECL EFI_STATUS BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters) @@ -29,7 +39,7 @@ BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters) * @param SystemTable * Provides the EFI system table. * - * @return This routine returns status code. + * @return This routine returns a status code. * * @since XT 1.0 */ -- 2.45.1 From 7a18a0caeb70292fdbdabde6b07b31f63a2f65f4 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 22:51:33 +0100 Subject: [PATCH 179/182] Add 'dummy' module routines forward references --- xtldr/modules/dummy/dummy.c | 3 +-- xtldr/modules/dummy/globals.c | 2 +- xtldr/modules/dummy/includes/dummy.h | 26 ++++++++++++++++++++++++++ xtldr/modules/dummy/includes/globals.h | 4 ++-- 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 xtldr/modules/dummy/includes/dummy.h diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.c index 0468380..0628827 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.c @@ -6,8 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include -#include +#include /* Dummy module information */ diff --git a/xtldr/modules/dummy/globals.c b/xtldr/modules/dummy/globals.c index d693509..595be67 100644 --- a/xtldr/modules/dummy/globals.c +++ b/xtldr/modules/dummy/globals.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /* XTLDR protocol handler */ diff --git a/xtldr/modules/dummy/includes/dummy.h b/xtldr/modules/dummy/includes/dummy.h new file mode 100644 index 0000000..675bdbc --- /dev/null +++ b/xtldr/modules/dummy/includes/dummy.h @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/dummy/includes/dummy.h + * DESCRIPTION: XTLDR Dummy Module header file + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_DUMMY_DUMMY_H +#define __XTLDR_DUMMY_DUMMY_H + +#include +#include + + +/* Dummy module routines forward references */ +XTCDECL +EFI_STATUS +BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters); + +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif/* __XTLDR_DUMMY_DUMMY_H */ diff --git a/xtldr/modules/dummy/includes/globals.h b/xtldr/modules/dummy/includes/globals.h index fcb72c1..8fd8446 100644 --- a/xtldr/modules/dummy/includes/globals.h +++ b/xtldr/modules/dummy/includes/globals.h @@ -2,14 +2,14 @@ * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/modules/dummy/includes/globals.h - * DESCRIPTION: Dummy XTLDR module global variables + * DESCRIPTION: XTLDR Dummy Module global variables * DEVELOPERS: Rafal Kupiec */ #ifndef __XTLDR_DUMMY_GLOBALS_H #define __XTLDR_DUMMY_GLOBALS_H -#include +#include /* XTLDR protocol handler */ -- 2.45.1 From b561bc80ccc025f054c183d622e9fbf2c89bc72a Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 22:53:00 +0100 Subject: [PATCH 180/182] Allow modules to read boot loader configuration --- sdk/xtdk/bltypes.h | 5 +++++ sdk/xtdk/xtblapi.h | 1 + xtldr/protocol.c | 1 + 3 files changed, 7 insertions(+) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 1c5149a..25a5127 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -67,6 +67,7 @@ typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Paramet typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); +typedef PWCHAR (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); @@ -226,6 +227,10 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol; } Boot; struct + { + PBL_CONFIG_GET_VALUE GetValue; + } Config; + struct { PBL_CLEAR_CONSOLE_LINE ClearLine; PBL_CONSOLE_CLEAR_SCREEN ClearScreen; diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index c95e689..e13f9c4 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -43,6 +43,7 @@ /* Architecture specific XT kernel routines */ #include ARCH_HEADER(arfuncs.h) +#include ARCH_HEADER(hlfuncs.h) /* Boot Manager specific structures */ #include diff --git a/xtldr/protocol.c b/xtldr/protocol.c index fc71f1f..5cefb67 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -560,6 +560,7 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; + BlpLdrProtocol.Config.GetValue = BlGetConfigValue; BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; -- 2.45.1 From a674d2eb1b880936dc64092d3d35885ba40696ab Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 8 Jan 2024 23:17:01 +0100 Subject: [PATCH 181/182] Import 'beep' module --- xtldr/modules/CMakeLists.txt | 1 + xtldr/modules/beep/CMakeLists.txt | 27 ++++ xtldr/modules/beep/beep.c | 209 ++++++++++++++++++++++++++ xtldr/modules/beep/globals.c | 13 ++ xtldr/modules/beep/includes/beep.h | 38 +++++ xtldr/modules/beep/includes/globals.h | 18 +++ 6 files changed, 306 insertions(+) create mode 100644 xtldr/modules/beep/CMakeLists.txt create mode 100644 xtldr/modules/beep/beep.c create mode 100644 xtldr/modules/beep/globals.c create mode 100644 xtldr/modules/beep/includes/beep.h create mode 100644 xtldr/modules/beep/includes/globals.h diff --git a/xtldr/modules/CMakeLists.txt b/xtldr/modules/CMakeLists.txt index 136fbbb..375c1d7 100644 --- a/xtldr/modules/CMakeLists.txt +++ b/xtldr/modules/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(beep) add_subdirectory(dummy) add_subdirectory(fb_o) add_subdirectory(pecoff_o) diff --git a/xtldr/modules/beep/CMakeLists.txt b/xtldr/modules/beep/CMakeLists.txt new file mode 100644 index 0000000..fb81272 --- /dev/null +++ b/xtldr/modules/beep/CMakeLists.txt @@ -0,0 +1,27 @@ +# XT Boot Loader Beep Module +PROJECT(XTLDR_BEEP) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_BEEP_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_BEEP_SOURCE + ${XTLDR_BEEP_SOURCE_DIR}/beep.c + ${XTLDR_BEEP_SOURCE_DIR}/globals.c) + +# Link bootloader executable +add_executable(beep ${XTLDR_BEEP_SOURCE}) + +# Add linker libraries +target_link_libraries(beep libxtldr libxtos) + +# Set proper binary name and install target +set_target_properties(beep PROPERTIES SUFFIX .efi) +set_install_target(beep efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(beep "XtLdrModuleMain") +set_linker_map(beep TRUE) +set_subsystem(beep efi_boot_service_driver) diff --git a/xtldr/modules/beep/beep.c b/xtldr/modules/beep/beep.c new file mode 100644 index 0000000..1eab7b0 --- /dev/null +++ b/xtldr/modules/beep/beep.c @@ -0,0 +1,209 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/beep.c + * DESCRIPTION: XTLDR Beep Module + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Dummy module information */ +XTBL_MODINFO = L"Plays a GRUB compatible tune via PC speaker"; + +/** + * Disables the PC speaker. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpDisableToneBeep() +{ + UCHAR Status; + + /* Stop the PC speaker */ + Status = HlIoPortInByte(0x61); + HlIoPortOutByte(0x61, Status & 0xFC); +} + +/** + * Enables the PC speaker and plays a sound. + * + * @param Pitch + * Specifies a pitch (in Hz) of the sound. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpEnableToneBeep(IN UINT Pitch) +{ + UINT Counter; + UCHAR Status; + + /* Pitch only in range of 20..20000 */ + if(Pitch < 20) + { + Pitch = 20; + } + else if(Pitch > 20000) + { + Pitch = 20000; + } + + /* Set the desired frequency of the PIT clock */ + Counter = 0x1234DD / Pitch; + HlIoPortOutByte(0x43, 0xB6); + HlIoPortOutByte(0x43, 0xB6); + HlIoPortOutByte(0x42, (UCHAR) Counter & 0xFF); + HlIoPortOutByte(0x42, (UCHAR) (Counter >> 8) & 0xFF); + + /* Start the PC speaker */ + Status = HlIoPortInByte(0x61); + HlIoPortOutByte(0x61, Status | 0x03); +} + +/** + * This routine plays a tune. + * + * @param Arguments + * Optional list of parameters provided with the command. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +BpPlayTune(IN PWCHAR Arguments) +{ + LONG Pitch, Duration, Tempo; + PWCHAR Argument, LastArgument; + + /* Reset pitch and duration */ + Duration = -1; + Pitch = -1; + Tempo = -1; + + /* Tokenize provided list of arguments */ + Argument = RtlTokenizeWideString(Arguments, L" ", &LastArgument); + + /* Iterate over all arguments */ + while(Argument != NULL) + { + /* Check if tempo, pitch and duration are set */ + if(Tempo < 0) + { + /* Set the tempo */ + Tempo = BpWideStringToNumber(Argument); + } + else if(Pitch < 0) + { + /* Set the pitch */ + Pitch = BpWideStringToNumber(Argument); + } + else + { + /* Set the duration */ + Duration = BpWideStringToNumber(Argument); + + /* Check pitch value */ + if(Pitch > 0) + { + /* Emit the beep tone */ + BpEnableToneBeep(Pitch); + } + else + { + /* Stop emitting beep tone */ + BpDisableToneBeep(); + } + + /* Wait for duration time */ + XtLdrProto->Util.SleepExecution(60000 * Duration / Tempo); + + /* Reset pitch and duration */ + Pitch = -1; + Duration = -1; + } + + /* Get next argument */ + Argument = RtlTokenizeWideString(NULL, L" ", &LastArgument); + } + + /* Stop emitting beep tone */ + BpDisableToneBeep(); +} + +/** + * Converts a wide string into a number. + * + * @param String + * Supplies an input wide string. + * + * @return This routine returns the number that was converted from the wide string. + * + * @since XT 1.0 + */ +XTCDECL +UINT +BpWideStringToNumber(IN PWCHAR String) +{ + ULONG Number = 0; + + /* Iterate over all characters until '\0' found */ + do + { + /* Check if this is a digit */ + if(*String - '0' < 10) + { + /* Add another digit to the number */ + Number *= 10; + Number += *String - '0'; + } + } + while(*++String != L'\0'); + + /* Return number */ + return Number; +} + +/** + * This routine is the entry point of the XT EFI boot loader module. + * + * @param ImageHandle + * Firmware-allocated handle that identifies the image. + * + * @param SystemTable + * Provides the EFI system table. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_STATUS Status; + + /* Open the XTLDR protocol */ + Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProto); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open the protocol, return error */ + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Play the tune set in the configuration */ + BpPlayTune(XtLdrProto->Config.GetValue(L"TUNE")); + + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/modules/beep/globals.c b/xtldr/modules/beep/globals.c new file mode 100644 index 0000000..eb8e3cc --- /dev/null +++ b/xtldr/modules/beep/globals.c @@ -0,0 +1,13 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/globals.c + * DESCRIPTION: Dummy XTLDR module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL XtLdrProto; diff --git a/xtldr/modules/beep/includes/beep.h b/xtldr/modules/beep/includes/beep.h new file mode 100644 index 0000000..db0af8f --- /dev/null +++ b/xtldr/modules/beep/includes/beep.h @@ -0,0 +1,38 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/includes/beep.h + * DESCRIPTION: XTLDR Beep Module header file + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_BEEP_BEEP_H +#define __XTLDR_BEEP_BEEP_H + +#include +#include + + +/* Beep module routines forward references */ +XTCDECL +VOID +BpDisableToneBeep(); + +XTCDECL +VOID +BpEnableToneBeep(IN UINT Pitch); + +XTCDECL +VOID +BpPlayTune(IN PWCHAR Arguments); + +XTCDECL +UINT +BpWideStringToNumber(IN PWCHAR String); + +XTCDECL +EFI_STATUS +XtLdrModuleMain(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable); + +#endif/* __XTLDR_BEEP_BEEP_H */ diff --git a/xtldr/modules/beep/includes/globals.h b/xtldr/modules/beep/includes/globals.h new file mode 100644 index 0000000..ee5bff0 --- /dev/null +++ b/xtldr/modules/beep/includes/globals.h @@ -0,0 +1,18 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/beep/includes/globals.h + * DESCRIPTION: XTLDR Beep Module global variables + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_BEEP_GLOBALS_H +#define __XTLDR_BEEP_GLOBALS_H + +#include + + +/* XTLDR protocol handler */ +EXTERN PXTBL_LOADER_PROTOCOL XtLdrProto; + +#endif/* __XTLDR_BEEP_GLOBALS_H */ -- 2.45.1 From cb4bd3db8b3842215f66e04c2d274faa43b9f764 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 9 Jan 2024 16:24:57 +0100 Subject: [PATCH 182/182] Return a copy of config value, so that it won't get altered --- xtldr/config.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/xtldr/config.c b/xtldr/config.c index 763a03d..c2e8569 100644 --- a/xtldr/config.c +++ b/xtldr/config.c @@ -25,10 +25,12 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName) { PXTBL_CONFIG_ENTRY ConfigEntry; PLIST_ENTRY ConfigListEntry; - SIZE_T Length; + SIZE_T KeyLength, ValueLength; + EFI_STATUS Status; + PWCHAR Value; /* Get config entry name length */ - Length = RtlWideStringLength(ConfigName, 0); + KeyLength = RtlWideStringLength(ConfigName, 0); /* Iterate through config entries */ ConfigListEntry = BlpConfig.Flink; @@ -38,10 +40,24 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName) ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); /* Check if requested configuration found */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, KeyLength) == 0) { - /* Return config value */ - return ConfigEntry->Value; + /* Get value length */ + ValueLength = RtlWideStringLength(ConfigEntry->Value, 0); + + /* Allocate memory for value */ + Status = BlMemoryAllocatePool(ValueLength * sizeof(WCHAR), (PVOID *)&Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, return NULL */ + BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); + return NULL; + } + + /* Copy value and return it */ + RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); + Value[ValueLength] = 0; + return Value; } /* Move to the next config entry */ -- 2.45.1