]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Application/LinuxLoader/LinuxLoaderEfiApp.c
BeagleBoardPkg/BeagleBoardPkg.dsc: remove the LinuxLoader application
[mirror_edk2.git] / ArmPkg / Application / LinuxLoader / LinuxLoaderEfiApp.c
CommitLineData
23b01c83
RC
1/** @file\r
2*\r
3* Copyright (c) 2011-2015, ARM Limited. All rights reserved.\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 "LinuxLoader.h"\r
16\r
17/**\r
18 Extract the next item from the command line.\r
19\r
20 The items are separated by spaces. Quotation marks (") are used for argument\r
21 grouping and the escaping character is "^" as for the EFI Shell command lines.\r
22\r
23 @param[in out] CommandLine Command line pointer.\r
24 @param[out] Item Pointer to the allocated buffer where the\r
25 item is stored.\r
26\r
27 @retval EFI_SUCCESS The token was found and extracted.\r
28 @retval EFI_NOT_FOUND No item found.\r
29 @retval EFI_OUT_OF_RESOURCES The memory allocation failed.\r
30\r
31**/\r
32STATIC\r
33EFI_STATUS\r
34ExtractNextItem (\r
35 IN OUT CONST CHAR16 **CommandLine,\r
36 OUT CHAR16 **Item\r
37 )\r
38{\r
39 CONST CHAR16 *Walker;\r
40 VOID *Buffer;\r
41 CHAR16 *WritePtr;\r
42 BOOLEAN InQuotedString;\r
43 BOOLEAN Interpret;\r
44\r
45 for (Walker = *CommandLine; *Walker == L' '; Walker++) {\r
46 ;\r
47 }\r
48\r
49 Buffer = AllocatePool (StrSize (Walker));\r
50 if (Buffer == NULL) {\r
51 return EFI_OUT_OF_RESOURCES;\r
52 }\r
53\r
54 for (WritePtr = Buffer, Interpret = TRUE, InQuotedString = FALSE;\r
55 ((*Walker != L' ') || InQuotedString) && (*Walker != L'\0');\r
56 Walker++\r
57 ) {\r
58 if (Interpret) {\r
59 if (*Walker == L'^') {\r
60 Interpret = FALSE;\r
61 continue;\r
62 }\r
63 if (*Walker == L'"') {\r
64 InQuotedString = !InQuotedString;\r
65 continue;\r
66 }\r
67 } else {\r
68 Interpret = TRUE;\r
69 }\r
70 *(WritePtr++) = *Walker;\r
71 }\r
72\r
73 if (WritePtr == Buffer) {\r
74 FreePool (Buffer);\r
75 return EFI_NOT_FOUND;\r
76 }\r
77\r
78 *WritePtr = L'\0';\r
79 *CommandLine = Walker;\r
80 *Item = Buffer;\r
81\r
82 return EFI_SUCCESS;\r
83}\r
84\r
85/**\r
86 Check if an item of the command line is a flag or not.\r
87\r
88 @param[in] Item Command line item.\r
89\r
90 @retval TRUE The item is a flag.\r
91 @retval FALSE The item is not a flag.\r
92\r
93**/\r
94STATIC\r
95BOOLEAN\r
96IsFlag (\r
97 IN CONST CHAR16 *Item\r
98 )\r
99{\r
100 return ((Item[0] == L'-') && (Item[2] == L'\0'));\r
101}\r
102\r
103/**\r
104 Process the application command line.\r
105\r
106 @param[out] KernelTextDevicePath A pointer to the buffer where the device\r
107 path to the Linux kernel is stored. The\r
108 address of the buffer is NULL in case of\r
109 an error. Otherwise, the returned address\r
110 is the address of a buffer allocated with\r
111 a call to AllocatePool() that has to be\r
112 freed by the caller.\r
113 @param[out] FdtTextDevicePath A pointer to the buffer where the device\r
114 path to the FDT is stored. The address of\r
115 the buffer is NULL in case of an error or\r
116 if the device path to the FDT is not\r
117 defined. Otherwise, the returned address\r
118 is the address of a buffer allocated with\r
119 a call to AllocatePool() that has to be\r
120 freed by the caller.\r
121 @param[out] InitrdTextDevicePath A pointer to the buffer where the device\r
122 path to the RAM root file system is stored.\r
123 The address of the buffer is NULL in case\r
124 of an error or if the device path to the\r
125 RAM root file system is not defined.\r
126 Otherwise, the returned address is the\r
127 address of a buffer allocated with a call\r
128 to AllocatePool() that has to be freed by\r
129 the caller.\r
130 @param[out] LinuxCommandLine A pointer to the buffer where the Linux\r
131 kernel command line is stored. The address\r
132 of the buffer is NULL in case of an error\r
133 or if the Linux command line is not\r
134 defined. Otherwise, the returned address\r
135 is the address of a buffer allocated with\r
136 a call to AllocatePool() that has to be\r
137 freed by the caller.\r
138\r
139 @param[out] AtagMachineType Value of the ARM Machine Type\r
140\r
141 @retval EFI_SUCCESS The processing was successfull.\r
142 @retval EFI_NOT_FOUND EFI_LOADED_IMAGE_PROTOCOL not found.\r
143 @retval EFI_NOT_FOUND Path to the Linux kernel not found.\r
144 @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a\r
145 conflict between two parameters.\r
146 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
147\r
148**/\r
149EFI_STATUS\r
150ProcessAppCommandLine (\r
151 OUT CHAR16 **KernelTextDevicePath,\r
152 OUT CHAR16 **FdtTextDevicePath,\r
153 OUT CHAR16 **InitrdTextDevicePath,\r
154 OUT CHAR16 **LinuxCommandLine,\r
155 OUT UINTN *AtagMachineType\r
156 )\r
157{\r
158 EFI_STATUS Status;\r
159 EFI_STATUS Status2;\r
160 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
161 CONST CHAR16 *Walker;\r
162 CHAR16 *Item;\r
163 CHAR16 Flag;\r
164 BOOLEAN HasAtagSupport;\r
165 BOOLEAN HasFdtSupport;\r
166\r
167 *KernelTextDevicePath = NULL;\r
168 *FdtTextDevicePath = NULL;\r
169 *InitrdTextDevicePath = NULL;\r
170 *LinuxCommandLine = NULL;\r
171 *AtagMachineType = ARM_FDT_MACHINE_TYPE;\r
172\r
173 HasAtagSupport = FALSE;\r
174 HasFdtSupport = FALSE;\r
175\r
176 Status = gBS->HandleProtocol (\r
177 gImageHandle,\r
178 &gEfiLoadedImageProtocolGuid,\r
179 (VOID**)&LoadedImage\r
180 );\r
181 if (EFI_ERROR (Status)) {\r
182 ASSERT_EFI_ERROR (Status);\r
183 return Status;\r
184 }\r
185\r
186 Walker = (CHAR16*)LoadedImage->LoadOptions;\r
187 if (Walker == NULL) {\r
188 PrintHelp (NULL);\r
189 return EFI_INVALID_PARAMETER;\r
190 }\r
191\r
192 //\r
193 // Get the device path to the Linux kernel.\r
194 //\r
195\r
196 Status = ExtractNextItem (&Walker, &Item);\r
197 if (!EFI_ERROR (Status)) {\r
198 if (!IsFlag (Item)) {\r
199 *KernelTextDevicePath = Item;\r
200 } else {\r
201 PrintHii (NULL, STRING_TOKEN (STR_MISSING_KERNEL_PATH));\r
202 FreePool (Item);\r
203 return EFI_NOT_FOUND;\r
204 }\r
205 } else {\r
206 if (Status != EFI_NOT_FOUND) {\r
207 return Status;\r
208 }\r
209 PrintHelp (NULL);\r
210 return EFI_INVALID_PARAMETER;\r
211 }\r
212\r
213 Status = EFI_INVALID_PARAMETER;\r
214 while (*Walker != L'\0') {\r
215 Status2 = ExtractNextItem (&Walker, &Item);\r
216 if (Status2 == EFI_NOT_FOUND) {\r
217 break;\r
218 }\r
219 if (EFI_ERROR (Status2)) {\r
220 Status = Status2;\r
221 goto Error;\r
222 }\r
223\r
224 if (!IsFlag (Item)) {\r
225 PrintHii (NULL, STRING_TOKEN (STR_INVALID_FLAG), Item[0], Item[1]);\r
226 FreePool (Item);\r
227 goto Error;\r
228 }\r
229 Flag = Item[1];\r
230 FreePool (Item);\r
231\r
232 Status2 = ExtractNextItem (&Walker, &Item);\r
233 if (Status2 == EFI_NOT_FOUND) {\r
234 PrintHii (NULL, STRING_TOKEN (STR_MISSING_VALUE), Flag);\r
235 goto Error;\r
236 }\r
237 if (EFI_ERROR (Status2)) {\r
238 Status = Status2;\r
239 goto Error;\r
240 }\r
241 if (IsFlag (Item)) {\r
242 PrintHii (NULL, STRING_TOKEN (STR_MISSING_VALUE), Flag);\r
243 FreePool (Item);\r
244 goto Error;\r
245 }\r
246\r
247 switch (Flag) {\r
248 case L'a':\r
249 if (HasFdtSupport) {\r
250 PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT));\r
251 goto Error;\r
252 }\r
253 *AtagMachineType = StrDecimalToUintn (Item);\r
254 HasAtagSupport = TRUE;\r
255 break;\r
256 case L'd':\r
257 *FdtTextDevicePath = Item;\r
258 if (HasAtagSupport) {\r
259 PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT));\r
260 goto Error;\r
261 }\r
262 HasFdtSupport = TRUE;\r
263 break;\r
264\r
265 case L'c':\r
266 *LinuxCommandLine = Item;\r
267 break;\r
268\r
269 case L'f':\r
270 *InitrdTextDevicePath = Item;\r
271 break;\r
272\r
273 default:\r
274 PrintHii (NULL, STRING_TOKEN (STR_INVALID_FLAG), L'-', Flag);\r
275 FreePool (Item);\r
276 goto Error;\r
277 }\r
278 }\r
279\r
280 Status = EFI_SUCCESS;\r
281\r
282Error:\r
283 if (EFI_ERROR (Status)) {\r
284 if (*KernelTextDevicePath != NULL) {\r
285 FreePool (*KernelTextDevicePath);\r
286 *KernelTextDevicePath = NULL;\r
287 }\r
288 if (*FdtTextDevicePath != NULL) {\r
289 FreePool (*FdtTextDevicePath);\r
290 *FdtTextDevicePath = NULL;\r
291 }\r
292 if (*InitrdTextDevicePath != NULL) {\r
293 FreePool (*InitrdTextDevicePath);\r
294 *InitrdTextDevicePath = NULL;\r
295 }\r
296 if (*LinuxCommandLine != NULL) {\r
297 FreePool (*LinuxCommandLine);\r
298 *LinuxCommandLine = NULL;\r
299 }\r
300 }\r
301\r
302 return Status;\r
303}\r