summaryrefslogtreecommitdiffstats
path: root/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c')
-rw-r--r--EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
new file mode 100644
index 0000000000..977167da40
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
@@ -0,0 +1,140 @@
+/** @file
+
+ Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+ 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 <Library/AndroidBootImgLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BdsLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePathFromText.h>
+
+/* 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_HANDLE ImageHandle,
+ 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);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to get AndroidBootImg Size: %r\n", Status));
+ return Status;
+ }
+ BootImgSize = ALIGN_VALUE (BootImgSize, BlockSize);
+ FreePages (Buffer, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
+
+ /* Both PartitionStart and PartitionSize are counted as block size. */
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize));
+ if (Buffer == NULL) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ /* Load header of boot.img */
+ Status = BlockIo->ReadBlocks (
+ BlockIo,
+ MediaId,
+ 0,
+ BootImgSize,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to read blocks: %r\n", Status));
+ goto EXIT;
+ }
+
+ Status = AndroidBootImgBoot (Buffer, BootImgSize);
+
+EXIT:
+ return Status;
+}