EFI_STATUS efi_set_volroot(EFI_HANDLE device_handle) { vol_root = LibOpenRoot(device_handle); if (!vol_root) { return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
static EFI_STATUS egFindESP(OUT EFI_FILE_HANDLE *RootDir) { EFI_STATUS Status; UINTN HandleCount = 0; EFI_HANDLE *Handles; Status = LibLocateHandle(ByProtocol, &ESPGuid, NULL, &HandleCount, &Handles); if (!EFI_ERROR(Status) && HandleCount > 0) { *RootDir = LibOpenRoot(Handles[0]); if (*RootDir == NULL) Status = EFI_NOT_FOUND; FreePool(Handles); } return Status; }
/** This function build the FsOptionMenu list which records all available file system in the system. They includes all instances of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM. @retval EFI_SUCCESS Success find the file system @retval EFI_OUT_OF_RESOURCES Can not create menu entry **/ EFI_STATUS LibFindFileSystem ( VOID ) { UINTN NoSimpleFsHandles; EFI_HANDLE *SimpleFsHandle; UINT16 *VolumeLabel; UINTN Index; EFI_STATUS Status; MENU_ENTRY *MenuEntry; FILE_CONTEXT *FileContext; UINTN OptionNumber; EFI_FILE_SYSTEM_VOLUME_LABEL *Info; NoSimpleFsHandles = 0; OptionNumber = 0; // // Locate Handles that support Simple File System protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoSimpleFsHandles, &SimpleFsHandle ); if (!EFI_ERROR (Status)) { // // Find all the instances of the File System prototocol // for (Index = 0; Index < NoSimpleFsHandles; Index++) { // // Allocate pool for this load option // MenuEntry = LibCreateMenuEntry (); if (NULL == MenuEntry) { FreePool (SimpleFsHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->DeviceHandle = SimpleFsHandle[Index]; FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle); if (FileContext->FileHandle == NULL) { LibDestroyMenuEntry (MenuEntry); continue; } MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle)); FileContext->FileName = LibStrDuplicate (L"\\"); FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName); FileContext->IsDir = TRUE; FileContext->IsRoot = TRUE; // // Get current file system's Volume Label // Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid); if (Info == NULL) { VolumeLabel = L"NO FILE SYSTEM INFO"; } else { if (Info->VolumeLabel == NULL) { VolumeLabel = L"NULL VOLUME LABEL"; } else { VolumeLabel = Info->VolumeLabel; if (*VolumeLabel == 0x0000) { VolumeLabel = L"NO VOLUME LABEL"; } } } MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); UnicodeSPrint ( MenuEntry->DisplayString, MAX_CHAR, L"%s, [%s]", VolumeLabel, MenuEntry->HelpString ); MenuEntry->DisplayStringToken = HiiSetString ( gFileExplorerPrivate.FeHiiHandle, 0, MenuEntry->DisplayString, NULL ); if (Info != NULL) FreePool (Info); OptionNumber++; InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link); } } if (NoSimpleFsHandles != 0) { FreePool (SimpleFsHandle); } gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber; return EFI_SUCCESS; }
EFI_STATUS EFIAPI EBounceMain (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS Status; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; EFI_CONSOLE_CONTROL_SCREEN_MODE currentMode; EFI_LOADED_IMAGE *SelfLoadedImage; EFI_FILE *RootDir; EFI_FILE *BootFile; EFI_DEVICE_PATH *DevicePath; CHAR16 *DevicePathAsString; CHAR16 DirName[256]; CHAR16 FileName[256]; UINTN i, FileNameIndex; EFI_HANDLE LoaderHandle; InitializeLib(ImageHandle, SystemTable); // switch to text mode if (BS->LocateProtocol(&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl) == EFI_SUCCESS) { ConsoleControl->GetMode(ConsoleControl, ¤tMode, NULL, NULL); if (currentMode == EfiConsoleControlScreenGraphics) ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText); } /// load elilo.efi or e.efi from the same directory // get loaded image protocol for ourselves if (BS->HandleProtocol(ImageHandle, &LoadedImageProtocol, (VOID*)&SelfLoadedImage) != EFI_SUCCESS) { Print(L"Can not retrieve a LoadedImageProtocol handle for ImageHandle\n"); return EFI_NOT_FOUND; } // open volume RootDir = LibOpenRoot(SelfLoadedImage->DeviceHandle); if (RootDir == NULL) { Print(L"Can't open volume.\n"); return EFI_NOT_FOUND; } // find the current directory DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath); if (DevicePathAsString != NULL) { StrCpy(DirName, DevicePathAsString); FreePool(DevicePathAsString); for (i = StrLen(DirName) - 1; i > 0 && DirName[i] != '\\'; i--) ; DirName[i++] = '\\'; DirName[i] = 0; } else { StrCpy(DirName, L"\\"); } for (FileNameIndex = 0; FileNames[FileNameIndex]; FileNameIndex++) { // build full absolute path name StrCpy(FileName, DirName); StrCat(FileName, FileNames[FileNameIndex]); // check for presence of the file if (RootDir->Open(RootDir, &BootFile, FileName, EFI_FILE_MODE_READ, 0) != EFI_SUCCESS) continue; BootFile->Close(BootFile); // make a full device path for the image file DevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, FileName); // load the image into memory Status = BS->LoadImage(FALSE, ImageHandle, DevicePath, NULL, 0, &LoaderHandle); FreePool(DevicePath); if (EFI_ERROR(Status)) { Print(L"Can not load the file %s\n", FileName); return Status; } // start it! BS->StartImage(LoaderHandle, NULL, NULL); // just in case we get control back... break; } return EFI_SUCCESS; }
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { EFI_LOADED_IMAGE *loaded_image; EFI_FILE *root_dir; CHAR16 *loaded_image_path; CHAR8 *b; UINTN size; BOOLEAN secure = FALSE; CHAR8 *sections[] = { (UINT8 *)".cmdline", (UINT8 *)".linux", (UINT8 *)".initrd", (UINT8 *)".splash", NULL }; UINTN addrs[ELEMENTSOF(sections)-1] = {}; UINTN offs[ELEMENTSOF(sections)-1] = {}; UINTN szs[ELEMENTSOF(sections)-1] = {}; CHAR8 *cmdline = NULL; UINTN cmdline_len; CHAR16 uuid[37]; EFI_STATUS err; InitializeLib(image, sys_table); err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(err)) { Print(L"Error getting a LoadedImageProtocol handle: %r ", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return err; } root_dir = LibOpenRoot(loaded_image->DeviceHandle); if (!root_dir) { Print(L"Unable to open root directory: %r ", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return EFI_LOAD_ERROR; } loaded_image_path = DevicePathToStr(loaded_image->FilePath); if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) { if (*b > 0) secure = TRUE; FreePool(b); } err = pefile_locate_sections(root_dir, loaded_image_path, sections, addrs, offs, szs); if (EFI_ERROR(err)) { Print(L"Unable to locate embedded .linux section: %r ", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return err; } if (szs[0] > 0) cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]); cmdline_len = szs[0]; /* if we are not in secure boot mode, accept a custom command line and replace the built-in one */ if (!secure && loaded_image->LoadOptionsSize > 0) { CHAR16 *options; CHAR8 *line; UINTN i; options = (CHAR16 *)loaded_image->LoadOptions; cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8); line = AllocatePool(cmdline_len); for (i = 0; i < cmdline_len; i++) line[i] = options[i]; cmdline = line; #ifdef SD_BOOT_LOG_TPM /* Try to log any options to the TPM, escpecially manually edited options */ err = tpm_log_event(SD_TPM_PCR, (EFI_PHYSICAL_ADDRESS) loaded_image->LoadOptions, loaded_image->LoadOptionsSize, loaded_image->LoadOptions); if (EFI_ERROR(err)) { Print(L"Unable to add image options measurement: %r", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return err; } #endif } /* export the device path this image is started from */ if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); if (szs[3] > 0) graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL); err = linux_exec(image, cmdline, cmdline_len, (UINTN)loaded_image->ImageBase + addrs[1], (UINTN)loaded_image->ImageBase + addrs[2], szs[2]); graphics_mode(FALSE); Print(L"Execution of embedded linux image failed: %r\n", err); uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); return err; }