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