public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd
       [not found] <cover.1630449811.git.jbrasen@nvidia.com>
@ 2021-08-31 22:48 ` Jeff Brasen
  2021-09-01  8:56   ` Ard Biesheuvel
  2021-09-01  9:53   ` [edk2-devel] " Marvin Häuser
  0 siblings, 2 replies; 3+ messages in thread
From: Jeff Brasen @ 2021-08-31 22:48 UTC (permalink / raw)
  To: devel; +Cc: leif, ardb+tianocore, abner.chang, daniel.schaefer, Jeff Brasen

Add support under a pcd feature for using the new interface to pass
initrd to the linux kernel.

Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
---
 EmbeddedPkg/EmbeddedPkg.dec                   |   1 +
 .../AndroidBootImgLib/AndroidBootImgLib.inf   |   3 +
 .../AndroidBootImgLib/AndroidBootImgLib.c     | 147 ++++++++++++++++--
 3 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index c2068ce5a8ce..7638aaaadeb8 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -86,6 +86,7 @@ [Ppis]
 [PcdsFeatureFlag.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
   gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
+  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2|FALSE|BOOLEAN|0x0000005b
 
 [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0|UINT32|0x0000000b
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
index bfed4ba9dcd4..39d8abe72cd1 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
@@ -42,3 +42,6 @@ [Protocols]
 
 [Guids]
   gFdtTableGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
index bbc240c3632a..255996e65bdc 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
@@ -10,11 +10,15 @@
 #include <libfdt.h>
 #include <Library/AndroidBootImgLib.h>
 #include <Library/PrintLib.h>
+#include <Library/DevicePathLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 
 #include <Protocol/AndroidBootImg.h>
 #include <Protocol/LoadedImage.h>
+#include <Protocol/LoadFile2.h>
+
+#include <Guid/LinuxEfiInitrdMedia.h>
 
 #include <libfdt.h>
 
@@ -25,7 +29,14 @@ typedef struct {
   EFI_DEVICE_PATH_PROTOCOL                End;
 } MEMORY_DEVICE_PATH;
 
+typedef struct {
+  VENDOR_DEVICE_PATH                      VenMediaNode;
+  EFI_DEVICE_PATH_PROTOCOL                EndNode;
+} RAMDISK_DEVICE_PATH;
+
 STATIC ANDROID_BOOTIMG_PROTOCOL                 *mAndroidBootImg;
+STATIC EFI_PHYSICAL_ADDRESS                     mRamdiskData = 0;
+STATIC UINT64                                   mRamdiskSize = 0;
 
 STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
 {
@@ -48,6 +59,96 @@ STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
   } // End
 };
 
+STATIC RAMDISK_DEVICE_PATH        mRamdiskDevicePath =
+{
+  {
+    {
+      MEDIA_DEVICE_PATH,
+      MEDIA_VENDOR_DP,
+      { sizeof (VENDOR_DEVICE_PATH), 0 }
+    },
+    LINUX_EFI_INITRD_MEDIA_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+/**
+  Causes the driver to load a specified file.
+
+  @param  This       Protocol instance pointer.
+  @param  FilePath   The device specific path of the file to load.
+  @param  BootPolicy Should always be FALSE.
+  @param  BufferSize On input the size of Buffer in bytes. On output with a return
+                     code of EFI_SUCCESS, the amount of data transferred to
+                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
+                     the size of Buffer required to retrieve the requested file.
+  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,
+                     then no the size of the requested file is returned in
+                     BufferSize.
+
+  @retval EFI_SUCCESS           The file was loaded.
+  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.
+  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
+                                BufferSize is NULL.
+  @retval EFI_NO_MEDIA          No medium was present to load the file.
+  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.
+  @retval EFI_NO_RESPONSE       The remote system did not respond.
+  @retval EFI_NOT_FOUND         The file was not found
+  @retval EFI_ABORTED           The file load process was manually canceled.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current
+                                directory entry. BufferSize has been updated with
+                                the size needed to complete the request.
+
+
+**/
+EFI_STATUS
+EFIAPI
+AndroidBootImgLoadFile2 (
+  IN EFI_LOAD_FILE2_PROTOCOL    *This,
+  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
+  IN BOOLEAN                    BootPolicy,
+  IN OUT UINTN                  *BufferSize,
+  IN VOID                       *Buffer OPTIONAL
+  )
+
+{
+  // Verify if the valid parameters
+  if (This == NULL || BufferSize == NULL || FilePath == NULL || !IsDevicePathValid (FilePath, 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BootPolicy) {
+    return EFI_UNSUPPORTED;
+  }
+
+  // Check if the given buffer size is big enough
+  // EFI_BUFFER_TOO_SMALL gets boot manager allocate a bigger buffer
+  if (mRamdiskSize == 0) {
+    return EFI_NOT_FOUND;
+  }
+  if (Buffer == NULL || *BufferSize < mRamdiskSize) {
+    *BufferSize = mRamdiskSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Copy InitRd
+  gBS->CopyMem (Buffer, (VOID *)mRamdiskData, mRamdiskSize);
+
+  return EFI_SUCCESS;
+}
+
+///
+/// Load File Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_LOAD_FILE2_PROTOCOL  mAndroidBootImgLoadFile2 = {
+  AndroidBootImgLoadFile2
+};
+
 EFI_STATUS
 AndroidBootImgGetImgSize (
   IN  VOID    *BootImg,
@@ -383,6 +484,7 @@ AndroidBootImgBoot (
   VOID                               *RamdiskData;
   UINTN                               RamdiskSize;
   IN  VOID                           *FdtBase;
+  EFI_HANDLE                          RamdiskHandle;
 
   Status = gBS->LocateProtocol (&gAndroidBootImgProtocolGuid, NULL,
                                 (VOID **) &mAndroidBootImg);
@@ -420,16 +522,32 @@ AndroidBootImgBoot (
     return Status;
   }
 
-  Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
-  if (EFI_ERROR (Status)) {
-    FreePool (NewKernelArg);
-    return Status;
-  }
+  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
+    RamdiskHandle = 0;
+    mRamdiskData = (EFI_PHYSICAL_ADDRESS)RamdiskData;
+    mRamdiskSize = RamdiskSize;
+    Status = gBS->InstallMultipleProtocolInterfaces (&RamdiskHandle,
+                                                     &gEfiLoadFile2ProtocolGuid,
+                                                     &mAndroidBootImgLoadFile2,
+                                                     &gEfiDevicePathProtocolGuid,
+                                                     &mRamdiskDevicePath,
+                                                     NULL);
+    if (EFI_ERROR (Status)) {
+      FreePool (NewKernelArg);
+      return Status;
+    }
+  } else {
+    Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
+    if (EFI_ERROR (Status)) {
+      FreePool (NewKernelArg);
+      return Status;
+    }
 
-  Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
-  if (EFI_ERROR (Status)) {
-    FreePool (NewKernelArg);
-    return Status;
+    Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
+    if (EFI_ERROR (Status)) {
+      FreePool (NewKernelArg);
+      return Status;
+    }
   }
 
   KernelDevicePath = mMemoryDevicePathTemplate;
@@ -466,5 +584,16 @@ AndroidBootImgBoot (
   Status = gBS->StartImage (ImageHandle, NULL, NULL);
   // Clear the Watchdog Timer if the image returns
   gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);
+
+  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
+    mRamdiskData = 0;
+    mRamdiskSize = 0;
+    gBS->UninstallMultipleProtocolInterfaces (RamdiskHandle,
+                                              &gEfiLoadFile2ProtocolGuid,
+                                              &mAndroidBootImgLoadFile2,
+                                              &gEfiDevicePathProtocolGuid,
+                                              &mRamdiskDevicePath,
+                                              NULL);
+  }
   return EFI_SUCCESS;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd
  2021-08-31 22:48 ` [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd Jeff Brasen
@ 2021-09-01  8:56   ` Ard Biesheuvel
  2021-09-01  9:53   ` [edk2-devel] " Marvin Häuser
  1 sibling, 0 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2021-09-01  8:56 UTC (permalink / raw)
  To: Jeff Brasen
  Cc: edk2-devel-groups-io, Leif Lindholm, Ard Biesheuvel, Abner Chang,
	Daniel Schaefer

Hi Jeff,

On Wed, 1 Sept 2021 at 00:48, Jeff Brasen <jbrasen@nvidia.com> wrote:
>
> Add support under a pcd feature for using the new interface to pass
> initrd to the linux kernel.
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
>  EmbeddedPkg/EmbeddedPkg.dec                   |   1 +
>  .../AndroidBootImgLib/AndroidBootImgLib.inf   |   3 +
>  .../AndroidBootImgLib/AndroidBootImgLib.c     | 147 ++++++++++++++++--
>  3 files changed, 142 insertions(+), 9 deletions(-)
>
> diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
> index c2068ce5a8ce..7638aaaadeb8 100644
> --- a/EmbeddedPkg/EmbeddedPkg.dec
> +++ b/EmbeddedPkg/EmbeddedPkg.dec
> @@ -86,6 +86,7 @@ [Ppis]
>  [PcdsFeatureFlag.common]
>    gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
>    gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
> +  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2|FALSE|BOOLEAN|0x0000005b
>
>  [PcdsFixedAtBuild.common]
>    gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0|UINT32|0x0000000b
> diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> index bfed4ba9dcd4..39d8abe72cd1 100644
> --- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> @@ -42,3 +42,6 @@ [Protocols]
>
>  [Guids]
>    gFdtTableGuid
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2
> diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> index bbc240c3632a..255996e65bdc 100644
> --- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> @@ -10,11 +10,15 @@
>  #include <libfdt.h>
>  #include <Library/AndroidBootImgLib.h>
>  #include <Library/PrintLib.h>
> +#include <Library/DevicePathLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/UefiLib.h>
>
>  #include <Protocol/AndroidBootImg.h>
>  #include <Protocol/LoadedImage.h>
> +#include <Protocol/LoadFile2.h>
> +
> +#include <Guid/LinuxEfiInitrdMedia.h>
>
>  #include <libfdt.h>
>
> @@ -25,7 +29,14 @@ typedef struct {
>    EFI_DEVICE_PATH_PROTOCOL                End;
>  } MEMORY_DEVICE_PATH;
>
> +typedef struct {
> +  VENDOR_DEVICE_PATH                      VenMediaNode;
> +  EFI_DEVICE_PATH_PROTOCOL                EndNode;
> +} RAMDISK_DEVICE_PATH;
> +
>  STATIC ANDROID_BOOTIMG_PROTOCOL                 *mAndroidBootImg;
> +STATIC EFI_PHYSICAL_ADDRESS                     mRamdiskData = 0;
> +STATIC UINT64                                   mRamdiskSize = 0;
>
>  STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
>  {
> @@ -48,6 +59,96 @@ STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
>    } // End
>  };
>
> +STATIC RAMDISK_DEVICE_PATH        mRamdiskDevicePath =

Could this be CONST?

> +{
> +  {
> +    {
> +      MEDIA_DEVICE_PATH,
> +      MEDIA_VENDOR_DP,
> +      { sizeof (VENDOR_DEVICE_PATH), 0 }
> +    },
> +    LINUX_EFI_INITRD_MEDIA_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
> +  }
> +};
> +
> +/**
> +  Causes the driver to load a specified file.
> +
> +  @param  This       Protocol instance pointer.
> +  @param  FilePath   The device specific path of the file to load.
> +  @param  BootPolicy Should always be FALSE.
> +  @param  BufferSize On input the size of Buffer in bytes. On output with a return
> +                     code of EFI_SUCCESS, the amount of data transferred to
> +                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
> +                     the size of Buffer required to retrieve the requested file.
> +  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,
> +                     then no the size of the requested file is returned in
> +                     BufferSize.
> +
> +  @retval EFI_SUCCESS           The file was loaded.
> +  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.
> +  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
> +                                BufferSize is NULL.
> +  @retval EFI_NO_MEDIA          No medium was present to load the file.
> +  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.
> +  @retval EFI_NO_RESPONSE       The remote system did not respond.
> +  @retval EFI_NOT_FOUND         The file was not found
> +  @retval EFI_ABORTED           The file load process was manually canceled.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current
> +                                directory entry. BufferSize has been updated with
> +                                the size needed to complete the request.
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AndroidBootImgLoadFile2 (
> +  IN EFI_LOAD_FILE2_PROTOCOL    *This,
> +  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
> +  IN BOOLEAN                    BootPolicy,
> +  IN OUT UINTN                  *BufferSize,
> +  IN VOID                       *Buffer OPTIONAL
> +  )
> +
> +{
> +  // Verify if the valid parameters
> +  if (This == NULL || BufferSize == NULL || FilePath == NULL || !IsDevicePathValid (FilePath, 0)) {

Please wrap new code to 80 columns

> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (BootPolicy) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  // Check if the given buffer size is big enough
> +  // EFI_BUFFER_TOO_SMALL gets boot manager allocate a bigger buffer
> +  if (mRamdiskSize == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +  if (Buffer == NULL || *BufferSize < mRamdiskSize) {
> +    *BufferSize = mRamdiskSize;
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  // Copy InitRd
> +  gBS->CopyMem (Buffer, (VOID *)mRamdiskData, mRamdiskSize);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +///
> +/// Load File Protocol instance
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +EFI_LOAD_FILE2_PROTOCOL  mAndroidBootImgLoadFile2 = {
> +  AndroidBootImgLoadFile2
> +};
> +
>  EFI_STATUS
>  AndroidBootImgGetImgSize (
>    IN  VOID    *BootImg,
> @@ -383,6 +484,7 @@ AndroidBootImgBoot (
>    VOID                               *RamdiskData;
>    UINTN                               RamdiskSize;
>    IN  VOID                           *FdtBase;
> +  EFI_HANDLE                          RamdiskHandle;
>
>    Status = gBS->LocateProtocol (&gAndroidBootImgProtocolGuid, NULL,
>                                  (VOID **) &mAndroidBootImg);
> @@ -420,16 +522,32 @@ AndroidBootImgBoot (
>      return Status;
>    }
>
> -  Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
> -  if (EFI_ERROR (Status)) {
> -    FreePool (NewKernelArg);
> -    return Status;
> -  }
> +  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
> +    RamdiskHandle = 0;
> +    mRamdiskData = (EFI_PHYSICAL_ADDRESS)RamdiskData;

Why is this being converted from a VOID* to EFI_PHYSICAL_ADDRESS and
then back again?

> +    mRamdiskSize = RamdiskSize;
> +    Status = gBS->InstallMultipleProtocolInterfaces (&RamdiskHandle,
> +                                                     &gEfiLoadFile2ProtocolGuid,
> +                                                     &mAndroidBootImgLoadFile2,
> +                                                     &gEfiDevicePathProtocolGuid,
> +                                                     &mRamdiskDevicePath,
> +                                                     NULL);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);

There are now 3 occurrences of this FreePool() so better use goto with
a label at the end of the function.

> +      return Status;
> +    }
> +  } else {
> +    Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);
> +      return Status;
> +    }
>
> -  Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
> -  if (EFI_ERROR (Status)) {
> -    FreePool (NewKernelArg);
> -    return Status;
> +    Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);
> +      return Status;
> +    }
>    }
>
>    KernelDevicePath = mMemoryDevicePathTemplate;
> @@ -466,5 +584,16 @@ AndroidBootImgBoot (
>    Status = gBS->StartImage (ImageHandle, NULL, NULL);
>    // Clear the Watchdog Timer if the image returns
>    gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);
> +
> +  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
> +    mRamdiskData = 0;
> +    mRamdiskSize = 0;
> +    gBS->UninstallMultipleProtocolInterfaces (RamdiskHandle,
> +                                              &gEfiLoadFile2ProtocolGuid,
> +                                              &mAndroidBootImgLoadFile2,
> +                                              &gEfiDevicePathProtocolGuid,
> +                                              &mRamdiskDevicePath,
> +                                              NULL);
> +  }
>    return EFI_SUCCESS;
>  }
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [edk2-devel] [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd
  2021-08-31 22:48 ` [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd Jeff Brasen
  2021-09-01  8:56   ` Ard Biesheuvel
@ 2021-09-01  9:53   ` Marvin Häuser
  1 sibling, 0 replies; 3+ messages in thread
From: Marvin Häuser @ 2021-09-01  9:53 UTC (permalink / raw)
  To: devel, jbrasen; +Cc: leif, ardb+tianocore, abner.chang, daniel.schaefer

Good day Jeff,

On 01/09/2021 00:48, Jeff Brasen via groups.io wrote:
> Add support under a pcd feature for using the new interface to pass
> initrd to the linux kernel.
>
> Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
>   EmbeddedPkg/EmbeddedPkg.dec                   |   1 +
>   .../AndroidBootImgLib/AndroidBootImgLib.inf   |   3 +
>   .../AndroidBootImgLib/AndroidBootImgLib.c     | 147 ++++++++++++++++--
>   3 files changed, 142 insertions(+), 9 deletions(-)
>
> diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
> index c2068ce5a8ce..7638aaaadeb8 100644
> --- a/EmbeddedPkg/EmbeddedPkg.dec
> +++ b/EmbeddedPkg/EmbeddedPkg.dec
> @@ -86,6 +86,7 @@ [Ppis]
>   [PcdsFeatureFlag.common]
>     gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
>     gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
> +  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2|FALSE|BOOLEAN|0x0000005b
>   
>   [PcdsFixedAtBuild.common]
>     gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0|UINT32|0x0000000b
> diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> index bfed4ba9dcd4..39d8abe72cd1 100644
> --- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> @@ -42,3 +42,6 @@ [Protocols]
>   
>   [Guids]
>     gFdtTableGuid
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2
> diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> index bbc240c3632a..255996e65bdc 100644
> --- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> @@ -10,11 +10,15 @@
>   #include <libfdt.h>
>   #include <Library/AndroidBootImgLib.h>
>   #include <Library/PrintLib.h>
> +#include <Library/DevicePathLib.h>
>   #include <Library/UefiBootServicesTableLib.h>
>   #include <Library/UefiLib.h>
>   
>   #include <Protocol/AndroidBootImg.h>
>   #include <Protocol/LoadedImage.h>
> +#include <Protocol/LoadFile2.h>
> +
> +#include <Guid/LinuxEfiInitrdMedia.h>
>   
>   #include <libfdt.h>
>   
> @@ -25,7 +29,14 @@ typedef struct {
>     EFI_DEVICE_PATH_PROTOCOL                End;
>   } MEMORY_DEVICE_PATH;
>   
> +typedef struct {
> +  VENDOR_DEVICE_PATH                      VenMediaNode;
> +  EFI_DEVICE_PATH_PROTOCOL                EndNode;
> +} RAMDISK_DEVICE_PATH;
> +
>   STATIC ANDROID_BOOTIMG_PROTOCOL                 *mAndroidBootImg;
> +STATIC EFI_PHYSICAL_ADDRESS                     mRamdiskData = 0;
> +STATIC UINT64                                   mRamdiskSize = 0;

This should be UINTN to align with the source of the value. This gets 
rid of implicit truncation to UINTN when UINTN != UINT64, MSVC emits 
warnings for such.

>   STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
>   {
> @@ -48,6 +59,96 @@ STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
>     } // End
>   };
>   
> +STATIC RAMDISK_DEVICE_PATH        mRamdiskDevicePath =
> +{
> +  {
> +    {
> +      MEDIA_DEVICE_PATH,
> +      MEDIA_VENDOR_DP,
> +      { sizeof (VENDOR_DEVICE_PATH), 0 }
> +    },
> +    LINUX_EFI_INITRD_MEDIA_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
> +  }
> +};
> +
> +/**
> +  Causes the driver to load a specified file.
> +
> +  @param  This       Protocol instance pointer.
> +  @param  FilePath   The device specific path of the file to load.
> +  @param  BootPolicy Should always be FALSE.
> +  @param  BufferSize On input the size of Buffer in bytes. On output with a return
> +                     code of EFI_SUCCESS, the amount of data transferred to
> +                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
> +                     the size of Buffer required to retrieve the requested file.
> +  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,
> +                     then no the size of the requested file is returned in
> +                     BufferSize.
> +
> +  @retval EFI_SUCCESS           The file was loaded.
> +  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.
> +  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
> +                                BufferSize is NULL.
> +  @retval EFI_NO_MEDIA          No medium was present to load the file.
> +  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.
> +  @retval EFI_NO_RESPONSE       The remote system did not respond.
> +  @retval EFI_NOT_FOUND         The file was not found
> +  @retval EFI_ABORTED           The file load process was manually canceled.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current
> +                                directory entry. BufferSize has been updated with
> +                                the size needed to complete the request.
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AndroidBootImgLoadFile2 (
> +  IN EFI_LOAD_FILE2_PROTOCOL    *This,
> +  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
> +  IN BOOLEAN                    BootPolicy,
> +  IN OUT UINTN                  *BufferSize,
> +  IN VOID                       *Buffer OPTIONAL
> +  )
> +
> +{
> +  // Verify if the valid parameters
> +  if (This == NULL || BufferSize == NULL || FilePath == NULL || !IsDevicePathValid (FilePath, 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (BootPolicy) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  // Check if the given buffer size is big enough
> +  // EFI_BUFFER_TOO_SMALL gets boot manager allocate a bigger buffer
> +  if (mRamdiskSize == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +  if (Buffer == NULL || *BufferSize < mRamdiskSize) {
> +    *BufferSize = mRamdiskSize;

Implicit truncation of mRamdiskSize is resolved by the comment above.

> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  // Copy InitRd
> +  gBS->CopyMem (Buffer, (VOID *)mRamdiskData, mRamdiskSize);

Implicit truncation of mRamdiskSize is resolved by the comment above.

I think using BaseMemoryLib's CopyMem() is more conventional than 
calling gBS->CopyMem().

EFI_PHYSICAL_ADDRESS may not be of the same precision as the pointer 
types, it needs to be cast to UINTN first. However, I don't see a need 
for EFI_PHYSICAL_ADDRESS right away, was it chosen for a specific reason?

> +
> +  return EFI_SUCCESS;
> +}
> +
> +///
> +/// Load File Protocol instance
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED

I think it can be STATIC?

> +EFI_LOAD_FILE2_PROTOCOL  mAndroidBootImgLoadFile2 = {
> +  AndroidBootImgLoadFile2
> +};
> +
>   EFI_STATUS
>   AndroidBootImgGetImgSize (
>     IN  VOID    *BootImg,
> @@ -383,6 +484,7 @@ AndroidBootImgBoot (
>     VOID                               *RamdiskData;
>     UINTN                               RamdiskSize;
>     IN  VOID                           *FdtBase;
> +  EFI_HANDLE                          RamdiskHandle;
>   
>     Status = gBS->LocateProtocol (&gAndroidBootImgProtocolGuid, NULL,
>                                   (VOID **) &mAndroidBootImg);
> @@ -420,16 +522,32 @@ AndroidBootImgBoot (
>       return Status;
>     }
>   
> -  Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
> -  if (EFI_ERROR (Status)) {
> -    FreePool (NewKernelArg);
> -    return Status;
> -  }
> +  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
> +    RamdiskHandle = 0;

EFI_HANDLE is a pointer type and thus needs a NULL value.

> +    mRamdiskData = (EFI_PHYSICAL_ADDRESS)RamdiskData;

Same precision issue as above.

> +    mRamdiskSize = RamdiskSize;
> +    Status = gBS->InstallMultipleProtocolInterfaces (&RamdiskHandle,
> +                                                     &gEfiLoadFile2ProtocolGuid,
> +                                                     &mAndroidBootImgLoadFile2,
> +                                                     &gEfiDevicePathProtocolGuid,
> +                                                     &mRamdiskDevicePath,
> +                                                     NULL);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);
> +      return Status;
> +    }
> +  } else {
> +    Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);
> +      return Status;
> +    }
>   
> -  Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
> -  if (EFI_ERROR (Status)) {
> -    FreePool (NewKernelArg);
> -    return Status;
> +    Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (NewKernelArg);
> +      return Status;
> +    }

To reduce duplication of the error-handling, I'd personally write it 
like this:

   if (Condition) {
     Status = Op1 ();
   } else {
     Status = Op2 ();
     if (Status != error) {
       Status = Op3 ();
     }
   }
   if (Status == error) {
     HandleError ();
   }

But that's nitpicking of course...

Thanks!

Best regards,
Marvin

>     }
>   
>     KernelDevicePath = mMemoryDevicePathTemplate;
> @@ -466,5 +584,16 @@ AndroidBootImgBoot (
>     Status = gBS->StartImage (ImageHandle, NULL, NULL);
>     // Clear the Watchdog Timer if the image returns
>     gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);
> +
> +  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
> +    mRamdiskData = 0;
> +    mRamdiskSize = 0;
> +    gBS->UninstallMultipleProtocolInterfaces (RamdiskHandle,
> +                                              &gEfiLoadFile2ProtocolGuid,
> +                                              &mAndroidBootImgLoadFile2,
> +                                              &gEfiDevicePathProtocolGuid,
> +                                              &mRamdiskDevicePath,
> +                                              NULL);
> +  }
>     return EFI_SUCCESS;
>   }


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-09-01  9:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <cover.1630449811.git.jbrasen@nvidia.com>
2021-08-31 22:48 ` [PATCH 1/1] EmbeddedPkg: Add LoadFile2 for linux initrd Jeff Brasen
2021-09-01  8:56   ` Ard Biesheuvel
2021-09-01  9:53   ` [edk2-devel] " Marvin Häuser

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox