3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
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 "LinuxLoader.h"
18 Extract the next item from the command line.
20 The items are separated by spaces. Quotation marks (") are used for argument
21 grouping and the escaping character is "^" as for the EFI Shell command lines.
23 @param[in out] CommandLine Command line pointer.
24 @param[out] Item Pointer to the allocated buffer where the
27 @retval EFI_SUCCESS The token was found and extracted.
28 @retval EFI_NOT_FOUND No item found.
29 @retval EFI_OUT_OF_RESOURCES The memory allocation failed.
35 IN OUT CONST CHAR16
**CommandLine
,
42 BOOLEAN InQuotedString
;
45 for (Walker
= *CommandLine
; *Walker
== L
' '; Walker
++) {
49 Buffer
= AllocatePool (StrSize (Walker
));
51 return EFI_OUT_OF_RESOURCES
;
54 for (WritePtr
= Buffer
, Interpret
= TRUE
, InQuotedString
= FALSE
;
55 ((*Walker
!= L
' ') || InQuotedString
) && (*Walker
!= L
'\0');
59 if (*Walker
== L
'^') {
63 if (*Walker
== L
'"') {
64 InQuotedString
= !InQuotedString
;
70 *(WritePtr
++) = *Walker
;
73 if (WritePtr
== Buffer
) {
79 *CommandLine
= Walker
;
86 Check if an item of the command line is a flag or not.
88 @param[in] Item Command line item.
90 @retval TRUE The item is a flag.
91 @retval FALSE The item is not a flag.
100 return ((Item
[0] == L
'-') && (Item
[2] == L
'\0'));
104 Process the application command line.
106 @param[out] KernelTextDevicePath A pointer to the buffer where the device
107 path to the Linux kernel is stored. The
108 address of the buffer is NULL in case of
109 an error. Otherwise, the returned address
110 is the address of a buffer allocated with
111 a call to AllocatePool() that has to be
113 @param[out] FdtTextDevicePath A pointer to the buffer where the device
114 path to the FDT is stored. The address of
115 the buffer is NULL in case of an error or
116 if the device path to the FDT is not
117 defined. Otherwise, the returned address
118 is the address of a buffer allocated with
119 a call to AllocatePool() that has to be
121 @param[out] InitrdTextDevicePath A pointer to the buffer where the device
122 path to the RAM root file system is stored.
123 The address of the buffer is NULL in case
124 of an error or if the device path to the
125 RAM root file system is not defined.
126 Otherwise, the returned address is the
127 address of a buffer allocated with a call
128 to AllocatePool() that has to be freed by
130 @param[out] LinuxCommandLine A pointer to the buffer where the Linux
131 kernel command line is stored. The address
132 of the buffer is NULL in case of an error
133 or if the Linux command line is not
134 defined. Otherwise, the returned address
135 is the address of a buffer allocated with
136 a call to AllocatePool() that has to be
139 @param[out] AtagMachineType Value of the ARM Machine Type
141 @retval EFI_SUCCESS The processing was successfull.
142 @retval EFI_NOT_FOUND EFI_LOADED_IMAGE_PROTOCOL not found.
143 @retval EFI_NOT_FOUND Path to the Linux kernel not found.
144 @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a
145 conflict between two parameters.
146 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
150 ProcessAppCommandLine (
151 OUT CHAR16
**KernelTextDevicePath
,
152 OUT CHAR16
**FdtTextDevicePath
,
153 OUT CHAR16
**InitrdTextDevicePath
,
154 OUT CHAR16
**LinuxCommandLine
,
155 OUT UINTN
*AtagMachineType
160 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
161 CONST CHAR16
*Walker
;
164 BOOLEAN HasAtagSupport
;
165 BOOLEAN HasFdtSupport
;
167 *KernelTextDevicePath
= NULL
;
168 *FdtTextDevicePath
= NULL
;
169 *InitrdTextDevicePath
= NULL
;
170 *LinuxCommandLine
= NULL
;
171 *AtagMachineType
= ARM_FDT_MACHINE_TYPE
;
173 HasAtagSupport
= FALSE
;
174 HasFdtSupport
= FALSE
;
176 Status
= gBS
->HandleProtocol (
178 &gEfiLoadedImageProtocolGuid
,
181 if (EFI_ERROR (Status
)) {
182 ASSERT_EFI_ERROR (Status
);
186 Walker
= (CHAR16
*)LoadedImage
->LoadOptions
;
187 if (Walker
== NULL
) {
189 return EFI_INVALID_PARAMETER
;
193 // Get the device path to the Linux kernel.
196 Status
= ExtractNextItem (&Walker
, &Item
);
197 if (!EFI_ERROR (Status
)) {
198 if (!IsFlag (Item
)) {
199 *KernelTextDevicePath
= Item
;
201 PrintHii (NULL
, STRING_TOKEN (STR_MISSING_KERNEL_PATH
));
203 return EFI_NOT_FOUND
;
206 if (Status
!= EFI_NOT_FOUND
) {
210 return EFI_INVALID_PARAMETER
;
213 Status
= EFI_INVALID_PARAMETER
;
214 while (*Walker
!= L
'\0') {
215 Status2
= ExtractNextItem (&Walker
, &Item
);
216 if (Status2
== EFI_NOT_FOUND
) {
219 if (EFI_ERROR (Status2
)) {
224 if (!IsFlag (Item
)) {
225 PrintHii (NULL
, STRING_TOKEN (STR_INVALID_FLAG
), Item
[0], Item
[1]);
232 Status2
= ExtractNextItem (&Walker
, &Item
);
233 if (Status2
== EFI_NOT_FOUND
) {
234 PrintHii (NULL
, STRING_TOKEN (STR_MISSING_VALUE
), Flag
);
237 if (EFI_ERROR (Status2
)) {
242 PrintHii (NULL
, STRING_TOKEN (STR_MISSING_VALUE
), Flag
);
250 PrintHii (NULL
, STRING_TOKEN (STR_ATAG_FDT_CONFLICT
));
253 *AtagMachineType
= StrDecimalToUintn (Item
);
254 HasAtagSupport
= TRUE
;
257 *FdtTextDevicePath
= Item
;
258 if (HasAtagSupport
) {
259 PrintHii (NULL
, STRING_TOKEN (STR_ATAG_FDT_CONFLICT
));
262 HasFdtSupport
= TRUE
;
266 *LinuxCommandLine
= Item
;
270 *InitrdTextDevicePath
= Item
;
274 PrintHii (NULL
, STRING_TOKEN (STR_INVALID_FLAG
), L
'-', Flag
);
280 Status
= EFI_SUCCESS
;
283 if (EFI_ERROR (Status
)) {
284 if (*KernelTextDevicePath
!= NULL
) {
285 FreePool (*KernelTextDevicePath
);
286 *KernelTextDevicePath
= NULL
;
288 if (*FdtTextDevicePath
!= NULL
) {
289 FreePool (*FdtTextDevicePath
);
290 *FdtTextDevicePath
= NULL
;
292 if (*InitrdTextDevicePath
!= NULL
) {
293 FreePool (*InitrdTextDevicePath
);
294 *InitrdTextDevicePath
= NULL
;
296 if (*LinuxCommandLine
!= NULL
) {
297 FreePool (*LinuxCommandLine
);
298 *LinuxCommandLine
= NULL
;