From 2f8820a021454667d1f25e0b38567eb239c8a69d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 4 Jan 2024 22:47:40 +0100 Subject: [PATCH] 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; -}