diff --git a/sdk/xtdk/xttarget.h b/sdk/xtdk/xttarget.h index b686c43..0545779 100644 --- a/sdk/xtdk/xttarget.h +++ b/sdk/xtdk/xttarget.h @@ -21,11 +21,13 @@ #define _ARCH_I686 1 #define _XT32 1 #define EFI_ERROR_MASK 0x80000000 + #define XTOS_KERNEL_ADDRESS 0x81800000 #elif defined(__amd64__) || defined(__x86_64__) #define _ARCH amd64 #define _ARCH_AMD64 1 #define _XT64 1 #define EFI_ERROR_MASK 0x8000000000000000 + #define XTOS_KERNEL_ADDRESS 0xFFFFF80800000000 #else #error Unknown architecture #endif diff --git a/xtldr/includes/blmod.h b/xtldr/includes/blmod.h index 3194e93..a469f79 100644 --- a/xtldr/includes/blmod.h +++ b/xtldr/includes/blmod.h @@ -15,11 +15,32 @@ /* 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 EFI_STATUS (*PXT_PECOFF_PROTOCOL_LOAD)(IN PEFI_FILE_HANDLE FileHandle, IN PVOID VirtualAddress, OUT PPECOFF_IMAGE_CONTEXT *Image); +/* 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; + /* EFI XT PE/COFF Image Protocol */ typedef struct _XT_PECOFFF_IMAGE_PROTOCOL { diff --git a/xtldr/modules/xtos/CMakeLists.txt b/xtldr/modules/xtos/CMakeLists.txt index 83cd62e..b6d2d74 100644 --- a/xtldr/modules/xtos/CMakeLists.txt +++ b/xtldr/modules/xtos/CMakeLists.txt @@ -4,7 +4,8 @@ PROJECT(XTLDR_XTOS) # Specify include directories include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_SOURCE_DIR}/includes) + ${XTLDR_SOURCE_DIR}/includes + ${XTLDR_XTOS_SOURCE_DIR}/includes) # Specify list of source code files list(APPEND XTLDR_XTOS_SOURCE diff --git a/xtldr/modules/xtos/includes/xtos.h b/xtldr/modules/xtos/includes/xtos.h new file mode 100644 index 0000000..2041afa --- /dev/null +++ b/xtldr/modules/xtos/includes/xtos.h @@ -0,0 +1,26 @@ +/** + * 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_STATUS +XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); + +EFI_STATUS +XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, + IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); + +EFI_STATUS +BlXtLdrModuleMain(EFI_HANDLE ImageHandle, + PEFI_SYSTEM_TABLE SystemTable); + +#endif /* __XTLDR_MODULES_XTOS_H */ diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index 4fcd8a5..e011865 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include /* EFI Image Handle */ @@ -16,7 +16,178 @@ EFI_HANDLE EfiImageHandle; PEFI_SYSTEM_TABLE EfiSystemTable; /* EFI XT Loader Protocol */ -PXT_BOOT_LOADER_PROTOCOL EfiXtLdrProtocol; +PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; + +/* XTOS PE/COFF Image Protocol */ +PXT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol; + +/* XTOS Boot Protocol */ +XT_BOOT_PROTOCOL XtBootProtocol; + +/** + * 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 + */ +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"; + } + + 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"; + } + + /* Print a debug message */ + XtLdrProtocol->DbgPrint(L"ARC Path: %S\nSystem Path: %S\nKernel File: %S\nBoot 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 */ + RtlWideStringConcatenate(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 Parameters + * Input parameters with detailed system configuration like boot device or kernel path. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, + IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters) +{ + PEFI_FILE_HANDLE KernelHandle; + EFI_STATUS Status; + + XtLdrProtocol->DbgPrint(L"Issuing XT startup sequence\n"); + + /* Open kernel file */ + Status = BootDir->Open(BootDir, &KernelHandle, Parameters->KernelFile, EFI_FILE_MODE_READ, 0); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to open the file */ + XtLdrProtocol->DbgPrint(L"ERROR: Failed to open the XTOS kernel\n"); + return Status; + } + + /* Load the PE/COFF kernel file */ + Status = XtPeCoffProtocol->Load(KernelHandle, (PVOID)XTOS_KERNEL_ADDRESS, NULL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to load the file */ + XtLdrProtocol->DbgPrint(L"ERROR: Failed to load the XTOS kernel\n"); + return Status; + } + + /* Close kernel file */ + KernelHandle->Close(KernelHandle); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} /** * This routine is the entry point of the XT EFI boot loader module. @@ -35,6 +206,8 @@ EFI_STATUS BlXtLdrModuleMain(EFI_HANDLE ImageHandle, 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 */ @@ -42,13 +215,16 @@ BlXtLdrModuleMain(EFI_HANDLE ImageHandle, EfiSystemTable = SystemTable; /* Open the XTLDR protocol */ - Status = BlGetXtLoaderProtocol(&EfiXtLdrProtocol); + Status = BlGetXtLoaderProtocol(&XtLdrProtocol); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open loader protocol */ return STATUS_EFI_PROTOCOL_ERROR; } - /* Return success */ - return STATUS_EFI_SUCCESS; + /* Set routines available via XTOS boot protocol */ + XtBootProtocol.BootSystem = XtBootSystem; + + /* Register XTOS boot protocol */ + return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE, &XtBootProtocol); }