EFI_DEVICE_PATH* FdtDevicePath;\r
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;\r
UINT32 LoaderType;\r
+ ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData;\r
+ ARM_BDS_LINUX_ARGUMENTS* LinuxArguments;\r
+ EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath;\r
+ UINTN FdtDevicePathSize;\r
+ UINTN CmdLineSize;\r
+ UINTN InitrdSize;\r
+ EFI_DEVICE_PATH* Initrd;\r
+\r
+ Status = EFI_UNSUPPORTED;\r
+ OptionalData = BootOption->OptionalData;\r
+ LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
+\r
+ if (LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
+ // Need to connect every drivers to ensure no dependencies are missing for the application\r
+ BdsConnectAllDrivers();\r
+\r
+ Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);\r
+ } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+ LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
+ CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
+ InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
+\r
+ if (InitrdSize > 0) {\r
+ Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
+ } else {\r
+ Initrd = NULL;\r
+ }\r
\r
- Status = EFI_UNSUPPORTED;\r
- LoaderType = ReadUnaligned32 (&BootOption->OptionalData->LoaderType);\r
-\r
- if (LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
- // Need to connect every drivers to ensure no dependencies are missing for the application\r
- BdsConnectAllDrivers();\r
-\r
- Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList);\r
- } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\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,\r
- NULL,\r
- NULL,\r
- FdtDevicePath);\r
-\r
- FreePool(FdtDevicePath);\r
- }\r
+ Status = BdsBootLinux (BootOption->FilePathList,\r
+ Initrd, // Initrd\r
+ (CHAR8*)(LinuxArguments + 1), // CmdLine\r
+ NULL);\r
+ } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
+ LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
+ CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
+ InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
+\r
+ if (InitrdSize > 0) {\r
+ Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
+ } else {\r
+ Initrd = NULL;\r
+ }\r
+\r
+ // Get the default FDT device path\r
+ Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
+ ASSERT_EFI_ERROR(Status);\r
+ DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\r
+\r
+ // Get the FDT device path\r
+ FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);\r
+ Status = GetEnvironmentVariable ((CHAR16 *)L"FDT", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ Status = BdsBootLinux (BootOption->FilePathList,\r
+ Initrd, // Initrd\r
+ (CHAR8*)(LinuxArguments + 1),\r
+ FdtDevicePath);\r
\r
return Status;\r
}\r
IN UINT32 Attributes,\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN BDS_LOADER_TYPE BootType,\r
- IN BDS_LOADER_ARGUMENTS* BootArguments\r
+ IN ARM_BDS_LOADER_TYPE BootType,\r
+ IN ARM_BDS_LOADER_ARGUMENTS* BootArguments\r
)\r
{\r
- EFI_LOAD_OPTION EfiLoadOption;\r
- UINTN EfiLoadOptionSize;\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
+ EFI_LOAD_OPTION EfiLoadOption;\r
+ UINTN EfiLoadOptionSize;\r
+ UINTN BootDescriptionSize;\r
+ UINTN BootOptionalDataSize;\r
+ UINT16 FilePathListLength;\r
+ UINT8* EfiLoadOptionPtr;\r
+ UINT8* InitrdPathListPtr;\r
+ UINTN OptionalDataSize;\r
+ ARM_BDS_LINUX_ARGUMENTS* DestLinuxArguments;\r
+ ARM_BDS_LINUX_ARGUMENTS* SrcLinuxArguments;\r
\r
// If we are overwriting an existent Boot Option then we have to free previously allocated memory\r
if (BootOption->LoadOption) {\r
FreePool(BootOption->LoadOption);\r
}\r
\r
- BootDescriptionSize = StrSize(BootDescription);\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
+ BootDescriptionSize = StrSize (BootDescription);\r
+ BootOptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
+ if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
+ BootOptionalDataSize += sizeof(ARM_BDS_LINUX_ARGUMENTS) + BootArguments->LinuxArguments.CmdLineSize + BootArguments->LinuxArguments.InitrdSize;\r
+ }\r
\r
// Compute the size of the FilePath list\r
- FilePathListLength = 0;\r
- DevicePathNode = DevicePath;\r
- while (!IsDevicePathEndType (DevicePathNode)) {\r
- FilePathListLength += DevicePathNodeLength (DevicePathNode);\r
- DevicePathNode = NextDevicePathNode (DevicePathNode);\r
- }\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
+ FilePathListLength = GetUnalignedDevicePathSize (DevicePath);\r
\r
// Allocate the memory for the EFI Load Option\r
EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize;\r
\r
// File path fields\r
BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;\r
- DevicePathNode = DevicePath;\r
- while (!IsDevicePathEndType (DevicePathNode)) {\r
- NodeLength = DevicePathNodeLength(DevicePathNode);\r
- CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength);\r
- EfiLoadOptionPtr += NodeLength;\r
- DevicePathNode = NextDevicePathNode (DevicePathNode);\r
- }\r
-\r
- // Set the End Device Path Type\r
- SetDevicePathEndNode (EfiLoadOptionPtr);\r
- EfiLoadOptionPtr = (UINT8 *)EfiLoadOptionPtr + sizeof(EFI_DEVICE_PATH);\r
+ CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);\r
+ EfiLoadOptionPtr += FilePathListLength;\r
\r
// Optional Data fields, Do unaligned writes\r
- WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, BootType);\r
+ BootOption->OptionalData = EfiLoadOptionPtr;\r
+ WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);\r
+ WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);\r
\r
- BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr;\r
+ OptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\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
+ if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
+ SrcLinuxArguments = &(BootArguments->LinuxArguments);\r
+ DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;\r
\r
- WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathListLength), InitrdPathListLength);\r
+ WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize);\r
+ WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize);\r
+ OptionalDataSize += sizeof (ARM_BDS_LINUX_ARGUMENTS);\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
+ if (SrcLinuxArguments->CmdLineSize > 0) {\r
+ CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize);\r
+ OptionalDataSize += SrcLinuxArguments->CmdLineSize;\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
+ if (SrcLinuxArguments->InitrdSize > 0) {\r
+ InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize);\r
+ CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);\r
}\r
}\r
+ BootOption->OptionalDataSize = OptionalDataSize;\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
- BootOption->LoadOptionIndex = BootOptionAllocateBootIndex();\r
+ BootOption->LoadOptionIndex = BootOptionAllocateBootIndex ();\r
}\r
\r
// Fill the EFI Load option fields\r
IN UINT32 Attributes,\r
IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN BDS_LOADER_TYPE BootType,\r
- IN BDS_LOADER_ARGUMENTS* BootArguments,\r
+ IN ARM_BDS_LOADER_TYPE BootType,\r
+ IN ARM_BDS_LOADER_ARGUMENTS* BootArguments,\r
OUT BDS_LOAD_OPTION **BdsLoadOption\r
)\r
{\r
\r
EFI_STATUS\r
BootOptionUpdate (\r
- IN BDS_LOAD_OPTION *BdsLoadOption,\r
- IN UINT32 Attributes,\r
- IN CHAR16* BootDescription,\r
+ IN BDS_LOAD_OPTION* BdsLoadOption,\r
+ IN UINT32 Attributes,\r
+ IN CHAR16* BootDescription,\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN BDS_LOADER_TYPE BootType,\r
- IN BDS_LOADER_ARGUMENTS* BootArguments\r
+ IN ARM_BDS_LOADER_TYPE BootType,\r
+ IN ARM_BDS_LOADER_ARGUMENTS* BootArguments\r
)\r
{\r
EFI_STATUS Status;\r