]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
e1e45e8146014f39efc615f48ba3204bf0f95aa2
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidBoot / AndroidBootApp.c
1 /** @file
2
3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
5
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
10
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.
13
14 **/
15
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>
22
23 #include <Protocol/BlockIo.h>
24 #include <Protocol/DevicePathFromText.h>
25
26 /* Validate the node is media hard drive type */
27 EFI_STATUS
28 ValidateAndroidMediaDevicePath (
29 IN EFI_DEVICE_PATH *DevicePath
30 )
31 {
32 EFI_DEVICE_PATH_PROTOCOL *Node, *NextNode;
33
34 NextNode = DevicePath;
35 while (NextNode != NULL) {
36 Node = NextNode;
37 if (Node->Type == MEDIA_DEVICE_PATH &&
38 Node->SubType == MEDIA_HARDDRIVE_DP) {
39 return EFI_SUCCESS;
40 }
41 NextNode = NextDevicePathNode (Node);
42 }
43 return EFI_INVALID_PARAMETER;
44 }
45
46 EFI_STATUS
47 EFIAPI
48 AndroidBootAppEntryPoint (
49 IN EFI_HANDLE ImageHandle,
50 IN EFI_SYSTEM_TABLE *SystemTable
51 )
52 {
53 EFI_STATUS Status;
54 CHAR16 *BootPathStr;
55 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
56 EFI_DEVICE_PATH *DevicePath;
57 EFI_BLOCK_IO_PROTOCOL *BlockIo;
58 UINT32 MediaId, BlockSize;
59 VOID *Buffer;
60 EFI_HANDLE Handle;
61 UINTN BootImgSize;
62
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);
70
71 Status = ValidateAndroidMediaDevicePath (DevicePath);
72 if (EFI_ERROR (Status)) {
73 return Status;
74 }
75
76 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
77 &DevicePath, &Handle);
78 if (EFI_ERROR (Status)) {
79 return Status;
80 }
81
82 Status = gBS->OpenProtocol (
83 Handle,
84 &gEfiBlockIoProtocolGuid,
85 (VOID **) &BlockIo,
86 gImageHandle,
87 NULL,
88 EFI_OPEN_PROTOCOL_GET_PROTOCOL
89 );
90 if (EFI_ERROR (Status)) {
91 DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
92 return Status;
93 }
94
95 MediaId = BlockIo->Media->MediaId;
96 BlockSize = BlockIo->Media->BlockSize;
97 Buffer = AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
98 if (Buffer == NULL) {
99 return EFI_BUFFER_TOO_SMALL;
100 }
101 /* Load header of boot.img */
102 Status = BlockIo->ReadBlocks (
103 BlockIo,
104 MediaId,
105 0,
106 BlockSize,
107 Buffer
108 );
109 Status = AndroidBootImgGetImgSize (Buffer, &BootImgSize);
110 if (EFI_ERROR (Status)) {
111 DEBUG ((DEBUG_ERROR, "Failed to get AndroidBootImg Size: %r\n", Status));
112 return Status;
113 }
114 BootImgSize = ALIGN_VALUE (BootImgSize, BlockSize);
115 FreePages (Buffer, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
116
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;
121 }
122
123 /* Load header of boot.img */
124 Status = BlockIo->ReadBlocks (
125 BlockIo,
126 MediaId,
127 0,
128 BootImgSize,
129 Buffer
130 );
131 if (EFI_ERROR (Status)) {
132 DEBUG ((DEBUG_ERROR, "Failed to read blocks: %r\n", Status));
133 goto EXIT;
134 }
135
136 Status = AndroidBootImgBoot (Buffer, BootImgSize);
137
138 EXIT:
139 return Status;
140 }