STATIC EFI_STATUS TryRemovableDevice ( IN EFI_DEVICE_PATH* DevicePath, OUT EFI_HANDLE* DeviceHandle, OUT EFI_DEVICE_PATH** NewDevicePath ) { EFI_STATUS Status; UINTN Index; EFI_DEVICE_PATH* TmpDevicePath; BDS_REMOVABLE_DEVICE_SUPPORT* RemovableDevice; EFI_DEVICE_PATH* RemovableDevicePath; BOOLEAN RemovableFound; RemovableDevice = NULL; RemovableDevicePath = NULL; RemovableFound = FALSE; TmpDevicePath = DevicePath; while (!IsDevicePathEnd (TmpDevicePath) && !RemovableFound) { for (Index = 0; Index < sizeof(RemovableDeviceSupport) / sizeof(BDS_REMOVABLE_DEVICE_SUPPORT); Index++) { RemovableDevice = &RemovableDeviceSupport[Index]; if (RemovableDevice->IsRemovable(TmpDevicePath)) { RemovableDevicePath = TmpDevicePath; RemovableFound = TRUE; break; } } TmpDevicePath = NextDevicePathNode (TmpDevicePath); } if (!RemovableFound) { return EFI_NOT_FOUND; } // Search into the current started drivers Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath); if (Status == EFI_NOT_FOUND) { // Connect all the drivers BdsConnectAllDrivers (); // Search again into all the drivers Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath); } return Status; }
EFI_STATUS EblDevicePaths ( IN UINTN Argc, IN CHAR8 **Argv ) { EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINTN Index; CHAR16* String; EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; BdsConnectAllDrivers(); Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (EFI_ERROR (Status)) { AsciiPrint ("Did not find the DevicePathToTextProtocol.\n"); return EFI_SUCCESS; } Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { AsciiPrint ("No device path found\n"); return EFI_SUCCESS; } for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); String = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE); Print (L"[0x%X] %s\n",(UINTN)HandleBuffer[Index], String); } return EFI_SUCCESS; }
STATIC EFI_STATUS InitializeConsolePipe ( IN EFI_DEVICE_PATH *ConsoleDevicePaths, IN EFI_GUID *Protocol, OUT EFI_HANDLE *Handle, OUT VOID* *Interface ) { EFI_STATUS Status; UINTN Size; UINTN NoHandles; EFI_HANDLE *Buffer; EFI_DEVICE_PATH_PROTOCOL* DevicePath; // Connect all the Device Path Consoles while (ConsoleDevicePaths != NULL) { DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size); Status = BdsConnectDevicePath (DevicePath, Handle, NULL); DEBUG_CODE_BEGIN(); if (EFI_ERROR(Status)) { // We convert back to the text representation of the device Path EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; EFI_STATUS Status; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); if (!EFI_ERROR(Status)) { DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE); DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status)); FreePool (DevicePathTxt); } } DEBUG_CODE_END(); // If the console splitter driver is not supported by the platform then use the first Device Path // instance for the console interface. if (!EFI_ERROR(Status) && (*Interface == NULL)) { Status = gBS->HandleProtocol (*Handle, Protocol, Interface); } } // No Device Path has been defined for this console interface. We take the first protocol implementation if (*Interface == NULL) { Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); if (EFI_ERROR (Status)) { BdsConnectAllDrivers(); Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); } if (!EFI_ERROR(Status)) { *Handle = Buffer[0]; Status = gBS->HandleProtocol (*Handle, Protocol, Interface); ASSERT_EFI_ERROR(Status); FreePool (Buffer); } } else { Status = EFI_SUCCESS; } return Status; }
STATIC EFI_STATUS SelectBootDevice ( OUT BDS_SUPPORTED_DEVICE** SupportedBootDevice ) { EFI_STATUS Status; LIST_ENTRY SupportedDeviceList; UINTN SupportedDeviceCount; LIST_ENTRY* Entry; UINTN SupportedDeviceSelected; UINTN Index; // // List the Boot Devices supported // // Start all the drivers first BdsConnectAllDrivers (); // List the supported devices Status = BootDeviceListSupportedInit (&SupportedDeviceList); ASSERT_EFI_ERROR(Status); SupportedDeviceCount = 0; for (Entry = GetFirstNode (&SupportedDeviceList); !IsNull (&SupportedDeviceList,Entry); Entry = GetNextNode (&SupportedDeviceList,Entry) ) { *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); Print(L"[%d] %s\n",SupportedDeviceCount+1,(*SupportedBootDevice)->Description); DEBUG_CODE_BEGIN(); CHAR16* DevicePathTxt; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ((*SupportedBootDevice)->DevicePathProtocol,TRUE,TRUE); Print(L"\t- %s\n",DevicePathTxt); FreePool(DevicePathTxt); DEBUG_CODE_END(); SupportedDeviceCount++; } if (SupportedDeviceCount == 0) { Print(L"There is no supported device.\n"); Status = EFI_ABORTED; goto EXIT; } // // Select the Boot Device // SupportedDeviceSelected = 0; while (SupportedDeviceSelected == 0) { Print(L"Select the Boot Device: "); Status = GetHIInputInteger (&SupportedDeviceSelected); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } else if ((SupportedDeviceSelected == 0) || (SupportedDeviceSelected > SupportedDeviceCount)) { Print(L"Invalid input (max %d)\n",SupportedDeviceCount); SupportedDeviceSelected = 0; } } // // Get the Device Path for the selected boot device // Index = 1; for (Entry = GetFirstNode (&SupportedDeviceList); !IsNull (&SupportedDeviceList,Entry); Entry = GetNextNode (&SupportedDeviceList,Entry) ) { if (Index == SupportedDeviceSelected) { *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); break; } Index++; } EXIT: BootDeviceListSupportedFree (&SupportedDeviceList, *SupportedBootDevice); return Status; }
EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath; EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath; UINTN FdtDevicePathSize; UINTN CmdLineSize; UINTN InitrdSize; EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { Status = EFI_UNSUPPORTED; OptionalData = BootOption->OptionalData; LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if (LoaderType == BDS_LOADER_EFI_APPLICATION) { if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { // Need to connect every drivers to ensure no dependencies are missing for the application BdsConnectAllDrivers (); } Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxAtag (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1)); // CmdLine } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } // Get the default FDT device path Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR(Status); DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); // Get the FDT device path FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath); Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid, DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath); ASSERT_EFI_ERROR(Status); Status = BdsBootLinuxFdt (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1), FdtDevicePath); FreePool (DefaultFdtDevicePath); FreePool (FdtDevicePath); } } else { // Connect all the drivers if the EFI Application is not a EFI OS Loader if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { BdsConnectAllDrivers (); } // Set BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); // Clear BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); } return Status; }
EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { EFI_STATUS Status; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; UINTN CmdLineSize; UINTN InitrdSize; EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { Status = EFI_UNSUPPORTED; OptionalData = BootOption->OptionalData; LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if (LoaderType == BDS_LOADER_EFI_APPLICATION) { if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { // Need to connect every drivers to ensure no dependencies are missing for the application BdsConnectAllDrivers (); } Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxAtag (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1)); // CmdLine } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxFdt ( BootOption->FilePathList, Initrd, (CHAR8*)(LinuxArguments + 1) ); } } else { // Connect all the drivers if the EFI Application is not a EFI OS Loader if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { BdsConnectAllDrivers (); } // Set BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); // Clear BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); } return Status; }