EmbeddedPkg/AndroidFastboot: Introduce Android FastBoot Application
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidFastboot / Arm / BootAndroidBootImg.c
CommitLineData
f6755908
OM
1/** @file\r
2\r
3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
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
18\r
19#include <Library/BdsLib.h>\r
20#include <Library/DevicePathLib.h>\r
21\r
22#include <Guid/ArmGlobalVariableHob.h>\r
23\r
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
49 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
50 0\r
51 } // End\r
52};\r
53\r
54EFI_STATUS\r
55BootAndroidBootImg (\r
56 IN UINTN BufferSize,\r
57 IN VOID *Buffer\r
58 )\r
59{\r
60 EFI_DEVICE_PATH_PROTOCOL *FdtDevicePath;\r
61 EFI_STATUS Status;\r
62 CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];\r
63 VOID *Kernel;\r
64 UINTN KernelSize;\r
65 VOID *Ramdisk;\r
66 UINTN RamdiskSize;\r
67 MEMORY_DEVICE_PATH KernelDevicePath;\r
68 MEMORY_DEVICE_PATH* RamdiskDevicePath;\r
69\r
70 Status = ParseAndroidBootImg (\r
71 Buffer,\r
72 &Kernel,\r
73 &KernelSize,\r
74 &Ramdisk,\r
75 &RamdiskSize,\r
76 KernelArgs\r
77 );\r
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
82 KernelDevicePath = MemoryDevicePathTemplate;\r
83\r
84 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to\r
85 // appease GCC.\r
86 KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;\r
87 KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;\r
88\r
89 RamdiskDevicePath = NULL;\r
90 if (RamdiskSize != 0) {\r
91 RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate);\r
92\r
93 RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk;\r
94 RamdiskDevicePath->Node1.EndingAddress = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize;\r
95 }\r
96\r
97 // Get the default FDT device path\r
98 Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,\r
99 NULL, 0, (VOID **)&FdtDevicePath);\r
100 if (Status == EFI_NOT_FOUND) {\r
101 DEBUG ((EFI_D_ERROR, "Error: Please update FDT path in boot manager\n"));\r
102 return EFI_DEVICE_ERROR;\r
103 }\r
104 ASSERT_EFI_ERROR (Status);\r
105\r
106 Status = BdsBootLinuxFdt (\r
107 (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath,\r
108 (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath,\r
109 KernelArgs,\r
110 FdtDevicePath\r
111 );\r
112 if (EFI_ERROR (Status)) {\r
113 DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status));\r
114 return EFI_DEVICE_ERROR;\r
115 }\r
116\r
117 if (RamdiskDevicePath) {\r
118 FreePool (RamdiskDevicePath);\r
119 }\r
120\r
121 // If we got here we do a confused face because BootLinuxFdt returned,\r
122 // reporting success.\r
123 DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));\r
124 return EFI_SUCCESS;\r
125}\r