]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BootOption.c
ArmPlatformPkg/Bds: Add Linux 'initrd' support to BDS
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOption.c
index dba0d0f639a66815fbdf2f108ebbe12cacd5b9c7..f4ff182ef219437b6a7631ade94dc39e0e5b0e29 100644 (file)
@@ -35,14 +35,21 @@ BootOptionStart (
 \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
@@ -184,8 +191,8 @@ BootOptionSetFields (
   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
@@ -193,9 +200,12 @@ BootOptionSetFields (
   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
@@ -203,8 +213,9 @@ BootOptionSetFields (
   }\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
@@ -216,6 +227,18 @@ BootOptionSetFields (
   // 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
@@ -257,9 +280,34 @@ BootOptionSetFields (
   // 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
@@ -279,7 +327,7 @@ BootOptionCreate (
   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
@@ -344,7 +392,7 @@ BootOptionUpdate (
   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