/** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/xtldr.c * DESCRIPTION: XTOS UEFI Boot Loader * DEVELOPERS: Rafal Kupiec */ #include XTCDECL VOID BlDisplayBootMenu(); /** * Initializes a list of operating systems for XTLDR boot menu. * * @param MenuEntries * Supplies a pointer to memory area where operating systems list will be stored. * * @param EntriesCount * Supplies a pointer to memory area where number of menu entries will be stored. * * @param DefaultId * Supplies a pointer to memory area where ID of default menu entry will be stored. * * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL VOID BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId) { PWCHAR DefaultMenuEntry, MenuEntryName; PLIST_ENTRY MenuEntrySectionList, MenuEntryList; PXTBL_CONFIG_SECTION MenuEntrySection; PXTBL_CONFIG_ENTRY MenuEntryOption; PXTBL_BOOTMENU_ITEM OsList; ULONG DefaultOS, NumberOfEntries; /* Set default values */ DefaultOS = 0; NumberOfEntries = 0; OsList = NULL; /* Get default menu entry from configuration */ DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); /* Iterate through all menu sections */ MenuEntrySectionList = BlpMenuList->Flink; while(MenuEntrySectionList != BlpMenuList) { /* NULLify menu entry name */ MenuEntryName = NULL; /* Get menu section */ MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); /* Check if this is the default menu entry */ if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0) { /* Set default OS ID */ DefaultOS = NumberOfEntries; } /* Iterate through all entry parameters */ MenuEntryList = MenuEntrySection->Options.Flink; while(MenuEntryList != &MenuEntrySection->Options) { /* Get menu entry parameter */ MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); /* Check if this is the menu entry display name */ if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) { /* Set menu entry display name */ MenuEntryName = MenuEntryOption->Value; } /* Get next parameter for this menu entry */ MenuEntryList = MenuEntryList->Flink; } /* Add OS to the boot menu list */ OsList[NumberOfEntries].EntryName = MenuEntryName; OsList[NumberOfEntries].Options = &MenuEntrySection->Options; /* Get next menu entry */ MenuEntrySectionList = MenuEntrySectionList->Flink; NumberOfEntries++; } /* Set return values */ *DefaultId = DefaultOS; *EntriesCount = NumberOfEntries; MenuEntries = OsList; } /** * This routine is the entry point of the XT EFI boot loader. * * @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 */ BlpInitializeEfiBootLoader(); /* 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"); } /* 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"); } for(;;) { if(BlpStatus.BootMenu != NULL) { /* Display alternative boot menu */ BlpStatus.BootMenu(); } else { /* Display default boot menu */ BlDisplayBootMenu(); } } /* This point should be never reached, if this happen return error code */ return STATUS_EFI_LOAD_ERROR; }