]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Bds/BootOption.c
ArmPlatformPkg/Bds: Add a signature in front of the Boot Argument propoer to this Bds
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOption.c
CommitLineData
ea46ebbe 1/** @file\r
2*\r
3* Copyright (c) 2011, 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 "BdsInternal.h"\r
16\r
17extern EFI_HANDLE mImageHandle;\r
18\r
19EFI_STATUS\r
20BootOptionStart (\r
21 IN BDS_LOAD_OPTION *BootOption\r
22 )\r
23{\r
c60ea9a8 24 EFI_STATUS Status;\r
25 EFI_DEVICE_PATH* FdtDevicePath;\r
26 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;\r
27 UINT32 LoaderType;\r
2ccfb71e 28 ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData;\r
29 ARM_BDS_LINUX_ARGUMENTS* LinuxArguments;\r
30 EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath;\r
31 EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath;\r
32 UINTN FdtDevicePathSize;\r
33 UINTN CmdLineSize;\r
34 UINTN InitrdSize;\r
35 EFI_DEVICE_PATH* Initrd;\r
36\r
37 Status = EFI_UNSUPPORTED;\r
38 OptionalData = BootOption->OptionalData;\r
39 LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
40\r
41 if (LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
42 // Need to connect every drivers to ensure no dependencies are missing for the application\r
43 BdsConnectAllDrivers();\r
44\r
45 Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);\r
46 } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
47 LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
48 CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
49 InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
50\r
51 if (InitrdSize > 0) {\r
52 Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
53 } else {\r
54 Initrd = NULL;\r
55 }\r
ea46ebbe 56\r
2ccfb71e 57 Status = BdsBootLinux (BootOption->FilePathList,\r
58 Initrd, // Initrd\r
59 (CHAR8*)(LinuxArguments + 1), // CmdLine\r
60 NULL);\r
61 } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
62 LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
63 CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
64 InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
65\r
66 if (InitrdSize > 0) {\r
67 Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
68 } else {\r
69 Initrd = NULL;\r
70 }\r
71\r
72 // Get the default FDT device path\r
73 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
74 ASSERT_EFI_ERROR(Status);\r
75 DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\r
76\r
77 // Get the FDT device path\r
78 FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);\r
79 Status = GetEnvironmentVariable ((CHAR16 *)L"FDT", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
80 ASSERT_EFI_ERROR(Status);\r
81\r
82 Status = BdsBootLinux (BootOption->FilePathList,\r
83 Initrd, // Initrd\r
84 (CHAR8*)(LinuxArguments + 1),\r
85 FdtDevicePath);\r
ea46ebbe 86\r
87 return Status;\r
88}\r
89\r
90EFI_STATUS\r
91BootOptionParseLoadOption (\r
92 IN EFI_LOAD_OPTION EfiLoadOption,\r
93 IN UINTN EfiLoadOptionSize,\r
94 OUT BDS_LOAD_OPTION **BdsLoadOption\r
95 )\r
96{\r
97 BDS_LOAD_OPTION *LoadOption;\r
98 UINTN FilePathListLength;\r
99 UINTN DescriptionLength;\r
100\r
101 if (EfiLoadOption == NULL) {\r
102 return EFI_INVALID_PARAMETER;\r
103 }\r
104\r
105 if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) {\r
106 return EFI_BAD_BUFFER_SIZE;\r
107 }\r
108\r
109 LoadOption = (BDS_LOAD_OPTION*)AllocatePool(sizeof(BDS_LOAD_OPTION));\r
110 if (LoadOption == NULL) {\r
111 return EFI_OUT_OF_RESOURCES;\r
112 }\r
113\r
114 LoadOption->LoadOption = EfiLoadOption;\r
115 LoadOption->LoadOptionSize = EfiLoadOptionSize;\r
116\r
117 LoadOption->Attributes = *(UINT32*)EfiLoadOption;\r
118 FilePathListLength = *(UINT16*)(EfiLoadOption + sizeof(UINT32));\r
119 LoadOption->Description = (CHAR16*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16));\r
120 DescriptionLength = StrSize (LoadOption->Description);\r
121 LoadOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength);\r
122\r
123 if ((UINTN)((UINT8*)LoadOption->FilePathList + FilePathListLength - EfiLoadOption) == EfiLoadOptionSize) {\r
124 LoadOption->OptionalData = NULL;\r
125 } else {\r
126 LoadOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)((UINT8*)LoadOption->FilePathList + FilePathListLength);\r
127 }\r
128\r
129 *BdsLoadOption = LoadOption;\r
130 return EFI_SUCCESS;\r
131}\r
132\r
133EFI_STATUS\r
134BootOptionFromLoadOptionVariable (\r
135 IN UINT16 LoadOptionIndex,\r
136 OUT BDS_LOAD_OPTION **BdsLoadOption\r
137 )\r
138{\r
139 EFI_STATUS Status;\r
140 CHAR16 BootVariableName[9];\r
141 EFI_LOAD_OPTION EfiLoadOption;\r
142 UINTN EfiLoadOptionSize;\r
143\r
144 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex);\r
145\r
146 Status = GetEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);\r
147 if (!EFI_ERROR(Status)) {\r
148 Status = BootOptionParseLoadOption (EfiLoadOption,EfiLoadOptionSize,BdsLoadOption);\r
149 if (!EFI_ERROR(Status)) {\r
150 (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex;\r
151 }\r
152 }\r
153\r
154 return Status;\r
155}\r
156\r
157EFI_STATUS\r
158BootOptionList (\r
159 IN OUT LIST_ENTRY *BootOptionList\r
160 )\r
161{\r
162 EFI_STATUS Status;\r
163 UINTN Index;\r
164 UINT16 *BootOrder;\r
165 UINTN BootOrderSize;\r
166 BDS_LOAD_OPTION *BdsLoadOption;\r
167\r
168 InitializeListHead (BootOptionList);\r
169\r
170 // Get the Boot Option Order from the environment variable\r
171 Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
172 if (EFI_ERROR(Status)) {\r
173 return Status;\r
174 }\r
175\r
176 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
177 Status = BootOptionFromLoadOptionVariable (BootOrder[Index],&BdsLoadOption);\r
178 if (!EFI_ERROR(Status)) {\r
179 InsertTailList (BootOptionList,&BdsLoadOption->Link);\r
180 }\r
181 }\r
182\r
183 return EFI_SUCCESS;\r
184}\r
185\r
186UINT16\r
187BootOptionAllocateBootIndex (\r
188 VOID\r
189 )\r
190{\r
191 EFI_STATUS Status;\r
192 UINTN Index;\r
193 UINT32 BootIndex;\r
194 UINT16 *BootOrder;\r
195 UINTN BootOrderSize;\r
196 BOOLEAN Found;\r
197\r
198 // Get the Boot Option Order from the environment variable\r
199 Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
200 if (!EFI_ERROR(Status)) {\r
201 for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) {\r
202 Found = FALSE;\r
203 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
204 if (BootOrder[Index] == BootIndex) {\r
205 Found = TRUE;\r
206 break;\r
207 }\r
208 }\r
209 if (!Found) {\r
210 return BootIndex;\r
211 }\r
212 }\r
213 }\r
214 // Return the first index\r
215 return 0;\r
216}\r
217\r
218STATIC\r
219EFI_STATUS\r
220BootOptionSetFields (\r
c60ea9a8 221 IN BDS_LOAD_OPTION* BootOption,\r
222 IN UINT32 Attributes,\r
223 IN CHAR16* BootDescription,\r
224 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 225 IN ARM_BDS_LOADER_TYPE BootType,\r
226 IN ARM_BDS_LOADER_ARGUMENTS* BootArguments\r
ea46ebbe 227 )\r
228{\r
2ccfb71e 229 EFI_LOAD_OPTION EfiLoadOption;\r
230 UINTN EfiLoadOptionSize;\r
231 UINTN BootDescriptionSize;\r
232 UINTN BootOptionalDataSize;\r
233 UINT16 FilePathListLength;\r
234 UINT8* EfiLoadOptionPtr;\r
235 UINT8* InitrdPathListPtr;\r
236 UINTN OptionalDataSize;\r
237 ARM_BDS_LINUX_ARGUMENTS* DestLinuxArguments;\r
238 ARM_BDS_LINUX_ARGUMENTS* SrcLinuxArguments;\r
ea46ebbe 239\r
240 // If we are overwriting an existent Boot Option then we have to free previously allocated memory\r
241 if (BootOption->LoadOption) {\r
242 FreePool(BootOption->LoadOption);\r
243 }\r
244\r
2ccfb71e 245 BootDescriptionSize = StrSize (BootDescription);\r
246 BootOptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
247 if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
248 BootOptionalDataSize += sizeof(ARM_BDS_LINUX_ARGUMENTS) + BootArguments->LinuxArguments.CmdLineSize + BootArguments->LinuxArguments.InitrdSize;\r
249 }\r
ea46ebbe 250\r
251 // Compute the size of the FilePath list\r
2ccfb71e 252 FilePathListLength = GetUnalignedDevicePathSize (DevicePath);\r
656416bc 253\r
ea46ebbe 254 // Allocate the memory for the EFI Load Option\r
255 EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize;\r
256 EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);\r
257 EfiLoadOptionPtr = EfiLoadOption;\r
258\r
259 //\r
260 // Populate the EFI Load Option and BDS Boot Option structures\r
261 //\r
262\r
263 // Attributes fields\r
264 BootOption->Attributes = Attributes;\r
265 *(UINT32*)EfiLoadOptionPtr = Attributes;\r
266 EfiLoadOptionPtr += sizeof(UINT32);\r
267\r
268 // FilePath List fields\r
269 BootOption->FilePathListLength = FilePathListLength;\r
270 *(UINT16*)EfiLoadOptionPtr = FilePathListLength;\r
271 EfiLoadOptionPtr += sizeof(UINT16);\r
272\r
273 // Boot description fields\r
274 BootOption->Description = (CHAR16*)EfiLoadOptionPtr;\r
275 CopyMem (EfiLoadOptionPtr, BootDescription, BootDescriptionSize);\r
276 EfiLoadOptionPtr += BootDescriptionSize;\r
277\r
278 // File path fields\r
279 BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;\r
2ccfb71e 280 CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);\r
281 EfiLoadOptionPtr += FilePathListLength;\r
ea46ebbe 282\r
283 // Optional Data fields, Do unaligned writes\r
2ccfb71e 284 BootOption->OptionalData = EfiLoadOptionPtr;\r
285 WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);\r
286 WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);\r
ea46ebbe 287\r
2ccfb71e 288 OptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
ea46ebbe 289\r
2ccfb71e 290 if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
291 SrcLinuxArguments = &(BootArguments->LinuxArguments);\r
292 DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;\r
656416bc 293\r
2ccfb71e 294 WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize);\r
295 WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize);\r
296 OptionalDataSize += sizeof (ARM_BDS_LINUX_ARGUMENTS);\r
656416bc 297\r
2ccfb71e 298 if (SrcLinuxArguments->CmdLineSize > 0) {\r
299 CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize);\r
300 OptionalDataSize += SrcLinuxArguments->CmdLineSize;\r
301 }\r
656416bc 302\r
2ccfb71e 303 if (SrcLinuxArguments->InitrdSize > 0) {\r
304 InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize);\r
305 CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);\r
656416bc 306 }\r
307 }\r
2ccfb71e 308 BootOption->OptionalDataSize = OptionalDataSize;\r
309\r
6bab33c7 310 // If this function is called at the creation of the Boot Device entry (not at the update) the\r
311 // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry\r
312 if (BootOption->LoadOptionSize == 0) {\r
2ccfb71e 313 BootOption->LoadOptionIndex = BootOptionAllocateBootIndex ();\r
6bab33c7 314 }\r
315\r
ea46ebbe 316 // Fill the EFI Load option fields\r
ea46ebbe 317 BootOption->LoadOption = EfiLoadOption;\r
318 BootOption->LoadOptionSize = EfiLoadOptionSize;\r
319\r
320 return EFI_SUCCESS;\r
321}\r
322\r
323EFI_STATUS\r
324BootOptionCreate (\r
c60ea9a8 325 IN UINT32 Attributes,\r
326 IN CHAR16* BootDescription,\r
ea46ebbe 327 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 328 IN ARM_BDS_LOADER_TYPE BootType,\r
329 IN ARM_BDS_LOADER_ARGUMENTS* BootArguments,\r
c60ea9a8 330 OUT BDS_LOAD_OPTION **BdsLoadOption\r
ea46ebbe 331 )\r
332{\r
c60ea9a8 333 EFI_STATUS Status;\r
334 BDS_LOAD_OPTION *BootOption;\r
335 CHAR16 BootVariableName[9];\r
ea46ebbe 336 UINT16 *BootOrder;\r
337 UINTN BootOrderSize;\r
338\r
339 //\r
340 // Allocate and fill the memory for the BDS Load Option structure\r
341 //\r
342 BootOption = (BDS_LOAD_OPTION*)AllocateZeroPool(sizeof(BDS_LOAD_OPTION));\r
343\r
344 InitializeListHead (&BootOption->Link);\r
345 BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, BootArguments);\r
346\r
347 //\r
348 // Set the related environment variables\r
349 //\r
350\r
351 // Create Boot#### environment variable\r
352 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\r
353 Status = gRT->SetVariable (\r
354 BootVariableName,\r
355 &gEfiGlobalVariableGuid,\r
356 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
357 BootOption->LoadOptionSize,\r
358 BootOption->LoadOption\r
359 );\r
360\r
361 // Add the new Boot Index to the list\r
362 Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
363 if (!EFI_ERROR(Status)) {\r
364 BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder);\r
365 // Add the new index at the end\r
366 BootOrder[BootOrderSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;\r
367 BootOrderSize += sizeof(UINT16);\r
368 } else {\r
369 // BootOrder does not exist. Create it\r
370 BootOrderSize = sizeof(UINT16);\r
371 BootOrder = &(BootOption->LoadOptionIndex);\r
372 }\r
373\r
374 // Update (or Create) the BootOrder environment variable\r
375 Status = gRT->SetVariable (\r
376 L"BootOrder",\r
377 &gEfiGlobalVariableGuid,\r
378 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
379 BootOrderSize,\r
380 BootOrder\r
381 );\r
382\r
383 *BdsLoadOption = BootOption;\r
384 return Status;\r
385}\r
386\r
387EFI_STATUS\r
388BootOptionUpdate (\r
2ccfb71e 389 IN BDS_LOAD_OPTION* BdsLoadOption,\r
390 IN UINT32 Attributes,\r
391 IN CHAR16* BootDescription,\r
ea46ebbe 392 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 393 IN ARM_BDS_LOADER_TYPE BootType,\r
394 IN ARM_BDS_LOADER_ARGUMENTS* BootArguments\r
ea46ebbe 395 )\r
396{\r
397 EFI_STATUS Status;\r
ea46ebbe 398 CHAR16 BootVariableName[9];\r
399\r
400 // Update the BDS Load Option structure\r
401 BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, BootArguments);\r
402\r
403 // Update the related environment variables\r
6bab33c7 404 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);\r
405\r
ea46ebbe 406 Status = gRT->SetVariable (\r
407 BootVariableName,\r
408 &gEfiGlobalVariableGuid,\r
409 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
6bab33c7 410 BdsLoadOption->LoadOptionSize,\r
411 BdsLoadOption->LoadOption\r
ea46ebbe 412 );\r
413\r
414 return Status;\r
415}\r
416\r
417EFI_STATUS\r
418BootOptionDelete (\r
419 IN BDS_LOAD_OPTION *BootOption\r
420 )\r
421{\r
422 UINTN Index;\r
423 UINTN BootOrderSize;\r
424 UINT16* BootOrder;\r
425 UINTN BootOrderCount;\r
426 EFI_STATUS Status;\r
427\r
428 // If the Boot Optiono was attached to a list remove it\r
429 if (!IsListEmpty (&BootOption->Link)) {\r
430 // Remove the entry from the list\r
431 RemoveEntryList (&BootOption->Link);\r
432 }\r
433\r
434 // Remove the entry from the BootOrder environment variable\r
435 Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
436 if (!EFI_ERROR(Status)) {\r
437 BootOrderCount = BootOrderSize / sizeof(UINT16);\r
438\r
439 // Find the index of the removed entry\r
440 for (Index = 0; Index < BootOrderCount; Index++) {\r
441 if (BootOrder[Index] == BootOption->LoadOptionIndex) {\r
442 // If it the last entry we do not need to rearrange the BootOrder list\r
443 if (Index + 1 != BootOrderCount) {\r
444 CopyMem (&BootOrder[Index],&BootOrder[Index+1], BootOrderCount - (Index + 1));\r
445 }\r
446 break;\r
447 }\r
448 }\r
449\r
450 // Update the BootOrder environment variable\r
451 Status = gRT->SetVariable (\r
452 L"BootOrder",\r
453 &gEfiGlobalVariableGuid,\r
454 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
455 BootOrderSize - sizeof(UINT16),\r
456 BootOrder\r
457 );\r
458 }\r
459\r
460 return EFI_SUCCESS;\r
461}\r