3 Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "AndroidFastbootApp.h"
17 #include <Protocol/DevicePath.h>
18 #include <Protocol/LoadedImage.h>
20 #include <Library/DevicePathLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
24 // Device Path representing an image in memory
27 MEMMAP_DEVICE_PATH Node1
;
28 EFI_DEVICE_PATH_PROTOCOL End
;
32 STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate
=
39 (UINT8
)(sizeof (MEMMAP_DEVICE_PATH
)),
40 (UINT8
)((sizeof (MEMMAP_DEVICE_PATH
)) >> 8),
43 0, // StartingAddress (set at runtime)
44 0 // EndingAddress (set at runtime)
48 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 { sizeof (EFI_DEVICE_PATH_PROTOCOL
), 0 }
55 Start an EFI Application from a Device Path
57 @param ParentImageHandle Handle of the calling image
58 @param DevicePath Location of the EFI Application
60 @retval EFI_SUCCESS All drivers have been connected
61 @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
62 @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
68 IN EFI_HANDLE ParentImageHandle
,
69 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
70 IN UINTN LoadOptionsSize
,
75 EFI_HANDLE ImageHandle
;
76 EFI_LOADED_IMAGE_PROTOCOL
* LoadedImage
;
78 // Load the image from the device path with Boot Services function
79 Status
= gBS
->LoadImage (TRUE
, ParentImageHandle
, DevicePath
, NULL
, 0,
81 if (EFI_ERROR (Status
)) {
85 // Passed LoadOptions to the EFI Application
86 if (LoadOptionsSize
!= 0) {
87 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
,
88 (VOID
**) &LoadedImage
);
89 if (EFI_ERROR (Status
)) {
93 LoadedImage
->LoadOptionsSize
= LoadOptionsSize
;
94 LoadedImage
->LoadOptions
= LoadOptions
;
97 // Before calling the image, enable the Watchdog Timer for the 5 Minute period
98 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
100 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
101 // Clear the Watchdog Timer after the image returns
102 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
114 CHAR8 KernelArgs
[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE
];
119 MEMORY_DEVICE_PATH KernelDevicePath
;
120 CHAR16
*LoadOptions
, *NewLoadOptions
;
122 Status
= ParseAndroidBootImg (
130 if (EFI_ERROR (Status
)) {
134 KernelDevicePath
= MemoryDevicePathTemplate
;
136 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
138 KernelDevicePath
.Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
;
139 KernelDevicePath
.Node1
.EndingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
+ KernelSize
;
141 // Initialize Linux command line
142 LoadOptions
= CatSPrint (NULL
, L
"%a", KernelArgs
);
143 if (LoadOptions
== NULL
) {
144 return EFI_OUT_OF_RESOURCES
;
147 if (RamdiskSize
!= 0) {
148 NewLoadOptions
= CatSPrint (LoadOptions
, L
" initrd=0x%x,0x%x",
149 (UINTN
)Ramdisk
, RamdiskSize
);
150 FreePool (LoadOptions
);
151 if (NewLoadOptions
== NULL
) {
152 return EFI_OUT_OF_RESOURCES
;
154 LoadOptions
= NewLoadOptions
;
157 Status
= StartEfiApplication (gImageHandle
,
158 (EFI_DEVICE_PATH_PROTOCOL
*) &KernelDevicePath
,
159 StrSize (LoadOptions
),
161 if (EFI_ERROR (Status
)) {
162 DEBUG ((EFI_D_ERROR
, "Couldn't Boot Linux: %d\n", Status
));
163 Status
= EFI_DEVICE_ERROR
;
164 goto FreeLoadOptions
;
167 // If we got here we do a confused face because BootLinuxFdt returned,
168 // reporting success.
169 DEBUG ((EFI_D_ERROR
, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
173 FreePool (LoadOptions
);