]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
EmbeddedPkg: get rid of BdsLib dependency from Android*Boot
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidFastboot / Arm / BootAndroidBootImg.c
CommitLineData
f6755908
OM
1/** @file\r
2\r
bd9a5182 3 Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>\r
f6755908
OM
4\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "AndroidFastbootApp.h"\r
16\r
17#include <Protocol/DevicePath.h>\r
fcf41edf 18#include <Protocol/LoadedImage.h>\r
f6755908 19\r
f6755908 20#include <Library/DevicePathLib.h>\r
bd9a5182
OM
21#include <Library/UefiBootServicesTableLib.h>\r
22#include <Library/UefiLib.h>\r
f6755908 23\r
f6755908
OM
24// Device Path representing an image in memory\r
25#pragma pack(1)\r
26typedef struct {\r
27 MEMMAP_DEVICE_PATH Node1;\r
28 EFI_DEVICE_PATH_PROTOCOL End;\r
29} MEMORY_DEVICE_PATH;\r
30#pragma pack()\r
31\r
32STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate =\r
33{\r
34 {\r
35 {\r
36 HARDWARE_DEVICE_PATH,\r
37 HW_MEMMAP_DP,\r
38 {\r
39 (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),\r
40 (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),\r
41 },\r
42 }, // Header\r
43 0, // StartingAddress (set at runtime)\r
44 0 // EndingAddress (set at runtime)\r
45 }, // Node1\r
46 {\r
47 END_DEVICE_PATH_TYPE,\r
48 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
b0fdce95 49 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
f6755908
OM
50 } // End\r
51};\r
52\r
fcf41edf
AB
53\r
54/**\r
55 Start an EFI Application from a Device Path\r
56\r
57 @param ParentImageHandle Handle of the calling image\r
58 @param DevicePath Location of the EFI Application\r
59\r
60 @retval EFI_SUCCESS All drivers have been connected\r
61 @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found\r
62 @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.\r
63\r
64**/\r
65STATIC\r
66EFI_STATUS\r
67StartEfiApplication (\r
68 IN EFI_HANDLE ParentImageHandle,\r
69 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
70 IN UINTN LoadOptionsSize,\r
71 IN VOID* LoadOptions\r
72 )\r
73{\r
74 EFI_STATUS Status;\r
75 EFI_HANDLE ImageHandle;\r
76 EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;\r
77\r
78 // Load the image from the device path with Boot Services function\r
79 Status = gBS->LoadImage (TRUE, ParentImageHandle, DevicePath, NULL, 0,\r
80 &ImageHandle);\r
81 if (EFI_ERROR (Status)) {\r
82 return Status;\r
83 }\r
84\r
85 // Passed LoadOptions to the EFI Application\r
86 if (LoadOptionsSize != 0) {\r
87 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,\r
88 (VOID **) &LoadedImage);\r
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
92\r
93 LoadedImage->LoadOptionsSize = LoadOptionsSize;\r
94 LoadedImage->LoadOptions = LoadOptions;\r
95 }\r
96\r
97 // Before calling the image, enable the Watchdog Timer for the 5 Minute period\r
98 gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
99 // Start the image\r
100 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
101 // Clear the Watchdog Timer after the image returns\r
102 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
103\r
104 return Status;\r
105}\r
106\r
f6755908
OM
107EFI_STATUS\r
108BootAndroidBootImg (\r
109 IN UINTN BufferSize,\r
110 IN VOID *Buffer\r
111 )\r
112{\r
f6755908 113 EFI_STATUS Status;\r
6e414300 114 CHAR8 KernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE];\r
f6755908
OM
115 VOID *Kernel;\r
116 UINTN KernelSize;\r
117 VOID *Ramdisk;\r
118 UINTN RamdiskSize;\r
119 MEMORY_DEVICE_PATH KernelDevicePath;\r
34e0bcea 120 CHAR16 *LoadOptions, *NewLoadOptions;\r
f6755908
OM
121\r
122 Status = ParseAndroidBootImg (\r
123 Buffer,\r
124 &Kernel,\r
125 &KernelSize,\r
126 &Ramdisk,\r
127 &RamdiskSize,\r
128 KernelArgs\r
129 );\r
130 if (EFI_ERROR (Status)) {\r
131 return Status;\r
132 }\r
133\r
134 KernelDevicePath = MemoryDevicePathTemplate;\r
135\r
136 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to\r
137 // appease GCC.\r
138 KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;\r
139 KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;\r
140\r
34e0bcea
AB
141 // Initialize Linux command line\r
142 LoadOptions = CatSPrint (NULL, L"%a", KernelArgs);\r
143 if (LoadOptions == NULL) {\r
bd9a5182
OM
144 return EFI_OUT_OF_RESOURCES;\r
145 }\r
146\r
34e0bcea
AB
147 if (RamdiskSize != 0) {\r
148 NewLoadOptions = CatSPrint (LoadOptions, L" initrd=0x%x,0x%x",\r
149 (UINTN)Ramdisk, RamdiskSize);\r
150 FreePool (LoadOptions);\r
151 if (NewLoadOptions == NULL) {\r
152 return EFI_OUT_OF_RESOURCES;\r
153 }\r
154 LoadOptions = NewLoadOptions;\r
bd9a5182
OM
155 }\r
156\r
fcf41edf 157 Status = StartEfiApplication (gImageHandle,\r
34e0bcea
AB
158 (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath,\r
159 StrSize (LoadOptions),\r
160 LoadOptions);\r
f6755908
OM
161 if (EFI_ERROR (Status)) {\r
162 DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status));\r
34e0bcea
AB
163 Status = EFI_DEVICE_ERROR;\r
164 goto FreeLoadOptions;\r
f6755908
OM
165 }\r
166\r
167 // If we got here we do a confused face because BootLinuxFdt returned,\r
168 // reporting success.\r
169 DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));\r
170 return EFI_SUCCESS;\r
34e0bcea
AB
171\r
172FreeLoadOptions:\r
173 FreePool (LoadOptions);\r
174 return Status;\r
f6755908 175}\r