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>
19 #include <Library/BdsLib.h>
20 #include <Library/DevicePathLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
24 #include <Guid/ArmGlobalVariableHob.h>
26 #define LINUX_LOADER_COMMAND_LINE L"%s -f %s -c %s"
28 // This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader
29 CONST EFI_GUID mLinuxLoaderAppGuid
= { 0x701f54f2, 0x0d70, 0x4b89, { 0xbc, 0x0a, 0xd9, 0xca, 0x25, 0x37, 0x90, 0x59 }};
31 // Device Path representing an image in memory
34 MEMMAP_DEVICE_PATH Node1
;
35 EFI_DEVICE_PATH_PROTOCOL End
;
39 STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate
=
46 (UINT8
)(sizeof (MEMMAP_DEVICE_PATH
)),
47 (UINT8
)((sizeof (MEMMAP_DEVICE_PATH
)) >> 8),
50 0, // StartingAddress (set at runtime)
51 0 // EndingAddress (set at runtime)
55 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
56 { sizeof (EFI_DEVICE_PATH_PROTOCOL
), 0 }
67 CHAR8 KernelArgs
[BOOTIMG_KERNEL_ARGS_SIZE
];
72 MEMORY_DEVICE_PATH KernelDevicePath
;
73 MEMORY_DEVICE_PATH
* RamdiskDevicePath
;
74 CHAR16
* KernelDevicePathTxt
;
75 CHAR16
* RamdiskDevicePathTxt
;
76 EFI_DEVICE_PATH
* LinuxLoaderDevicePath
;
79 Status
= ParseAndroidBootImg (
87 if (EFI_ERROR (Status
)) {
91 KernelDevicePath
= MemoryDevicePathTemplate
;
93 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
95 KernelDevicePath
.Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
;
96 KernelDevicePath
.Node1
.EndingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
+ KernelSize
;
98 RamdiskDevicePath
= NULL
;
99 if (RamdiskSize
!= 0) {
100 RamdiskDevicePath
= (MEMORY_DEVICE_PATH
*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &MemoryDevicePathTemplate
);
102 RamdiskDevicePath
->Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Ramdisk
;
103 RamdiskDevicePath
->Node1
.EndingAddress
= ((EFI_PHYSICAL_ADDRESS
)(UINTN
) Ramdisk
) + RamdiskSize
;
107 // Boot Linux using the Legacy Linux Loader
110 Status
= LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid
, &LinuxLoaderDevicePath
);
111 if (EFI_ERROR (Status
)) {
112 Print (L
"Couldn't Boot Linux: %d\n", Status
);
113 return EFI_DEVICE_ERROR
;
116 KernelDevicePathTxt
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*) &KernelDevicePath
, FALSE
, FALSE
);
117 if (KernelDevicePathTxt
== NULL
) {
118 return EFI_OUT_OF_RESOURCES
;
121 RamdiskDevicePathTxt
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*) RamdiskDevicePath
, FALSE
, FALSE
);
122 if (RamdiskDevicePathTxt
== NULL
) {
123 return EFI_OUT_OF_RESOURCES
;
126 // Initialize Legacy Linux loader command line
127 LoadOptions
= CatSPrint (NULL
, LINUX_LOADER_COMMAND_LINE
, KernelDevicePathTxt
, RamdiskDevicePathTxt
, KernelArgs
);
128 if (LoadOptions
== NULL
) {
129 return EFI_OUT_OF_RESOURCES
;
132 Status
= BdsStartEfiApplication (gImageHandle
, LinuxLoaderDevicePath
, StrSize (LoadOptions
), LoadOptions
);
133 if (EFI_ERROR (Status
)) {
134 DEBUG ((EFI_D_ERROR
, "Couldn't Boot Linux: %d\n", Status
));
135 return EFI_DEVICE_ERROR
;
138 if (RamdiskDevicePath
) {
139 FreePool (RamdiskDevicePathTxt
);
140 FreePool (RamdiskDevicePath
);
143 FreePool (KernelDevicePathTxt
);
145 // If we got here we do a confused face because BootLinuxFdt returned,
146 // reporting success.
147 DEBUG ((EFI_D_ERROR
, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));