Re: [edk2] [PATCH v6 2/2] EmbeddedPkg/AndroidBoot: boot android kernel from storage

2017-08-10 Thread Leif Lindholm
On Wed, Aug 09, 2017 at 06:39:23PM +0800, Jun Nie wrote:
> Add an android kernel loader that could load kernel from storage
> device.
> This android boot image BDS add addtitional cmdline/dtb/ramfs
> support besides kernel that is introduced by Android boot header.
> 
> This patch is derived from Haojian's code as below link.
> https://patches.linaro.org/patch/94683/
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jun Nie 
> ---
>  .../Application/AndroidBoot/AndroidBootApp.c   | 140 ++
>  .../Application/AndroidBoot/AndroidBootApp.inf |  64 +++
>  EmbeddedPkg/EmbeddedPkg.dec|   2 +
>  EmbeddedPkg/EmbeddedPkg.dsc|   2 +
>  EmbeddedPkg/Include/Library/AndroidBootImgLib.h|  13 +
>  EmbeddedPkg/Include/Protocol/AndroidBootImg.h  |  47 ++
>  .../Library/AndroidBootImgLib/AndroidBootImgLib.c  | 471 
> +
>  .../AndroidBootImgLib/AndroidBootImgLib.inf|  48 +++
>  8 files changed, 787 insertions(+)
>  create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
>  create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf
>  create mode 100644 EmbeddedPkg/Include/Protocol/AndroidBootImg.h
>  create mode 100644 EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
>  create mode 100644 
> EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
> 

> diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c 
> b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> new file mode 100644
> index 000..cb4fb67
> --- /dev/null
> +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
> @@ -0,0 +1,471 @@
> +/** @file
> +
> +  Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
> +  Copyright (c) 2017, Linaro. All rights reserved.
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD 
> License
> +  which accompanies this distribution.  The full text of the license may be 
> found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
> IMPLIED.
> +
> +**/
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +#define FDT_ADDITIONAL_ENTRIES_SIZE 0x400
> +
> +typedef struct {
> +  MEMMAP_DEVICE_PATH  Node1;
> +  EFI_DEVICE_PATH_PROTOCOLEnd;
> +} MEMORY_DEVICE_PATH;
> +
> +STATIC ANDROID_BOOTIMG_PROTOCOL *mAndroidBootImg;
> +
> +STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
> +{
> +  {
> +{
> +  HARDWARE_DEVICE_PATH,
> +  HW_MEMMAP_DP,
> +  {
> +(UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
> +(UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),
> +  },
> +}, // Header
> +0, // StartingAddress (set at runtime)
> +0  // EndingAddress   (set at runtime)
> +  }, // Node1
> +  {
> +END_DEVICE_PATH_TYPE,
> +END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
> +  } // End
> +};
> +
> +EFI_STATUS
> +AndroidBootImgGetImgSize (
> +  IN  VOID*BootImg,
> +  OUT UINTN   *ImgSize
> +  )
> +{
> +  ANDROID_BOOTIMG_HEADER   *Header;
> +
> +  Header = (ANDROID_BOOTIMG_HEADER *) BootImg;
> +
> +  if (AsciiStrnCmp ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC,
> +ANDROID_BOOT_MAGIC_LENGTH) != 0) {
> +return EFI_INVALID_PARAMETER;
> +  }
> +
> +  /* The page size is not specified, but it should be power of 2 at least */
> +  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
> +
> +  /* Get real size of abootimg */
> +  *ImgSize = ALIGN_VALUE (Header->KernelSize, Header->PageSize) +
> + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize) +
> + ALIGN_VALUE (Header->SecondStageBootloaderSize, 
> Header->PageSize) +
> + Header->PageSize;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AndroidBootImgGetKernelInfo (
> +  IN  VOID*BootImg,
> +  OUT VOID   **Kernel,
> +  OUT UINTN   *KernelSize
> +  )
> +{
> +  ANDROID_BOOTIMG_HEADER   *Header;
> +
> +  Header = (ANDROID_BOOTIMG_HEADER *) BootImg;
> +
> +  if (AsciiStrnCmp ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC,
> +ANDROID_BOOT_MAGIC_LENGTH) != 0) {
> +return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Header->KernelSize == 0) {
> +return EFI_NOT_FOUND;
> +  }
> +
> +  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
> +
> +  *KernelSize = Header->KernelSize;
> +  *Kernel = BootImg + Header->PageSize;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AndroidBootImgGetRamdiskInfo (
> +  IN  VOID*BootImg,
> +  OUT VOID   **Ramdisk,
> +  OUT UINTN   *RamdiskSize
> +  )
> +{
> +  ANDROID_BOOTIMG_HEADER   *Header;
> +  UINT8*BootImgBy

[edk2] [PATCH v6 2/2] EmbeddedPkg/AndroidBoot: boot android kernel from storage

2017-08-09 Thread Jun Nie
Add an android kernel loader that could load kernel from storage
device.
This android boot image BDS add addtitional cmdline/dtb/ramfs
support besides kernel that is introduced by Android boot header.

This patch is derived from Haojian's code as below link.
https://patches.linaro.org/patch/94683/

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jun Nie 
---
 .../Application/AndroidBoot/AndroidBootApp.c   | 140 ++
 .../Application/AndroidBoot/AndroidBootApp.inf |  64 +++
 EmbeddedPkg/EmbeddedPkg.dec|   2 +
 EmbeddedPkg/EmbeddedPkg.dsc|   2 +
 EmbeddedPkg/Include/Library/AndroidBootImgLib.h|  13 +
 EmbeddedPkg/Include/Protocol/AndroidBootImg.h  |  47 ++
 .../Library/AndroidBootImgLib/AndroidBootImgLib.c  | 471 +
 .../AndroidBootImgLib/AndroidBootImgLib.inf|  48 +++
 8 files changed, 787 insertions(+)
 create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
 create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf
 create mode 100644 EmbeddedPkg/Include/Protocol/AndroidBootImg.h
 create mode 100644 EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
 create mode 100644 EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf

diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c 
b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
new file mode 100644
index 000..977167d
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
@@ -0,0 +1,140 @@
+/** @file
+
+  Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
+  Copyright (c) 2017, Linaro. All rights reserved.
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD 
License
+  which accompanies this distribution.  The full text of the license may be 
found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/* Validate the node is media hard drive type */
+EFI_STATUS
+ValidateAndroidMediaDevicePath (
+  IN EFI_DEVICE_PATH  *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL*Node, *NextNode;
+
+  NextNode = DevicePath;
+  while (NextNode != NULL) {
+Node = NextNode;
+if (IS_DEVICE_PATH_NODE (Node, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP)) {
+  return EFI_SUCCESS;
+}
+NextNode = NextDevicePathNode (Node);
+  }
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+AndroidBootAppEntryPoint (
+  IN EFI_HANDLEImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  CHAR16  *BootPathStr;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
+  EFI_DEVICE_PATH *DevicePath;
+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
+  UINT32  MediaId, BlockSize;
+  VOID*Buffer;
+  EFI_HANDLE  Handle;
+  UINTN   BootImgSize;
+
+  BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
+  ASSERT (BootPathStr != NULL);
+  Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL,
+(VOID **)&EfiDevicePathFromTextProtocol);
+  ASSERT_EFI_ERROR(Status);
+  DevicePath = (EFI_DEVICE_PATH 
*)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
+  ASSERT (DevicePath != NULL);
+
+  Status = ValidateAndroidMediaDevicePath (DevicePath);
+  if (EFI_ERROR (Status)) {
+return Status;
+  }
+
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
+  &DevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+return Status;
+  }
+
+  Status = gBS->OpenProtocol (
+  Handle,
+  &gEfiBlockIoProtocolGuid,
+  (VOID **) &BlockIo,
+  gImageHandle,
+  NULL,
+  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+  );
+  if (EFI_ERROR (Status)) {
+DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
+return Status;
+  }
+
+  MediaId = BlockIo->Media->MediaId;
+  BlockSize = BlockIo->Media->BlockSize;
+  Buffer = AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
+  if (Buffer == NULL) {
+return EFI_BUFFER_TOO_SMALL;
+  }
+  /* Load header of boot.img */
+  Status = BlockIo->ReadBlocks (
+  BlockIo,
+  MediaId,
+  0,
+  BlockSize,
+  Buffer
+  );
+  Status = AndroidBootImgGetImgSize (Buffer, &BootImgSize);