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/BdsLib.h>
21 #include <Library/DevicePathLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiLib.h>
25 // Device Path representing an image in memory
28 MEMMAP_DEVICE_PATH Node1
;
29 EFI_DEVICE_PATH_PROTOCOL End
;
33 STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate
=
40 (UINT8
)(sizeof (MEMMAP_DEVICE_PATH
)),
41 (UINT8
)((sizeof (MEMMAP_DEVICE_PATH
)) >> 8),
44 0, // StartingAddress (set at runtime)
45 0 // EndingAddress (set at runtime)
49 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
50 { sizeof (EFI_DEVICE_PATH_PROTOCOL
), 0 }
56 Start an EFI Application from a Device Path
58 @param ParentImageHandle Handle of the calling image
59 @param DevicePath Location of the EFI Application
61 @retval EFI_SUCCESS All drivers have been connected
62 @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
63 @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
69 IN EFI_HANDLE ParentImageHandle
,
70 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
71 IN UINTN LoadOptionsSize
,
76 EFI_HANDLE ImageHandle
;
77 EFI_LOADED_IMAGE_PROTOCOL
* LoadedImage
;
79 // Load the image from the device path with Boot Services function
80 Status
= gBS
->LoadImage (TRUE
, ParentImageHandle
, DevicePath
, NULL
, 0,
82 if (EFI_ERROR (Status
)) {
86 // Passed LoadOptions to the EFI Application
87 if (LoadOptionsSize
!= 0) {
88 Status
= gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
,
89 (VOID
**) &LoadedImage
);
90 if (EFI_ERROR (Status
)) {
94 LoadedImage
->LoadOptionsSize
= LoadOptionsSize
;
95 LoadedImage
->LoadOptions
= LoadOptions
;
98 // Before calling the image, enable the Watchdog Timer for the 5 Minute period
99 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
101 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
102 // Clear the Watchdog Timer after the image returns
103 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
115 CHAR8 KernelArgs
[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE
];
120 MEMORY_DEVICE_PATH KernelDevicePath
;
121 CHAR16
*LoadOptions
, *NewLoadOptions
;
123 Status
= ParseAndroidBootImg (
131 if (EFI_ERROR (Status
)) {
135 KernelDevicePath
= MemoryDevicePathTemplate
;
137 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
139 KernelDevicePath
.Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
;
140 KernelDevicePath
.Node1
.EndingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
+ KernelSize
;
142 // Initialize Linux command line
143 LoadOptions
= CatSPrint (NULL
, L
"%a", KernelArgs
);
144 if (LoadOptions
== NULL
) {
145 return EFI_OUT_OF_RESOURCES
;
148 if (RamdiskSize
!= 0) {
149 NewLoadOptions
= CatSPrint (LoadOptions
, L
" initrd=0x%x,0x%x",
150 (UINTN
)Ramdisk
, RamdiskSize
);
151 FreePool (LoadOptions
);
152 if (NewLoadOptions
== NULL
) {
153 return EFI_OUT_OF_RESOURCES
;
155 LoadOptions
= NewLoadOptions
;
158 Status
= StartEfiApplication (gImageHandle
,
159 (EFI_DEVICE_PATH_PROTOCOL
*) &KernelDevicePath
,
160 StrSize (LoadOptions
),
162 if (EFI_ERROR (Status
)) {
163 DEBUG ((EFI_D_ERROR
, "Couldn't Boot Linux: %d\n", Status
));
164 Status
= EFI_DEVICE_ERROR
;
165 goto FreeLoadOptions
;
168 // If we got here we do a confused face because BootLinuxFdt returned,
169 // reporting success.
170 DEBUG ((EFI_D_ERROR
, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
174 FreePool (LoadOptions
);