EFI_STATUS\r
BdsBootLinux (\r
IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
- IN CONST CHAR8* Arguments,\r
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+ IN CONST CHAR8* Arguments,\r
IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
);\r
\r
EFI_STATUS\r
BdsBootLinux (\r
IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
IN CONST CHAR8* Arguments,\r
IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
);\r
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/BdsLib.h>
-#include <Library/BdsUnixLib.h>
#include <Library/PerformanceLib.h>
#include <Guid/FileInfo.h>
EFI_STATUS
PrepareAtagList (
IN CONST CHAR8* CommandLineString,
+ IN EFI_PHYSICAL_ADDRESS InitrdImage,
+ IN UINTN InitrdImageSize,
OUT LINUX_ATAG **AtagBase,
OUT UINT32 *AtagSize
)
// CommandLine setting root device
SetupCmdlineTag (CommandLineString);
+ if (InitrdImageSize > 0 && InitrdImage != 0) {
+ mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);
+ mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;
+
+ mLinuxKernelCurrentAtag->body.initrd2_tag.start = (UINT32)InitrdImage;
+ mLinuxKernelCurrentAtag->body.initrd2_tag.size = (UINT32)InitrdImageSize;
+
+ // Move pointer to next tag
+ mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
+ }
+
// end of tags
SetupEndTag();
EFI_STATUS
BdsBootLinux (
IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
IN CONST CHAR8* Arguments,
IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
)
{
EFI_STATUS Status;
UINT32 LinuxImageSize;
+ UINT32 InitrdImageSize;
UINT32 KernelParamsSize;
EFI_PHYSICAL_ADDRESS KernelParamsAddress;
UINT32 MachineType;
BOOLEAN FdtSupported = FALSE;
LINUX_KERNEL LinuxKernel;
- EFI_PHYSICAL_ADDRESS LinuxImage;;
+ EFI_PHYSICAL_ADDRESS LinuxImage;
+ EFI_PHYSICAL_ADDRESS InitrdImage;
PERF_START (NULL, "BDS", NULL, 0);
}
LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;
+ if (InitrdDevicePath) {
+ InitrdImageSize = 0;
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find initrd image.\n");
+ return Status;
+ }
+ }
+
if (FdtDevicePath) {
// Load the FDT binary from a device path
KernelParamsAddress = LINUX_ATAG_MAX_OFFSET;
MachineType = PcdGet32(PcdArmMachineType);
// By setting address=0 we leave the memory allocation to the function
- Status = PrepareAtagList (Arguments, (LINUX_ATAG**)&KernelParamsAddress, &KernelParamsSize);
+ Status = PrepareAtagList (Arguments, InitrdImage, InitrdImageSize, (LINUX_ATAG**)&KernelParamsAddress, &KernelParamsSize);
if(EFI_ERROR(Status)) {
Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);
goto Exit;
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Platform"|VOID*|0x00000019
gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Default Boot Device"|VOID*|0x0000000C
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L""|VOID*|0x0000000D
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L""|VOID*|0x0000000E
gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|""|VOID*|0x000000F
# PcdDefaultBootType define the type of the binary pointed by PcdDefaultBootDevicePath:
# - 0 = an EFI application
EFI_STATUS Status;
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;
EFI_DEVICE_PATH* BootDevicePath;
+ BDS_LOADER_ARGUMENTS BootArguments;
+ BDS_LOADER_TYPE BootType;
//
// If Boot Order does not exist then create a default entry
// Create the entry is the Default values are correct
if (BootDevicePath != NULL) {
+ BootType = (BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType);
+
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG) {
+ BootArguments.LinuxAtagArguments.CmdLine[0] = '\0';
+ AsciiStrnCpy (BootArguments.LinuxAtagArguments.CmdLine,(CHAR8*)PcdGetPtr(PcdDefaultBootArgument),BOOT_DEVICE_OPTION_MAX);
+ BootArguments.LinuxAtagArguments.InitrdPathList = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath));
+ }
+
BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,
(CHAR16*)PcdGetPtr(PcdDefaultBootDescription),
BootDevicePath,
- (BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType),
- (CHAR8*)PcdGetPtr(PcdDefaultBootArgument),
+ BootType,
+ &BootArguments,
&BdsLoadOption
);
FreePool (BdsLoadOption);
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor
gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath
gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument
gArmPlatformTokenSpaceGuid.PcdDefaultBootType
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath
\r
#define BOOT_DEVICE_DESCRIPTION_MAX 100\r
#define BOOT_DEVICE_FILEPATH_MAX 100\r
-#define BOOT_DEVICE_OPTION_MAX 100\r
+#define BOOT_DEVICE_OPTION_MAX 300\r
#define BOOT_DEVICE_ADDRESS_MAX 20\r
\r
typedef enum {\r
BDS_LOADER_KERNEL_LINUX_FDT,\r
} BDS_LOADER_TYPE;\r
\r
+typedef struct{\r
+ UINT16 InitrdPathListLength;\r
+ EFI_DEVICE_PATH_PROTOCOL *InitrdPathList;\r
+ CHAR8 CmdLine[BOOT_DEVICE_OPTION_MAX + 1];\r
+} BDS_LINUX_ATAG_ARGUMENTS;\r
+\r
+typedef union {\r
+ BDS_LINUX_ATAG_ARGUMENTS LinuxAtagArguments;\r
+} BDS_LOADER_ARGUMENTS;\r
+\r
typedef struct {\r
- BDS_LOADER_TYPE LoaderType;\r
- CHAR8 Arguments[];\r
+ BDS_LOADER_TYPE LoaderType;\r
+ BDS_LOADER_ARGUMENTS Arguments;\r
} BDS_LOADER_OPTIONAL_DATA;\r
\r
typedef enum {\r
\r
typedef UINT8* EFI_LOAD_OPTION;\r
\r
+/* This is defined by the UEFI specs, don't change it */\r
typedef struct {\r
LIST_ENTRY Link;\r
\r
BDS_SUPPORTED_DEVICE_TYPE Type;\r
EFI_STATUS (*ListDevices)(IN OUT LIST_ENTRY* BdsLoadOptionList);\r
BOOLEAN (*IsSupported)(IN BDS_LOAD_OPTION* BdsLoadOption);\r
- EFI_STATUS (*CreateDevicePathNode)(IN BDS_SUPPORTED_DEVICE* BdsLoadOption, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNode, OUT BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);\r
- EFI_STATUS (*UpdateDevicePathNode)(IN BDS_LOAD_OPTION *BootOption, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath, OUT BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);\r
+ EFI_STATUS (*CreateDevicePathNode)(IN BDS_SUPPORTED_DEVICE* BdsLoadOption, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNode, OUT BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);\r
+ EFI_STATUS (*UpdateDevicePathNode)(IN EFI_DEVICE_PATH *OldDevicePath, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath, OUT BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);\r
} BDS_LOAD_OPTION_SUPPORT;\r
\r
#define LOAD_OPTION_FROM_LINK(a) BASE_CR(a, BDS_LOAD_OPTION, Link)\r
\r
EFI_STATUS\r
BootDeviceListSupportedFree (\r
- IN LIST_ENTRY *SupportedDeviceList\r
+ IN LIST_ENTRY *SupportedDeviceList,\r
+ IN BDS_SUPPORTED_DEVICE *Except\r
);\r
\r
EFI_STATUS\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
IN BDS_LOADER_TYPE BootType,\r
- IN CHAR8* BootArguments,\r
+ IN BDS_LOADER_ARGUMENTS *BootArguments,\r
OUT BDS_LOAD_OPTION **BdsLoadOption\r
);\r
\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
IN BDS_LOADER_TYPE BootType,\r
- IN CHAR8* BootArguments\r
+ IN BDS_LOADER_ARGUMENTS *BootArguments\r
);\r
\r
EFI_STATUS\r
extern BDS_LOAD_OPTION_SUPPORT *BdsLoadOptionSupportList;\r
\r
EFI_STATUS\r
-BootMenuAddBootOption (\r
- IN LIST_ENTRY *BootOptionsList\r
+SelectBootDevice (\r
+ OUT BDS_SUPPORTED_DEVICE** SupportedBootDevice\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
LIST_ENTRY SupportedDeviceList;\r
UINTN SupportedDeviceCount;\r
- BDS_SUPPORTED_DEVICE* SupportedBootDevice;\r
LIST_ENTRY* Entry;\r
UINTN SupportedDeviceSelected;\r
- CHAR8 AsciiBootOption[BOOT_DEVICE_OPTION_MAX];\r
- CHAR8 AsciiBootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
- CHAR16 *BootDescription;\r
- UINT32 Attributes;\r
- BDS_LOADER_TYPE BootType;\r
UINTN Index;\r
- BDS_LOAD_OPTION *BdsLoadOption;\r
- EFI_DEVICE_PATH* DevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
-\r
- Attributes = 0;\r
- SupportedBootDevice = NULL;\r
\r
//\r
// List the Boot Devices supported\r
Entry = GetNextNode (&SupportedDeviceList,Entry)\r
)\r
{\r
- SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
- Print(L"[%d] %s\n",SupportedDeviceCount+1,SupportedBootDevice->Description);\r
+ *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
+ Print(L"[%d] %s\n",SupportedDeviceCount+1,(*SupportedBootDevice)->Description);\r
\r
DEBUG_CODE_BEGIN();\r
CHAR16* DevicePathTxt;\r
\r
Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
ASSERT_EFI_ERROR(Status);\r
- DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(SupportedBootDevice->DevicePathProtocol,TRUE,TRUE);\r
+ DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText((*SupportedBootDevice)->DevicePathProtocol,TRUE,TRUE);\r
\r
Print(L"\t- %s\n",DevicePathTxt);\r
\r
)\r
{\r
if (Index == SupportedDeviceSelected) {\r
- SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
+ *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
break;\r
}\r
Index++;\r
}\r
+ \r
+EXIT:\r
+ BootDeviceListSupportedFree (&SupportedDeviceList, *SupportedBootDevice);\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+BootMenuAddBootOption (\r
+ IN LIST_ENTRY *BootOptionsList\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ BDS_SUPPORTED_DEVICE* SupportedBootDevice;\r
+ BDS_LOADER_ARGUMENTS BootArguments;\r
+ CHAR8 AsciiBootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
+ CHAR16 *BootDescription;\r
+ UINT32 Attributes;\r
+ BDS_LOADER_TYPE BootType;\r
+ BDS_LOAD_OPTION *BdsLoadOption;\r
+ EFI_DEVICE_PATH *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *InitrdPathNode;\r
+\r
+ Attributes = 0;\r
+ SupportedBootDevice = NULL;\r
+\r
+ // List the Boot Devices supported\r
+ Status = SelectBootDevice(&SupportedBootDevice);\r
+ if (EFI_ERROR(Status)) {\r
+ Status = EFI_ABORTED;\r
+ goto EXIT;\r
+ }\r
\r
// Create the specific device path node\r
+ Print(L"File path of the EFI Application or the kernel: ");\r
Status = SupportedBootDevice->Support->CreateDevicePathNode (SupportedBootDevice, &DevicePathNode, &BootType, &Attributes);\r
if (EFI_ERROR(Status)) {\r
Status = EFI_ABORTED;\r
// Append the Device Path node to the select device path\r
DevicePath = AppendDevicePathNode (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode);\r
\r
- Print(L"Arguments to pass to the binary: ");\r
- Status = GetHIInputAscii (AsciiBootOption,BOOT_DEVICE_OPTION_MAX);\r
- if (EFI_ERROR(Status)) {\r
- Status = EFI_ABORTED;\r
- goto FREE_DEVICE_PATH;\r
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ // Create the specific device path node\r
+ Print(L"File path of the initrd: ");\r
+ Status = SupportedBootDevice->Support->CreateDevicePathNode (SupportedBootDevice, &InitrdPathNode, NULL, NULL);\r
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd\r
+ Status = EFI_ABORTED;\r
+ goto EXIT;\r
+ }\r
+\r
+ if (InitrdPathNode != NULL) {\r
+ // Append the Device Path node to the select device path\r
+ BootArguments.LinuxAtagArguments.InitrdPathList = AppendDevicePathNode (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNode);\r
+ } else {\r
+ BootArguments.LinuxAtagArguments.InitrdPathList = NULL;\r
+ }\r
+\r
+ Print(L"Arguments to pass to the binary: ");\r
+ Status = GetHIInputAscii (BootArguments.LinuxAtagArguments.CmdLine,BOOT_DEVICE_OPTION_MAX);\r
+ if (EFI_ERROR(Status)) {\r
+ Status = EFI_ABORTED;\r
+ goto FREE_DEVICE_PATH;\r
+ }\r
+ BootArguments.LinuxAtagArguments.CmdLine[BOOT_DEVICE_OPTION_MAX]= '\0';\r
}\r
\r
Print(L"Description for this new Entry: ");\r
AsciiStrToUnicodeStr (AsciiBootDescription, BootDescription);\r
\r
// Create new entry\r
- Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, AsciiBootOption, &BdsLoadOption);\r
+ Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, &BootArguments, &BdsLoadOption);\r
if (!EFI_ERROR(Status)) {\r
InsertTailList (BootOptionsList,&BdsLoadOption->Link);\r
}\r
FREE_DEVICE_PATH:\r
FreePool (DevicePath);\r
\r
+ \r
EXIT:\r
- BootDeviceListSupportedFree (&SupportedDeviceList);\r
+ if (Status == EFI_ABORTED) {\r
+ Print(L"\n");\r
+ }\r
+ FreePool(SupportedBootDevice);\r
return Status;\r
}\r
\r
DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(BootOption->FilePathList,TRUE,TRUE);\r
\r
Print(L"\t- %s\n",DevicePathTxt);\r
- if ((BootOption->OptionalData != NULL) && (BootOption->OptionalData->Arguments != NULL)) {\r
- Print(L"\t- Arguments: %a\n",BootOption->OptionalData->Arguments);\r
+ if ((BDS_LOADER_TYPE)ReadUnaligned32(&BootOption->OptionalData->LoaderType) == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ Print(L"\t- Arguments: %a\n",BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine);\r
}\r
\r
FreePool(DevicePathTxt);\r
if (EFI_ERROR(Status)) {\r
return Status;\r
} else if ((BootOptionSelected == 0) || (BootOptionSelected >= BootOptionCount)) {\r
- Print(L"Invalid input (max %d)\n",BootOptionCount);\r
+ Print(L"Invalid input (max %d)\n",BootOptionCount-1);\r
BootOptionSelected = 0;\r
}\r
}\r
IN LIST_ENTRY *BootOptionsList\r
)\r
{\r
- EFI_STATUS Status;\r
- BDS_LOAD_OPTION *BootOption;\r
- BDS_LOAD_OPTION_SUPPORT* DeviceSupport;\r
- CHAR8 AsciiBootOption[BOOT_DEVICE_OPTION_MAX];\r
- CHAR8 AsciiBootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
- CHAR16 *BootDescription;\r
- EFI_DEVICE_PATH* DevicePath;\r
- UINT32 Attributes;\r
- BDS_LOADER_TYPE BootType;\r
+ EFI_STATUS Status;\r
+ BDS_LOAD_OPTION *BootOption;\r
+ BDS_LOAD_OPTION_SUPPORT *DeviceSupport;\r
+ BDS_LOADER_ARGUMENTS BootArguments;\r
+ CHAR8 AsciiBootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
+ CHAR16 *BootDescription;\r
+ EFI_DEVICE_PATH* DevicePath;\r
+ BDS_LOADER_TYPE BootType;\r
\r
Status = BootMenuSelectBootOption (BootOptionsList,L"Update entry: ",&BootOption);\r
if (EFI_ERROR(Status)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- Status = DeviceSupport->UpdateDevicePathNode (BootOption,&DevicePath,&BootType,&Attributes);\r
+ Print(L"File path of the EFI Application or the kernel: ");\r
+ Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, &DevicePath, NULL, NULL);\r
if (EFI_ERROR(Status)) {\r
Status = EFI_ABORTED;\r
goto EXIT;\r
}\r
\r
- Print(L"Arguments to pass to the binary: ");\r
- if (BootOption->OptionalData) {\r
- AsciiStrnCpy(AsciiBootOption,BootOption->OptionalData->Arguments,BOOT_DEVICE_FILEPATH_MAX);\r
- } else {\r
- AsciiBootOption[0] = '\0';\r
- }\r
- Status = EditHIInputAscii (AsciiBootOption,BOOT_DEVICE_OPTION_MAX);\r
- if (EFI_ERROR(Status)) {\r
- Status = EFI_ABORTED;\r
- goto FREE_DEVICE_PATH;\r
+ BootType = (BDS_LOADER_TYPE)ReadUnaligned32((UINT32 *)(&BootOption->OptionalData->LoaderType));\r
+\r
+ // TODO: Allow adding an initrd to a boot entry without one\r
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ if (ReadUnaligned16(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathListLength) > 0\r
+ && (EFI_DEVICE_PATH_PROTOCOL *)ReadUnaligned32((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)) != NULL) {\r
+\r
+ Print(L"File path of the initrd: ");\r
+ Status = DeviceSupport->UpdateDevicePathNode (\r
+ (EFI_DEVICE_PATH_PROTOCOL *)ReadUnaligned32((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)),\r
+ &BootArguments.LinuxAtagArguments.InitrdPathList,\r
+ NULL,\r
+ NULL);\r
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {// EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd\r
+ Status = EFI_ABORTED;\r
+ goto EXIT;\r
+ }\r
+ } else {\r
+ BootArguments.LinuxAtagArguments.InitrdPathList = NULL;\r
+ BootArguments.LinuxAtagArguments.InitrdPathListLength = 0;\r
+ }\r
+\r
+ Print(L"Arguments to pass to the binary: ");\r
+ if (ReadUnaligned32((CONST UINT32*)&BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine)) {\r
+ AsciiStrnCpy(BootArguments.LinuxAtagArguments.CmdLine,\r
+ BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine,\r
+ BOOT_DEVICE_OPTION_MAX+1);\r
+ } else {\r
+ BootArguments.LinuxAtagArguments.CmdLine[0] = '\0';\r
+ }\r
+ Status = EditHIInputAscii (BootArguments.LinuxAtagArguments.CmdLine, BOOT_DEVICE_OPTION_MAX);\r
+ if (EFI_ERROR(Status)) {\r
+ Status = EFI_ABORTED;\r
+ goto FREE_DEVICE_PATH;\r
+ }\r
}\r
\r
Print(L"Description for this new Entry: ");\r
- UnicodeStrToAsciiStr (BootOption->Description,AsciiBootDescription);\r
- Status = EditHIInputAscii (AsciiBootDescription,BOOT_DEVICE_DESCRIPTION_MAX);\r
+ UnicodeStrToAsciiStr (BootOption->Description, AsciiBootDescription);\r
+ Status = EditHIInputAscii (AsciiBootDescription, BOOT_DEVICE_DESCRIPTION_MAX);\r
if (EFI_ERROR(Status)) {\r
Status = EFI_ABORTED;\r
goto FREE_DEVICE_PATH;\r
AsciiStrToUnicodeStr (AsciiBootDescription, BootDescription);\r
\r
// Update the entry\r
- Status = BootOptionUpdate (BootOption, Attributes, BootDescription, DevicePath, BootType, AsciiBootOption);\r
+ Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, BootType, &BootArguments);\r
\r
FreePool (BootDescription);\r
\r
DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(BootOption->FilePathList,TRUE,TRUE);\r
\r
Print(L"\t- %s\n",DevicePathTxt);\r
- if (BootOption->OptionalData != NULL) {\r
- Print(L"\t- LoaderType: %d\n", ReadUnaligned32 (&BootOption->OptionalData->LoaderType));\r
- if (BootOption->OptionalData->Arguments != NULL) {\r
- Print(L"\t- Arguments: %a\n",BootOption->OptionalData->Arguments);\r
+ if (ReadUnaligned32(&BootOption->OptionalData->LoaderType) == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ if (ReadUnaligned16(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathListLength) > 0\r
+ && (EFI_DEVICE_PATH_PROTOCOL *)ReadUnaligned32((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)) != NULL) {\r
+ DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)ReadUnaligned32((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)),TRUE,TRUE);\r
+ Print(L"\t- Initrd: %s\n", DevicePathTxt);\r
}\r
+ \r
+ Print(L"\t- Arguments: %a\n", BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine);\r
}\r
\r
+ Print(L"\t- LoaderType: %d\n", ReadUnaligned32 (&BootOption->OptionalData->LoaderType));\r
+\r
FreePool(DevicePathTxt);\r
DEBUG_CODE_END();\r
\r
\r
Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList);\r
} else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
- Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, NULL);\r
+ Status = BdsBootLinux (BootOption->FilePathList, \r
+ (EFI_DEVICE_PATH_PROTOCOL*)ReadUnaligned32((UINT32*)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)),\r
+ BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine,\r
+ NULL);\r
} else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
// Convert the FDT path into a Device Path\r
Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
ASSERT_EFI_ERROR(Status);\r
FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\r
\r
- Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, FdtDevicePath);\r
+ Status = BdsBootLinux (BootOption->FilePathList,\r
+ NULL,\r
+ NULL,\r
+ FdtDevicePath);\r
+\r
FreePool(FdtDevicePath);\r
}\r
\r
IN UINT32 Attributes,\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN BDS_LOADER_TYPE BootType,\r
- IN CHAR8* BootArguments\r
+ IN BDS_LOADER_TYPE BootType,\r
+ IN BDS_LOADER_ARGUMENTS* BootArguments\r
)\r
{\r
EFI_LOAD_OPTION EfiLoadOption;\r
UINTN BootDescriptionSize;\r
UINTN BootOptionalDataSize;\r
UINT16 FilePathListLength;\r
+ UINT16 InitrdPathListLength;\r
EFI_DEVICE_PATH_PROTOCOL* DevicePathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL* InitrdPathNode;\r
UINTN NodeLength;\r
UINT8* EfiLoadOptionPtr;\r
+ UINT8 *InitrdPathListPtr;\r
\r
// If we are overwriting an existent Boot Option then we have to free previously allocated memory\r
if (BootOption->LoadOption) {\r
}\r
\r
BootDescriptionSize = StrSize(BootDescription);\r
- BootOptionalDataSize = sizeof(BDS_LOADER_OPTIONAL_DATA) +\r
- (BootArguments == NULL ? 0 : AsciiStrSize(BootArguments));\r
+ BootOptionalDataSize = sizeof(BDS_LOADER_TYPE) + (BootType == BDS_LOADER_KERNEL_LINUX_ATAG ? \r
+ (sizeof(UINT16) + sizeof(EFI_DEVICE_PATH_PROTOCOL*) + BOOT_DEVICE_OPTION_MAX + 1)\r
+ : 0);\r
\r
// Compute the size of the FilePath list\r
FilePathListLength = 0;\r
// Add the length of the DevicePath EndType\r
FilePathListLength += DevicePathNodeLength (DevicePathNode);\r
\r
+ InitrdPathListLength = 0;\r
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG && BootArguments->LinuxAtagArguments.InitrdPathList != NULL) {\r
+ // Compute the size of the InitrdPath list \r
+ InitrdPathNode = BootArguments->LinuxAtagArguments.InitrdPathList;\r
+ while (!IsDevicePathEndType (InitrdPathNode)) {\r
+ InitrdPathListLength += DevicePathNodeLength (InitrdPathNode);\r
+ InitrdPathNode = NextDevicePathNode (InitrdPathNode);\r
+ }\r
+ // Add the length of the DevicePath EndType\r
+ InitrdPathListLength += DevicePathNodeLength (InitrdPathNode);\r
+ }\r
+\r
// Allocate the memory for the EFI Load Option\r
EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize;\r
EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);\r
// Optional Data fields, Do unaligned writes\r
WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, BootType);\r
\r
- CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments, BootArguments, AsciiStrSize(BootArguments));\r
BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr;\r
\r
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxAtagArguments.CmdLine,\r
+ BootArguments->LinuxAtagArguments.CmdLine,\r
+ AsciiStrSize(BootArguments->LinuxAtagArguments.CmdLine));\r
+\r
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathListLength), InitrdPathListLength);\r
+\r
+ if ((EFI_DEVICE_PATH_PROTOCOL*)ReadUnaligned32((UINT32 *)&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList) != NULL\r
+ && BootArguments->LinuxAtagArguments.InitrdPathList != NULL) {\r
+ InitrdPathListPtr = AllocatePool(InitrdPathListLength);\r
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList), (UINT32)InitrdPathListPtr);\r
+ InitrdPathNode = BootArguments->LinuxAtagArguments.InitrdPathList;\r
+\r
+ while (!IsDevicePathEndType (InitrdPathNode)) {\r
+ NodeLength = DevicePathNodeLength(InitrdPathNode);\r
+ CopyMem (InitrdPathListPtr, InitrdPathNode, NodeLength);\r
+ InitrdPathListPtr += NodeLength;\r
+ InitrdPathNode = NextDevicePathNode (InitrdPathNode);\r
+ }\r
+\r
+ // Set the End Device Path Type\r
+ SetDevicePathEndNode (InitrdPathListPtr);\r
+ } else {\r
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList), (UINT32)NULL);\r
+ }\r
+ }\r
// If this function is called at the creation of the Boot Device entry (not at the update) the\r
// BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry\r
if (BootOption->LoadOptionSize == 0) {\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
IN BDS_LOADER_TYPE BootType,\r
- IN CHAR8* BootArguments,\r
+ IN BDS_LOADER_ARGUMENTS* BootArguments,\r
OUT BDS_LOAD_OPTION **BdsLoadOption\r
)\r
{\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
IN BDS_LOADER_TYPE BootType,\r
- IN CHAR8* BootArguments\r
+ IN BDS_LOADER_ARGUMENTS* BootArguments\r
)\r
{\r
EFI_STATUS Status;\r
\r
EFI_STATUS\r
BdsLoadOptionFileSystemUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
\r
EFI_STATUS\r
BdsLoadOptionMemMapUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
\r
EFI_STATUS\r
BdsLoadOptionPxeUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
\r
EFI_STATUS\r
BdsLoadOptionTftpUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
\r
EFI_STATUS\r
BootDeviceListSupportedFree (\r
- IN LIST_ENTRY *SupportedDeviceList\r
+ IN LIST_ENTRY *SupportedDeviceList,\r
+ IN BDS_SUPPORTED_DEVICE *Except\r
)\r
{\r
LIST_ENTRY *Entry;\r
while (Entry != SupportedDeviceList) {\r
SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
Entry = RemoveEntryList (Entry);\r
- FreePool(SupportedDevice);\r
+ if (SupportedDevice != Except) {\r
+ FreePool(SupportedDevice);\r
+ }\r
}\r
\r
return EFI_SUCCESS;\r
CHAR16 *BootFilePath;\r
UINTN BootFilePathSize;\r
\r
- Print(L"File path of the EFI Application or the kernel: ");\r
Status = GetHIInputAscii (AsciiBootFilePath,BOOT_DEVICE_FILEPATH_MAX);\r
if (EFI_ERROR(Status)) {\r
return EFI_ABORTED;\r
}\r
\r
+ if (AsciiStrSize(AsciiBootFilePath) == 1) {\r
+ *DevicePathNode = NULL;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
// Convert Ascii into Unicode\r
BootFilePath = (CHAR16*)AllocatePool(AsciiStrSize(AsciiBootFilePath) * sizeof(CHAR16));\r
AsciiStrToUnicodeStr (AsciiBootFilePath, BootFilePath);\r
CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
FreePool (BootFilePath);\r
\r
- Status = BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);\r
+ if (BootType != NULL || Attributes != NULL) {\r
+ Status = BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);\r
+ }\r
+\r
if (EFI_ERROR(Status)) {\r
FreePool (FilePathDevicePath);\r
} else {\r
\r
EFI_STATUS\r
BdsLoadOptionFileSystemUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
EFI_DEVICE_PATH* DevicePath;\r
\r
- DevicePath = DuplicateDevicePath (BootOption->FilePathList);\r
- EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
+ DevicePath = DuplicateDevicePath(OldDevicePath);\r
\r
- Print(L"File path of the EFI Application or the kernel: ");\r
+ EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
+ \r
UnicodeStrToAsciiStr (EndingDevicePath->PathName,AsciiBootFilePath);\r
Status = EditHIInputAscii (AsciiBootFilePath,BOOT_DEVICE_FILEPATH_MAX);\r
if (EFI_ERROR(Status)) {\r
return Status;\r
}\r
\r
+ if (AsciiStrSize(AsciiBootFilePath) == 1) {\r
+ *NewDevicePath = NULL;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
// Convert Ascii into Unicode\r
BootFilePath = (CHAR16*)AllocatePool(AsciiStrSize(AsciiBootFilePath) * sizeof(CHAR16));\r
AsciiStrToUnicodeStr (AsciiBootFilePath, BootFilePath);\r
*NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);\r
FreePool(DevicePath);\r
\r
- return BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);\r
+ if (BootType != NULL || Attributes != NULL) {\r
+ return BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
BOOLEAN\r
\r
EFI_STATUS\r
BdsLoadOptionMemMapUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
MEMMAP_DEVICE_PATH* EndingDevicePath;\r
EFI_DEVICE_PATH* DevicePath;\r
\r
- DevicePath = DuplicateDevicePath (BootOption->FilePathList);\r
+ DevicePath = DuplicateDevicePath (OldDevicePath);\r
EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
\r
Print(L"Starting Address of the binary: ");\r
\r
EFI_STATUS\r
BdsLoadOptionPxeUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r
\r
EFI_STATUS\r
BdsLoadOptionTftpUpdateDevicePath (\r
- IN BDS_LOAD_OPTION *BootOption,\r
+ IN EFI_DEVICE_PATH *OldDevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath,\r
OUT BDS_LOADER_TYPE *BootType,\r
OUT UINT32 *Attributes\r