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 #define LINUX_LOADER_COMMAND_LINE L"%s -f %s -c %s"
26 // This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader
27 CONST EFI_GUID mLinuxLoaderAppGuid
= { 0x701f54f2, 0x0d70, 0x4b89, { 0xbc, 0x0a, 0xd9, 0xca, 0x25, 0x37, 0x90, 0x59 }};
29 // Device Path representing an image in memory
32 MEMMAP_DEVICE_PATH Node1
;
33 EFI_DEVICE_PATH_PROTOCOL End
;
37 STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate
=
44 (UINT8
)(sizeof (MEMMAP_DEVICE_PATH
)),
45 (UINT8
)((sizeof (MEMMAP_DEVICE_PATH
)) >> 8),
48 0, // StartingAddress (set at runtime)
49 0 // EndingAddress (set at runtime)
53 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
54 { sizeof (EFI_DEVICE_PATH_PROTOCOL
), 0 }
65 CHAR8 KernelArgs
[BOOTIMG_KERNEL_ARGS_SIZE
];
70 MEMORY_DEVICE_PATH KernelDevicePath
;
71 MEMORY_DEVICE_PATH
* RamdiskDevicePath
;
72 CHAR16
* KernelDevicePathTxt
;
73 CHAR16
* RamdiskDevicePathTxt
;
74 EFI_DEVICE_PATH
* LinuxLoaderDevicePath
;
77 Status
= ParseAndroidBootImg (
85 if (EFI_ERROR (Status
)) {
89 KernelDevicePath
= MemoryDevicePathTemplate
;
91 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
93 KernelDevicePath
.Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
;
94 KernelDevicePath
.Node1
.EndingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Kernel
+ KernelSize
;
96 RamdiskDevicePath
= NULL
;
97 if (RamdiskSize
!= 0) {
98 RamdiskDevicePath
= (MEMORY_DEVICE_PATH
*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &MemoryDevicePathTemplate
);
100 RamdiskDevicePath
->Node1
.StartingAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Ramdisk
;
101 RamdiskDevicePath
->Node1
.EndingAddress
= ((EFI_PHYSICAL_ADDRESS
)(UINTN
) Ramdisk
) + RamdiskSize
;
105 // Boot Linux using the Legacy Linux Loader
108 Status
= LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid
, &LinuxLoaderDevicePath
);
109 if (EFI_ERROR (Status
)) {
110 Print (L
"Couldn't Boot Linux: %d\n", Status
);
111 return EFI_DEVICE_ERROR
;
114 KernelDevicePathTxt
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*) &KernelDevicePath
, FALSE
, FALSE
);
115 if (KernelDevicePathTxt
== NULL
) {
116 return EFI_OUT_OF_RESOURCES
;
119 RamdiskDevicePathTxt
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*) RamdiskDevicePath
, FALSE
, FALSE
);
120 if (RamdiskDevicePathTxt
== NULL
) {
121 return EFI_OUT_OF_RESOURCES
;
124 // Initialize Legacy Linux loader command line
125 LoadOptions
= CatSPrint (NULL
, LINUX_LOADER_COMMAND_LINE
, KernelDevicePathTxt
, RamdiskDevicePathTxt
, KernelArgs
);
126 if (LoadOptions
== NULL
) {
127 return EFI_OUT_OF_RESOURCES
;
130 Status
= BdsStartEfiApplication (gImageHandle
, LinuxLoaderDevicePath
, StrSize (LoadOptions
), LoadOptions
);
131 if (EFI_ERROR (Status
)) {
132 DEBUG ((EFI_D_ERROR
, "Couldn't Boot Linux: %d\n", Status
));
133 return EFI_DEVICE_ERROR
;
136 if (RamdiskDevicePath
) {
137 FreePool (RamdiskDevicePathTxt
);
138 FreePool (RamdiskDevicePath
);
141 FreePool (KernelDevicePathTxt
);
143 // If we got here we do a confused face because BootLinuxFdt returned,
144 // reporting success.
145 DEBUG ((EFI_D_ERROR
, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));