3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/AndroidBootImgLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/DevicePathLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
23 #include <Protocol/BlockIo.h>
24 #include <Protocol/DevicePathFromText.h>
26 /* Validate the node is media hard drive type */
28 ValidateAndroidMediaDevicePath (
29 IN EFI_DEVICE_PATH
*DevicePath
32 EFI_DEVICE_PATH_PROTOCOL
*Node
, *NextNode
;
34 NextNode
= DevicePath
;
35 while (NextNode
!= NULL
) {
37 if (Node
->Type
== MEDIA_DEVICE_PATH
&&
38 Node
->SubType
== MEDIA_HARDDRIVE_DP
) {
41 NextNode
= NextDevicePathNode (Node
);
43 return EFI_INVALID_PARAMETER
;
48 AndroidBootAppEntryPoint (
49 IN EFI_HANDLE ImageHandle
,
50 IN EFI_SYSTEM_TABLE
*SystemTable
55 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL
*EfiDevicePathFromTextProtocol
;
56 EFI_DEVICE_PATH
*DevicePath
;
57 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
58 UINT32 MediaId
, BlockSize
;
63 BootPathStr
= (CHAR16
*)PcdGetPtr (PcdAndroidBootDevicePath
);
64 ASSERT (BootPathStr
!= NULL
);
65 Status
= gBS
->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid
, NULL
,
66 (VOID
**)&EfiDevicePathFromTextProtocol
);
67 ASSERT_EFI_ERROR(Status
);
68 DevicePath
= (EFI_DEVICE_PATH
*)EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (BootPathStr
);
69 ASSERT (DevicePath
!= NULL
);
71 Status
= ValidateAndroidMediaDevicePath (DevicePath
);
72 if (EFI_ERROR (Status
)) {
76 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
,
77 &DevicePath
, &Handle
);
78 if (EFI_ERROR (Status
)) {
82 Status
= gBS
->OpenProtocol (
84 &gEfiBlockIoProtocolGuid
,
88 EFI_OPEN_PROTOCOL_GET_PROTOCOL
90 if (EFI_ERROR (Status
)) {
91 DEBUG ((DEBUG_ERROR
, "Failed to get BlockIo: %r\n", Status
));
95 MediaId
= BlockIo
->Media
->MediaId
;
96 BlockSize
= BlockIo
->Media
->BlockSize
;
97 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER
)));
99 return EFI_BUFFER_TOO_SMALL
;
101 /* Load header of boot.img */
102 Status
= BlockIo
->ReadBlocks (
109 Status
= AndroidBootImgGetImgSize (Buffer
, &BootImgSize
);
110 if (EFI_ERROR (Status
)) {
111 DEBUG ((DEBUG_ERROR
, "Failed to get AndroidBootImg Size: %r\n", Status
));
114 BootImgSize
= ALIGN_VALUE (BootImgSize
, BlockSize
);
115 FreePages (Buffer
, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER
)));
117 /* Both PartitionStart and PartitionSize are counted as block size. */
118 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize
));
119 if (Buffer
== NULL
) {
120 return EFI_BUFFER_TOO_SMALL
;
123 /* Load header of boot.img */
124 Status
= BlockIo
->ReadBlocks (
131 if (EFI_ERROR (Status
)) {
132 DEBUG ((DEBUG_ERROR
, "Failed to read blocks: %r\n", Status
));
136 Status
= AndroidBootImgBoot (Buffer
, BootImgSize
);