EFI_STATUS BdsLoadOptionFileSystemCreateDevicePath ( IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes ) { EFI_STATUS Status; FILEPATH_DEVICE_PATH* FilePathDevicePath; CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; UINTN BootFilePathSize; Print(L"File path of the %s: ", FileName); Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); if (EFI_ERROR(Status)) { return EFI_ABORTED; } BootFilePathSize = StrSize (BootFilePath); if (BootFilePathSize == 2) { *DevicePathNodes = NULL; return EFI_NOT_FOUND; } // Create the FilePath Device Path node FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath; return Status; }
EFI_STATUS BdsLoadOptionMemMapCreateDevicePath ( IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes ) { EFI_STATUS Status; MEMMAP_DEVICE_PATH *MemMapDevicePath; CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; Print(L"Starting Address of the %s: ", FileName); Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX); if (EFI_ERROR(Status)) { return EFI_ABORTED; } Print(L"Ending Address of the %s: ", FileName); Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX); if (EFI_ERROR(Status)) { return EFI_ABORTED; } // Create the MemMap Device Path Node MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH); if (NULL == MemMapDevicePath) { return EFI_OUT_OF_RESOURCES; } MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH; MemMapDevicePath->Header.SubType = HW_MEMMAP_DP; SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH)); MemMapDevicePath->MemoryType = EfiBootServicesData; MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress); MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress); // Set a Device Path End Node after the Memory Map Device Path Node SetDevicePathEndNode (MemMapDevicePath + 1); *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath; return Status; }
EFI_STATUS GetHIInputBoolean ( OUT BOOLEAN *Value ) { CHAR16 CmdBoolean[2]; EFI_STATUS Status; while(1) { Print (L"[y/n] "); Status = GetHIInputStr (CmdBoolean, 2); if (EFI_ERROR(Status)) { return Status; } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) { if (Value) *Value = TRUE; return EFI_SUCCESS; } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) { if (Value) *Value = FALSE; return EFI_SUCCESS; } } }
EFI_STATUS BdsLoadOptionTftpCreateDevicePath ( IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes ) { EFI_STATUS Status; BOOLEAN IsDHCP; EFI_IP_ADDRESS LocalIp; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS GatewayIp; EFI_IP_ADDRESS RemoteIp; IPv4_DEVICE_PATH *IPv4DevicePathNode; FILEPATH_DEVICE_PATH *FilePathDevicePath; CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; UINTN BootFilePathSize; Print (L"Get the IP address from DHCP: "); Status = GetHIInputBoolean (&IsDHCP); if (EFI_ERROR (Status)) { return EFI_ABORTED; } if (!IsDHCP) { Print (L"Local static IP address: "); Status = GetHIInputIP (&LocalIp); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Print (L"Get the network mask: "); Status = GetHIInputIP (&SubnetMask); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Print (L"Get the gateway IP address: "); Status = GetHIInputIP (&GatewayIp); if (EFI_ERROR (Status)) { return EFI_ABORTED; } } Print (L"Get the TFTP server IP address: "); Status = GetHIInputIP (&RemoteIp); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Print (L"File path of the %s : ", FileName); Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); if (EFI_ERROR (Status)) { return EFI_ABORTED; } BootFilePathSize = StrSize(BootFilePath); if (BootFilePathSize == 2) { return EFI_NOT_FOUND; } // Allocate the memory for the IPv4 + File Path Device Path Nodes IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); if (NULL == IPv4DevicePathNode) { return EFI_INVALID_PARAMETER; } // Create the IPv4 Device Path IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH; IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP; SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH)); if (!IsDHCP) { CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS)); } CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); IPv4DevicePathNode->LocalPort = 0; IPv4DevicePathNode->RemotePort = 0; IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP; IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE); // Create the FilePath Device Path node FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1); FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); // Set the End Device Path Node SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode; return Status; }
EFI_STATUS BootMenuAddBootOption ( IN LIST_ENTRY *BootOptionsList ) { EFI_STATUS Status; BDS_SUPPORTED_DEVICE* SupportedBootDevice; ARM_BDS_LOADER_ARGUMENTS* BootArguments; CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; CHAR8 AsciiCmdLine[BOOT_DEVICE_OPTION_MAX]; CHAR16 CmdLine[BOOT_DEVICE_OPTION_MAX]; UINT32 Attributes; ARM_BDS_LOADER_TYPE BootType; BDS_LOAD_OPTION_ENTRY *BdsLoadOptionEntry; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPathNodes; EFI_DEVICE_PATH_PROTOCOL *InitrdPath; UINTN CmdLineSize; BOOLEAN InitrdSupport; UINTN InitrdSize; UINT8* OptionalData; UINTN OptionalDataSize; Attributes = 0; SupportedBootDevice = NULL; // List the Boot Devices supported Status = SelectBootDevice (&SupportedBootDevice); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } // Append the Device Path to the selected device path DevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNodes); if (DevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } if (SupportedBootDevice->Support->RequestBootType) { Status = BootDeviceGetType (DevicePath, &BootType, &Attributes); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } } else { BootType = BDS_LOADER_EFI_APPLICATION; } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { Print(L"Add an initrd: "); Status = GetHIInputBoolean (&InitrdSupport); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto EXIT; } if (InitrdSupport) { // Create the specific device path node Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes); if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd Status = EFI_ABORTED; goto EXIT; } if (InitrdPathNodes != NULL) { // Append the Device Path to the selected device path InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes); // Free the InitrdPathNodes created by Support->CreateDevicePathNode() FreePool (InitrdPathNodes); if (InitrdPath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto EXIT; } } else { InitrdPath = NULL; } } else { InitrdPath = NULL; } Print(L"Arguments to pass to the binary: "); Status = GetHIInputAscii (AsciiCmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } CmdLineSize = AsciiStrSize (AsciiCmdLine); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); BootArguments->LinuxArguments.CmdLineSize = CmdLineSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(&BootArguments->LinuxArguments + 1), AsciiCmdLine, CmdLineSize); CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { Print (L"Arguments to pass to the EFI Application: "); Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto EXIT; } OptionalData = (UINT8*)CmdLine; OptionalDataSize = StrSize (CmdLine); } Print(L"Description for this new Entry: "); Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); if (EFI_ERROR(Status)) { Status = EFI_ABORTED; goto FREE_DEVICE_PATH; } // Create new entry BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY)); Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption); if (!EFI_ERROR(Status)) { InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link); } FREE_DEVICE_PATH: FreePool (DevicePath); EXIT: if (Status == EFI_ABORTED) { Print(L"\n"); } FreePool(SupportedBootDevice); return Status; }