3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/AndroidBootImgLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/DevicePathLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
17 #include <Protocol/BlockIo.h>
18 #include <Protocol/DevicePathFromText.h>
20 /* Validate the node is media hard drive type */
22 ValidateAndroidMediaDevicePath (
23 IN EFI_DEVICE_PATH
*DevicePath
26 EFI_DEVICE_PATH_PROTOCOL
*Node
, *NextNode
;
28 NextNode
= DevicePath
;
29 while (NextNode
!= NULL
) {
31 if ((Node
->Type
== MEDIA_DEVICE_PATH
) &&
32 (Node
->SubType
== MEDIA_HARDDRIVE_DP
))
37 NextNode
= NextDevicePathNode (Node
);
40 return EFI_INVALID_PARAMETER
;
45 AndroidBootAppEntryPoint (
46 IN EFI_HANDLE ImageHandle
,
47 IN EFI_SYSTEM_TABLE
*SystemTable
52 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL
*EfiDevicePathFromTextProtocol
;
53 EFI_DEVICE_PATH
*DevicePath
;
54 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
55 UINT32 MediaId
, BlockSize
;
60 BootPathStr
= (CHAR16
*)PcdGetPtr (PcdAndroidBootDevicePath
);
61 ASSERT (BootPathStr
!= NULL
);
62 Status
= gBS
->LocateProtocol (
63 &gEfiDevicePathFromTextProtocolGuid
,
65 (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 (
77 &gEfiDevicePathProtocolGuid
,
81 if (EFI_ERROR (Status
)) {
85 Status
= gBS
->OpenProtocol (
87 &gEfiBlockIoProtocolGuid
,
91 EFI_OPEN_PROTOCOL_GET_PROTOCOL
93 if (EFI_ERROR (Status
)) {
94 DEBUG ((DEBUG_ERROR
, "Failed to get BlockIo: %r\n", Status
));
98 MediaId
= BlockIo
->Media
->MediaId
;
99 BlockSize
= BlockIo
->Media
->BlockSize
;
100 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ANDROID_BOOTIMG_HEADER
)));
101 if (Buffer
== NULL
) {
102 return EFI_BUFFER_TOO_SMALL
;
105 /* Load header of boot.img */
106 Status
= BlockIo
->ReadBlocks (
113 Status
= AndroidBootImgGetImgSize (Buffer
, &BootImgSize
);
114 if (EFI_ERROR (Status
)) {
115 DEBUG ((DEBUG_ERROR
, "Failed to get AndroidBootImg Size: %r\n", Status
));
119 BootImgSize
= ALIGN_VALUE (BootImgSize
, BlockSize
);
120 FreePages (Buffer
, EFI_SIZE_TO_PAGES (sizeof (ANDROID_BOOTIMG_HEADER
)));
122 /* Both PartitionStart and PartitionSize are counted as block size. */
123 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize
));
124 if (Buffer
== NULL
) {
125 return EFI_BUFFER_TOO_SMALL
;
128 /* Load header of boot.img */
129 Status
= BlockIo
->ReadBlocks (
136 if (EFI_ERROR (Status
)) {
137 DEBUG ((DEBUG_ERROR
, "Failed to read blocks: %r\n", Status
));
141 Status
= AndroidBootImgBoot (Buffer
, BootImgSize
);