]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
OvmfPkg/X86QemuLoadImageLib: fix "unused variable" error in X64 DXE builds
[mirror_edk2.git] / OvmfPkg / Library / X86QemuLoadImageLib / X86QemuLoadImageLib.c
CommitLineData
7c47d890
AB
1/** @file\r
2 X86 specific implementation of QemuLoadImageLib library class interface\r
3 with support for loading mixed mode images and non-EFI stub images\r
4\r
5 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
6 Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>\r
7\r
8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9**/\r
10\r
11#include <Uefi.h>\r
12\r
13#include <Guid/QemuKernelLoaderFsMedia.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/LoadLinuxLib.h>\r
16#include <Library/MemoryAllocationLib.h>\r
17#include <Library/PrintLib.h>\r
18#include <Library/QemuFwCfgLib.h>\r
19#include <Library/QemuLoadImageLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Protocol/DevicePath.h>\r
22#include <Protocol/LoadedImage.h>\r
23#include <Protocol/OvmfLoadedX86LinuxKernel.h>\r
24\r
25#pragma pack (1)\r
26typedef struct {\r
27 EFI_DEVICE_PATH_PROTOCOL FilePathHeader;\r
28 CHAR16 FilePath[ARRAY_SIZE (L"kernel")];\r
29} KERNEL_FILE_DEVPATH;\r
30\r
31typedef struct {\r
32 VENDOR_DEVICE_PATH VenMediaNode;\r
33 KERNEL_FILE_DEVPATH FileNode;\r
34 EFI_DEVICE_PATH_PROTOCOL EndNode;\r
35} KERNEL_VENMEDIA_FILE_DEVPATH;\r
36#pragma pack ()\r
37\r
38STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {\r
39 {\r
40 {\r
41 MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
42 { sizeof (VENDOR_DEVICE_PATH) }\r
43 },\r
44 QEMU_KERNEL_LOADER_FS_MEDIA_GUID\r
45 }, {\r
46 {\r
47 MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP,\r
48 { sizeof (KERNEL_FILE_DEVPATH) }\r
49 },\r
50 L"kernel",\r
51 }, {\r
52 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
53 { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
54 }\r
55};\r
56\r
57STATIC\r
58VOID\r
59FreeLegacyImage (\r
60 IN OVMF_LOADED_X86_LINUX_KERNEL *LoadedImage\r
61 )\r
62{\r
63 if (LoadedImage->SetupBuf != NULL) {\r
64 FreePages (LoadedImage->SetupBuf,\r
65 EFI_SIZE_TO_PAGES (LoadedImage->SetupSize));\r
66 }\r
67 if (LoadedImage->KernelBuf != NULL) {\r
68 FreePages (LoadedImage->KernelBuf,\r
69 EFI_SIZE_TO_PAGES (LoadedImage->KernelInitialSize));\r
70 }\r
71 if (LoadedImage->CommandLine != NULL) {\r
72 FreePages (LoadedImage->CommandLine,\r
73 EFI_SIZE_TO_PAGES (LoadedImage->CommandLineSize));\r
74 }\r
75 if (LoadedImage->InitrdData != NULL) {\r
76 FreePages (LoadedImage->InitrdData,\r
77 EFI_SIZE_TO_PAGES (LoadedImage->InitrdSize));\r
78 }\r
79}\r
80\r
81STATIC\r
82EFI_STATUS\r
83QemuLoadLegacyImage (\r
84 OUT EFI_HANDLE *ImageHandle\r
85 )\r
86{\r
87 EFI_STATUS Status;\r
88 UINTN KernelSize;\r
89 UINTN SetupSize;\r
90 OVMF_LOADED_X86_LINUX_KERNEL *LoadedImage;\r
91\r
92 QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);\r
93 KernelSize = (UINTN)QemuFwCfgRead32 ();\r
94\r
95 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);\r
96 SetupSize = (UINTN)QemuFwCfgRead32 ();\r
97\r
98 if (KernelSize == 0 || SetupSize == 0) {\r
99 DEBUG ((DEBUG_INFO, "qemu -kernel was not used.\n"));\r
100 return EFI_NOT_FOUND;\r
101 }\r
102\r
103 LoadedImage = AllocateZeroPool (sizeof (*LoadedImage));\r
104 if (LoadedImage == NULL) {\r
105 return EFI_OUT_OF_RESOURCES;\r
106 }\r
107\r
108 LoadedImage->SetupSize = SetupSize;\r
109 LoadedImage->SetupBuf = LoadLinuxAllocateKernelSetupPages (\r
110 EFI_SIZE_TO_PAGES (LoadedImage->SetupSize));\r
111 if (LoadedImage->SetupBuf == NULL) {\r
112 DEBUG ((DEBUG_ERROR, "Unable to allocate memory for kernel setup!\n"));\r
113 Status = EFI_OUT_OF_RESOURCES;\r
114 goto FreeImageDesc;\r
115 }\r
116\r
117 DEBUG ((DEBUG_INFO, "Setup size: 0x%x\n", (UINT32)LoadedImage->SetupSize));\r
118 DEBUG ((DEBUG_INFO, "Reading kernel setup image ..."));\r
119 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);\r
120 QemuFwCfgReadBytes (LoadedImage->SetupSize, LoadedImage->SetupBuf);\r
121 DEBUG ((DEBUG_INFO, " [done]\n"));\r
122\r
123 Status = LoadLinuxCheckKernelSetup (LoadedImage->SetupBuf,\r
124 LoadedImage->SetupSize);\r
125 if (EFI_ERROR (Status)) {\r
126 goto FreeImage;\r
127 }\r
128\r
129 Status = LoadLinuxInitializeKernelSetup (LoadedImage->SetupBuf);\r
130 if (EFI_ERROR (Status)) {\r
131 goto FreeImage;\r
132 }\r
133\r
134 LoadedImage->KernelInitialSize = LoadLinuxGetKernelSize (\r
135 LoadedImage->SetupBuf, KernelSize);\r
136 if (LoadedImage->KernelInitialSize == 0) {\r
137 Status = EFI_UNSUPPORTED;\r
138 goto FreeImage;\r
139 }\r
140\r
141 LoadedImage->KernelBuf = LoadLinuxAllocateKernelPages (\r
142 LoadedImage->SetupBuf,\r
143 EFI_SIZE_TO_PAGES (LoadedImage->KernelInitialSize)\r
144 );\r
145 if (LoadedImage->KernelBuf == NULL) {\r
146 DEBUG ((DEBUG_ERROR, "Unable to allocate memory for kernel!\n"));\r
147 Status = EFI_OUT_OF_RESOURCES;\r
148 goto FreeImage;\r
149 }\r
150\r
151 DEBUG ((DEBUG_INFO, "Kernel size: 0x%x\n", (UINT32)KernelSize));\r
152 DEBUG ((DEBUG_INFO, "Reading kernel image ..."));\r
153 QemuFwCfgSelectItem (QemuFwCfgItemKernelData);\r
154 QemuFwCfgReadBytes (KernelSize, LoadedImage->KernelBuf);\r
155 DEBUG ((DEBUG_INFO, " [done]\n"));\r
156\r
157 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
158 LoadedImage->CommandLineSize = (UINTN)QemuFwCfgRead32 ();\r
159\r
160 if (LoadedImage->CommandLineSize > 0) {\r
161 LoadedImage->CommandLine = LoadLinuxAllocateCommandLinePages (\r
162 EFI_SIZE_TO_PAGES (\r
163 LoadedImage->CommandLineSize));\r
164 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
165 QemuFwCfgReadBytes (LoadedImage->CommandLineSize, LoadedImage->CommandLine);\r
166 }\r
167\r
168 Status = LoadLinuxSetCommandLine (LoadedImage->SetupBuf,\r
169 LoadedImage->CommandLine);\r
170 if (EFI_ERROR (Status)) {\r
171 goto FreeImage;\r
172 }\r
173\r
174 QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
175 LoadedImage->InitrdSize = (UINTN)QemuFwCfgRead32 ();\r
176\r
177 if (LoadedImage->InitrdSize > 0) {\r
178 LoadedImage->InitrdData = LoadLinuxAllocateInitrdPages (\r
179 LoadedImage->SetupBuf,\r
180 EFI_SIZE_TO_PAGES (LoadedImage->InitrdSize));\r
181 DEBUG ((DEBUG_INFO, "Initrd size: 0x%x\n",\r
182 (UINT32)LoadedImage->InitrdSize));\r
183 DEBUG ((DEBUG_INFO, "Reading initrd image ..."));\r
184 QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);\r
185 QemuFwCfgReadBytes (LoadedImage->InitrdSize, LoadedImage->InitrdData);\r
186 DEBUG ((DEBUG_INFO, " [done]\n"));\r
187 }\r
188\r
189 Status = LoadLinuxSetInitrd (LoadedImage->SetupBuf, LoadedImage->InitrdData,\r
190 LoadedImage->InitrdSize);\r
191 if (EFI_ERROR (Status)) {\r
192 goto FreeImage;\r
193 }\r
194\r
195 *ImageHandle = NULL;\r
196 Status = gBS->InstallProtocolInterface (ImageHandle,\r
197 &gOvmfLoadedX86LinuxKernelProtocolGuid, EFI_NATIVE_INTERFACE,\r
198 LoadedImage);\r
199 if (EFI_ERROR (Status)) {\r
200 goto FreeImage;\r
201 }\r
202 return EFI_SUCCESS;\r
203\r
204FreeImage:\r
205 FreeLegacyImage (LoadedImage);\r
206FreeImageDesc:\r
207 FreePool (LoadedImage);\r
208 return Status;\r
209}\r
210\r
211STATIC\r
212EFI_STATUS\r
213QemuStartLegacyImage (\r
214 IN EFI_HANDLE ImageHandle\r
215 )\r
216{\r
217 EFI_STATUS Status;\r
218 OVMF_LOADED_X86_LINUX_KERNEL *LoadedImage;\r
219\r
220 Status = gBS->OpenProtocol (\r
221 ImageHandle,\r
222 &gOvmfLoadedX86LinuxKernelProtocolGuid,\r
223 (VOID **)&LoadedImage,\r
224 gImageHandle, // AgentHandle\r
225 NULL, // ControllerHandle\r
226 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
227 );\r
228 if (EFI_ERROR (Status)) {\r
229 return EFI_INVALID_PARAMETER;\r
230 }\r
231\r
232 return LoadLinux (LoadedImage->KernelBuf, LoadedImage->SetupBuf);\r
233}\r
234\r
235STATIC\r
236EFI_STATUS\r
237QemuUnloadLegacyImage (\r
238 IN EFI_HANDLE ImageHandle\r
239 )\r
240{\r
241 EFI_STATUS Status;\r
242 OVMF_LOADED_X86_LINUX_KERNEL *LoadedImage;\r
243\r
244 Status = gBS->OpenProtocol (\r
245 ImageHandle,\r
246 &gOvmfLoadedX86LinuxKernelProtocolGuid,\r
247 (VOID **)&LoadedImage,\r
248 gImageHandle, // AgentHandle\r
249 NULL, // ControllerHandle\r
250 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
251 );\r
252 if (EFI_ERROR (Status)) {\r
253 return EFI_INVALID_PARAMETER;\r
254 }\r
255\r
256 Status = gBS->UninstallProtocolInterface (ImageHandle,\r
257 &gOvmfLoadedX86LinuxKernelProtocolGuid, LoadedImage);\r
258 ASSERT_EFI_ERROR (Status);\r
259\r
260 FreeLegacyImage (LoadedImage);\r
261 FreePool (LoadedImage);\r
262 return EFI_SUCCESS;\r
263}\r
264\r
265/**\r
266 Download the kernel, the initial ramdisk, and the kernel command line from\r
267 QEMU's fw_cfg. The kernel will be instructed via its command line to load\r
268 the initrd from the same Simple FileSystem where the kernel was loaded from.\r
269\r
270 @param[out] ImageHandle The image handle that was allocated for\r
271 loading the image\r
272\r
273 @retval EFI_SUCCESS The image was loaded successfully.\r
274 @retval EFI_NOT_FOUND Kernel image was not found.\r
275 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
276 @retval EFI_PROTOCOL_ERROR Unterminated kernel command line.\r
277\r
278 @return Error codes from any of the underlying\r
279 functions.\r
280**/\r
281EFI_STATUS\r
282EFIAPI\r
283QemuLoadKernelImage (\r
284 OUT EFI_HANDLE *ImageHandle\r
285 )\r
286{\r
287 EFI_STATUS Status;\r
288 EFI_HANDLE KernelImageHandle;\r
289 EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;\r
290 UINTN CommandLineSize;\r
291 CHAR8 *CommandLine;\r
292 UINTN InitrdSize;\r
293\r
294 //\r
295 // Load the image. This should call back into the QEMU EFI loader file system.\r
296 //\r
297 Status = gBS->LoadImage (\r
298 FALSE, // BootPolicy: exact match required\r
299 gImageHandle, // ParentImageHandle\r
300 (EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath,\r
301 NULL, // SourceBuffer\r
302 0, // SourceSize\r
303 &KernelImageHandle\r
304 );\r
305 switch (Status) {\r
306 case EFI_SUCCESS:\r
307 break;\r
308\r
309 case EFI_NOT_FOUND:\r
310 //\r
311 // The image does not exist - no -kernel image was supplied via the\r
312 // command line so no point in invoking the legacy fallback\r
313 //\r
314 return EFI_NOT_FOUND;\r
315\r
316 case EFI_SECURITY_VIOLATION:\r
317 //\r
318 // We are running with UEFI secure boot enabled, and the image failed to\r
319 // authenticate. For compatibility reasons, we fall back to the legacy\r
320 // loader in this case. Since the image has been loaded, we need to unload\r
321 // it before proceeding\r
322 //\r
323 gBS->UnloadImage (KernelImageHandle);\r
324 //\r
325 // Fall through\r
326 //\r
327 case EFI_UNSUPPORTED:\r
328 //\r
329 // The image is not natively supported or cross-type supported. Let's try\r
330 // loading it using the loader that parses the bzImage metadata directly.\r
331 //\r
332 Status = QemuLoadLegacyImage (&KernelImageHandle);\r
333 if (EFI_ERROR (Status)) {\r
334 DEBUG ((DEBUG_ERROR, "%a: QemuLoadLegacyImage(): %r\n", __FUNCTION__,\r
335 Status));\r
336 return Status;\r
337 }\r
338 *ImageHandle = KernelImageHandle;\r
339 return EFI_SUCCESS;\r
340\r
341 default:\r
342 DEBUG ((DEBUG_ERROR, "%a: LoadImage(): %r\n", __FUNCTION__, Status));\r
343 return Status;\r
344 }\r
345\r
346 //\r
347 // Construct the kernel command line.\r
348 //\r
349 Status = gBS->OpenProtocol (\r
350 KernelImageHandle,\r
351 &gEfiLoadedImageProtocolGuid,\r
352 (VOID **)&KernelLoadedImage,\r
353 gImageHandle, // AgentHandle\r
354 NULL, // ControllerHandle\r
355 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
356 );\r
357 ASSERT_EFI_ERROR (Status);\r
358\r
359 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
360 CommandLineSize = (UINTN)QemuFwCfgRead32 ();\r
361\r
362 if (CommandLineSize == 0) {\r
363 KernelLoadedImage->LoadOptionsSize = 0;\r
364 } else {\r
365 CommandLine = AllocatePool (CommandLineSize);\r
366 if (CommandLine == NULL) {\r
367 Status = EFI_OUT_OF_RESOURCES;\r
368 goto UnloadImage;\r
369 }\r
370\r
371 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
372 QemuFwCfgReadBytes (CommandLineSize, CommandLine);\r
373\r
374 //\r
375 // Verify NUL-termination of the command line.\r
376 //\r
377 if (CommandLine[CommandLineSize - 1] != '\0') {\r
378 DEBUG ((DEBUG_ERROR, "%a: kernel command line is not NUL-terminated\n",\r
379 __FUNCTION__));\r
380 Status = EFI_PROTOCOL_ERROR;\r
381 goto FreeCommandLine;\r
382 }\r
383\r
384 //\r
385 // Drop the terminating NUL, convert to UTF-16.\r
386 //\r
387 KernelLoadedImage->LoadOptionsSize = (CommandLineSize - 1) * 2;\r
388 }\r
389\r
390 QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
391 InitrdSize = (UINTN)QemuFwCfgRead32 ();\r
392\r
393 if (InitrdSize > 0) {\r
394 //\r
395 // Append ' initrd=initrd' in UTF-16.\r
396 //\r
397 KernelLoadedImage->LoadOptionsSize += sizeof (L" initrd=initrd") - 2;\r
398 }\r
399\r
400 if (KernelLoadedImage->LoadOptionsSize == 0) {\r
401 KernelLoadedImage->LoadOptions = NULL;\r
402 } else {\r
403 //\r
404 // NUL-terminate in UTF-16.\r
405 //\r
406 KernelLoadedImage->LoadOptionsSize += 2;\r
407\r
408 KernelLoadedImage->LoadOptions = AllocatePool (\r
409 KernelLoadedImage->LoadOptionsSize);\r
410 if (KernelLoadedImage->LoadOptions == NULL) {\r
411 KernelLoadedImage->LoadOptionsSize = 0;\r
412 Status = EFI_OUT_OF_RESOURCES;\r
413 goto FreeCommandLine;\r
414 }\r
415\r
416 UnicodeSPrintAsciiFormat (\r
417 KernelLoadedImage->LoadOptions,\r
418 KernelLoadedImage->LoadOptionsSize,\r
419 "%a%a",\r
420 (CommandLineSize == 0) ? "" : CommandLine,\r
421 (InitrdSize == 0) ? "" : " initrd=initrd"\r
422 );\r
423 DEBUG ((DEBUG_INFO, "%a: command line: \"%s\"\n", __FUNCTION__,\r
424 (CHAR16 *)KernelLoadedImage->LoadOptions));\r
425 }\r
426\r
427 *ImageHandle = KernelImageHandle;\r
428 return EFI_SUCCESS;\r
429\r
430FreeCommandLine:\r
431 if (CommandLineSize > 0) {\r
432 FreePool (CommandLine);\r
433 }\r
434UnloadImage:\r
435 gBS->UnloadImage (KernelImageHandle);\r
436\r
437 return Status;\r
438}\r
439\r
440/**\r
441 Transfer control to a kernel image loaded with QemuLoadKernelImage ()\r
442\r
443 @param[in,out] ImageHandle Handle of image to be started. May assume a\r
444 different value on return if the image was\r
445 reloaded.\r
446\r
447 @retval EFI_INVALID_PARAMETER ImageHandle is either an invalid image handle\r
448 or the image has already been initialized with\r
449 StartImage\r
450 @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the\r
451 image should not be started.\r
452\r
453 @return Error codes returned by the started image\r
454**/\r
455EFI_STATUS\r
456EFIAPI\r
457QemuStartKernelImage (\r
458 IN OUT EFI_HANDLE *ImageHandle\r
459 )\r
460{\r
461 EFI_STATUS Status;\r
462 OVMF_LOADED_X86_LINUX_KERNEL *LoadedImage;\r
7c47d890
AB
463\r
464 Status = gBS->OpenProtocol (\r
465 *ImageHandle,\r
466 &gOvmfLoadedX86LinuxKernelProtocolGuid,\r
467 (VOID **)&LoadedImage,\r
468 gImageHandle, // AgentHandle\r
469 NULL, // ControllerHandle\r
470 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
471 );\r
472 if (!EFI_ERROR (Status)) {\r
473 return QemuStartLegacyImage (*ImageHandle);\r
474 }\r
475\r
476 Status = gBS->StartImage (\r
477 *ImageHandle,\r
478 NULL, // ExitDataSize\r
479 NULL // ExitData\r
480 );\r
481#ifdef MDE_CPU_IA32\r
482 if (Status == EFI_UNSUPPORTED) {\r
a3e25cc8
LE
483 EFI_HANDLE KernelImageHandle;\r
484\r
7c47d890
AB
485 //\r
486 // On IA32, EFI_UNSUPPORTED means that the image's machine type is X64 while\r
487 // we are expecting a IA32 one, and the StartImage () boot service is unable\r
488 // to handle it, either because the image does not have the special .compat\r
489 // PE/COFF section that Linux specifies for mixed mode capable images, or\r
490 // because we are running without the support code for that. So load the\r
491 // image again, using the legacy loader, and unload the normally loaded\r
492 // image before starting the legacy one.\r
493 //\r
494 Status = QemuLoadLegacyImage (&KernelImageHandle);\r
495 if (EFI_ERROR (Status)) {\r
496 //\r
497 // Note: no change to (*ImageHandle), the caller will release it.\r
498 //\r
499 return Status;\r
500 }\r
501 //\r
502 // Swap in the legacy-loaded image.\r
503 //\r
504 QemuUnloadKernelImage (*ImageHandle);\r
505 *ImageHandle = KernelImageHandle;\r
506 return QemuStartLegacyImage (KernelImageHandle);\r
507 }\r
508#endif\r
509 return Status;\r
510}\r
511\r
512/**\r
513 Unloads an image loaded with QemuLoadKernelImage ().\r
514\r
515 @param ImageHandle Handle that identifies the image to be\r
516 unloaded.\r
517\r
518 @retval EFI_SUCCESS The image has been unloaded.\r
519 @retval EFI_UNSUPPORTED The image has been started, and does not\r
520 support unload.\r
521 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.\r
522\r
523 @return Exit code from the image's unload function.\r
524**/\r
525EFI_STATUS\r
526EFIAPI\r
527QemuUnloadKernelImage (\r
528 IN EFI_HANDLE ImageHandle\r
529 )\r
530{\r
531 EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;\r
532 EFI_STATUS Status;\r
533\r
534 Status = gBS->OpenProtocol (\r
535 ImageHandle,\r
536 &gEfiLoadedImageProtocolGuid,\r
537 (VOID **)&KernelLoadedImage,\r
538 gImageHandle, // AgentHandle\r
539 NULL, // ControllerHandle\r
540 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
541 );\r
542 if (Status == EFI_UNSUPPORTED) {\r
543 //\r
544 // The handle exists but does not have an instance of the standard loaded\r
545 // image protocol installed on it. Attempt to unload it as a legacy image\r
546 // instead.\r
547 //\r
548 return QemuUnloadLegacyImage (ImageHandle);\r
549 }\r
550\r
551 if (EFI_ERROR (Status)) {\r
552 return EFI_INVALID_PARAMETER;\r
553 }\r
554\r
555 //\r
556 // We are unloading a normal, non-legacy loaded image, either on behalf of\r
557 // an external caller, or called from QemuStartKernelImage() on IA32, while\r
558 // switching from the normal to the legacy method to load and start a X64\r
559 // image.\r
560 //\r
561 if (KernelLoadedImage->LoadOptions != NULL) {\r
562 FreePool (KernelLoadedImage->LoadOptions);\r
563 KernelLoadedImage->LoadOptions = NULL;\r
564 }\r
565 KernelLoadedImage->LoadOptionsSize = 0;\r
566\r
567 return gBS->UnloadImage (ImageHandle);\r
568}\r