VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c@ 105681

Last change on this file since 105681 was 105670, checked in by vboxsync, 9 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • Property svn:eol-style set to native
File size: 18.1 KB
Line 
1/** @file
2
3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include <libfdt.h>
11#include <Library/AndroidBootImgLib.h>
12#include <Library/PrintLib.h>
13#include <Library/DevicePathLib.h>
14#include <Library/UefiBootServicesTableLib.h>
15#include <Library/UefiLib.h>
16
17#include <Protocol/AndroidBootImg.h>
18#include <Protocol/LoadFile2.h>
19#include <Protocol/LoadedImage.h>
20
21#include <Guid/LinuxEfiInitrdMedia.h>
22
23#define FDT_ADDITIONAL_ENTRIES_SIZE 0x400
24
25typedef struct {
26 MEMMAP_DEVICE_PATH Node1;
27 EFI_DEVICE_PATH_PROTOCOL End;
28} MEMORY_DEVICE_PATH;
29
30typedef struct {
31 VENDOR_DEVICE_PATH VendorMediaNode;
32 EFI_DEVICE_PATH_PROTOCOL EndNode;
33} RAMDISK_DEVICE_PATH;
34
35STATIC ANDROID_BOOTIMG_PROTOCOL *mAndroidBootImg;
36STATIC VOID *mRamdiskData = NULL;
37STATIC UINTN mRamdiskSize = 0;
38STATIC EFI_HANDLE mRamDiskLoadFileHandle = NULL;
39
40STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
41{
42 {
43 {
44 HARDWARE_DEVICE_PATH,
45 HW_MEMMAP_DP,
46 {
47 (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
48 (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),
49 },
50 }, // Header
51 0, // StartingAddress (set at runtime)
52 0 // EndingAddress (set at runtime)
53 }, // Node1
54 {
55 END_DEVICE_PATH_TYPE,
56 END_ENTIRE_DEVICE_PATH_SUBTYPE,
57 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
58 } // End
59};
60
61STATIC CONST RAMDISK_DEVICE_PATH mRamdiskDevicePath =
62{
63 {
64 {
65 MEDIA_DEVICE_PATH,
66 MEDIA_VENDOR_DP,
67 { sizeof (VENDOR_DEVICE_PATH), 0 }
68 },
69 LINUX_EFI_INITRD_MEDIA_GUID
70 },
71 {
72 END_DEVICE_PATH_TYPE,
73 END_ENTIRE_DEVICE_PATH_SUBTYPE,
74 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
75 }
76};
77
78/**
79 Causes the driver to load a specified file.
80
81 @param This Protocol instance pointer.
82 @param FilePath The device specific path of the file to load.
83 @param BootPolicy Should always be FALSE.
84 @param BufferSize On input the size of Buffer in bytes. On output with a return
85 code of EFI_SUCCESS, the amount of data transferred to
86 Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
87 the size of Buffer required to retrieve the requested file.
88 @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL,
89 then no the size of the requested file is returned in
90 BufferSize.
91
92 @retval EFI_SUCCESS The file was loaded.
93 @retval EFI_UNSUPPORTED BootPolicy is TRUE.
94 @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
95 BufferSize is NULL.
96 @retval EFI_NO_MEDIA No medium was present to load the file.
97 @retval EFI_DEVICE_ERROR The file was not loaded due to a device error.
98 @retval EFI_NO_RESPONSE The remote system did not respond.
99 @retval EFI_NOT_FOUND The file was not found
100 @retval EFI_ABORTED The file load process was manually canceled.
101 @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current
102 directory entry. BufferSize has been updated with
103 the size needed to complete the request.
104
105
106**/
107EFI_STATUS
108EFIAPI
109AndroidBootImgLoadFile2 (
110 IN EFI_LOAD_FILE2_PROTOCOL *This,
111 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
112 IN BOOLEAN BootPolicy,
113 IN OUT UINTN *BufferSize,
114 IN VOID *Buffer OPTIONAL
115 )
116
117{
118 // Verify if the valid parameters
119 if ((This == NULL) ||
120 (BufferSize == NULL) ||
121 (FilePath == NULL) ||
122 !IsDevicePathValid (FilePath, 0))
123 {
124 return EFI_INVALID_PARAMETER;
125 }
126
127 if (BootPolicy) {
128 return EFI_UNSUPPORTED;
129 }
130
131 // Check if the given buffer size is big enough
132 // EFI_BUFFER_TOO_SMALL to allow caller to allocate a bigger buffer
133 if (mRamdiskSize == 0) {
134 return EFI_NOT_FOUND;
135 }
136
137 if ((Buffer == NULL) || (*BufferSize < mRamdiskSize)) {
138 *BufferSize = mRamdiskSize;
139 return EFI_BUFFER_TOO_SMALL;
140 }
141
142 // Copy InitRd
143 CopyMem (Buffer, mRamdiskData, mRamdiskSize);
144 *BufferSize = mRamdiskSize;
145
146 return EFI_SUCCESS;
147}
148
149///
150/// Load File Protocol instance
151///
152STATIC EFI_LOAD_FILE2_PROTOCOL mAndroidBootImgLoadFile2 = {
153 AndroidBootImgLoadFile2
154};
155
156EFI_STATUS
157AndroidBootImgGetImgSize (
158 IN VOID *BootImg,
159 OUT UINTN *ImgSize
160 )
161{
162 ANDROID_BOOTIMG_HEADER *Header;
163
164 Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
165
166 if (AsciiStrnCmp (
167 (CONST CHAR8 *)Header->BootMagic,
168 ANDROID_BOOT_MAGIC,
169 ANDROID_BOOT_MAGIC_LENGTH
170 ) != 0)
171 {
172 return EFI_INVALID_PARAMETER;
173 }
174
175 /* The page size is not specified, but it should be power of 2 at least */
176 ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
177
178 /* Get real size of abootimg */
179 *ImgSize = ALIGN_VALUE (Header->KernelSize, Header->PageSize) +
180 ALIGN_VALUE (Header->RamdiskSize, Header->PageSize) +
181 ALIGN_VALUE (Header->SecondStageBootloaderSize, Header->PageSize) +
182 Header->PageSize;
183 return EFI_SUCCESS;
184}
185
186EFI_STATUS
187AndroidBootImgGetKernelInfo (
188 IN VOID *BootImg,
189 OUT VOID **Kernel,
190 OUT UINTN *KernelSize
191 )
192{
193 ANDROID_BOOTIMG_HEADER *Header;
194
195 Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
196
197 if (AsciiStrnCmp (
198 (CONST CHAR8 *)Header->BootMagic,
199 ANDROID_BOOT_MAGIC,
200 ANDROID_BOOT_MAGIC_LENGTH
201 ) != 0)
202 {
203 return EFI_INVALID_PARAMETER;
204 }
205
206 if (Header->KernelSize == 0) {
207 return EFI_NOT_FOUND;
208 }
209
210 ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
211
212 *KernelSize = Header->KernelSize;
213 *Kernel = (VOID *)((UINTN)BootImg + Header->PageSize);
214 return EFI_SUCCESS;
215}
216
217EFI_STATUS
218AndroidBootImgGetRamdiskInfo (
219 IN VOID *BootImg,
220 OUT VOID **Ramdisk,
221 OUT UINTN *RamdiskSize
222 )
223{
224 ANDROID_BOOTIMG_HEADER *Header;
225
226 Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
227
228 if (AsciiStrnCmp (
229 (CONST CHAR8 *)Header->BootMagic,
230 ANDROID_BOOT_MAGIC,
231 ANDROID_BOOT_MAGIC_LENGTH
232 ) != 0)
233 {
234 return EFI_INVALID_PARAMETER;
235 }
236
237 ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
238
239 *RamdiskSize = Header->RamdiskSize;
240
241 if (Header->RamdiskSize != 0) {
242 *Ramdisk = (VOID *)((INTN)BootImg
243 + Header->PageSize
244 + ALIGN_VALUE (Header->KernelSize, Header->PageSize));
245 }
246
247 return EFI_SUCCESS;
248}
249
250EFI_STATUS
251AndroidBootImgGetSecondBootLoaderInfo (
252 IN VOID *BootImg,
253 OUT VOID **Second,
254 OUT UINTN *SecondSize
255 )
256{
257 ANDROID_BOOTIMG_HEADER *Header;
258
259 Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
260
261 if (AsciiStrnCmp (
262 (CONST CHAR8 *)Header->BootMagic,
263 ANDROID_BOOT_MAGIC,
264 ANDROID_BOOT_MAGIC_LENGTH
265 ) != 0)
266 {
267 return EFI_INVALID_PARAMETER;
268 }
269
270 ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));
271
272 *SecondSize = Header->SecondStageBootloaderSize;
273
274 if (Header->SecondStageBootloaderSize != 0) {
275 *Second = (VOID *)((UINTN)BootImg
276 + Header->PageSize
277 + ALIGN_VALUE (Header->KernelSize, Header->PageSize)
278 + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize));
279 }
280
281 return EFI_SUCCESS;
282}
283
284EFI_STATUS
285AndroidBootImgGetKernelArgs (
286 IN VOID *BootImg,
287 OUT CHAR8 *KernelArgs
288 )
289{
290 ANDROID_BOOTIMG_HEADER *Header;
291
292 Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
293 AsciiStrnCpyS (
294 KernelArgs,
295 ANDROID_BOOTIMG_KERNEL_ARGS_SIZE,
296 Header->KernelArgs,
297 ANDROID_BOOTIMG_KERNEL_ARGS_SIZE
298 );
299
300 return EFI_SUCCESS;
301}
302
303EFI_STATUS
304AndroidBootImgGetFdt (
305 IN VOID *BootImg,
306 IN VOID **FdtBase
307 )
308{
309 UINTN SecondLoaderSize;
310 EFI_STATUS Status;
311
312 /* Check whether FDT is located in second boot region as some vendor do so,
313 * because second loader is never used as far as I know. */
314 Status = AndroidBootImgGetSecondBootLoaderInfo (
315 BootImg,
316 FdtBase,
317 &SecondLoaderSize
318 );
319 return Status;
320}
321
322EFI_STATUS
323AndroidBootImgUpdateArgs (
324 IN VOID *BootImg,
325 OUT VOID **KernelArgs
326 )
327{
328 CHAR8 ImageKernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE];
329 EFI_STATUS Status;
330 UINT32 NewKernelArgSize;
331
332 // Get kernel arguments from Android boot image
333 Status = AndroidBootImgGetKernelArgs (BootImg, ImageKernelArgs);
334 if (EFI_ERROR (Status)) {
335 return Status;
336 }
337
338 NewKernelArgSize = ANDROID_BOOTIMG_KERNEL_ARGS_SIZE + PcdGet32 (PcdAndroidKernelCommandLineOverflow);
339 *KernelArgs = AllocateZeroPool (sizeof (CHAR16) * NewKernelArgSize);
340 if (*KernelArgs == NULL) {
341 DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n"));
342 return EFI_OUT_OF_RESOURCES;
343 }
344
345 AsciiStrToUnicodeStrS (
346 ImageKernelArgs,
347 *KernelArgs,
348 NewKernelArgSize
349 );
350 // Append platform kernel arguments
351 if (mAndroidBootImg->AppendArgs) {
352 Status = mAndroidBootImg->AppendArgs (
353 *KernelArgs,
354 NewKernelArgSize
355 );
356 }
357
358 return Status;
359}
360
361EFI_STATUS
362AndroidBootImgInstallLoadFile2 (
363 IN VOID *RamdiskData,
364 IN UINTN RamdiskSize
365 )
366{
367 mRamDiskLoadFileHandle = NULL;
368 mRamdiskData = RamdiskData;
369 mRamdiskSize = RamdiskSize;
370 return gBS->InstallMultipleProtocolInterfaces (
371 &mRamDiskLoadFileHandle,
372 &gEfiLoadFile2ProtocolGuid,
373 &mAndroidBootImgLoadFile2,
374 &gEfiDevicePathProtocolGuid,
375 &mRamdiskDevicePath,
376 NULL
377 );
378}
379
380EFI_STATUS
381AndroidBootImgUninstallLoadFile2 (
382 VOID
383 )
384{
385 EFI_STATUS Status;
386
387 Status = EFI_SUCCESS;
388 mRamdiskData = NULL;
389 mRamdiskSize = 0;
390 if (mRamDiskLoadFileHandle != NULL) {
391 Status = gBS->UninstallMultipleProtocolInterfaces (
392 mRamDiskLoadFileHandle,
393 &gEfiLoadFile2ProtocolGuid,
394 &mAndroidBootImgLoadFile2,
395 &gEfiDevicePathProtocolGuid,
396 &mRamdiskDevicePath,
397 NULL
398 );
399 mRamDiskLoadFileHandle = NULL;
400 }
401
402 return Status;
403}
404
405BOOLEAN
406AndroidBootImgAcpiSupported (
407 VOID
408 )
409{
410 EFI_STATUS Status;
411 VOID *AcpiTable;
412
413 Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, &AcpiTable);
414 return !EFI_ERROR (Status);
415}
416
417EFI_STATUS
418AndroidBootImgLocateFdt (
419 IN VOID *BootImg,
420 IN VOID **FdtBase
421 )
422{
423 INTN Err;
424 EFI_STATUS Status;
425
426 Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, FdtBase);
427 if (!EFI_ERROR (Status)) {
428 return EFI_SUCCESS;
429 }
430
431 Status = AndroidBootImgGetFdt (BootImg, FdtBase);
432 if (EFI_ERROR (Status)) {
433 return Status;
434 }
435
436 Err = fdt_check_header (*FdtBase);
437 if (Err != 0) {
438 DEBUG ((
439 DEBUG_ERROR,
440 "ERROR: Device Tree header not valid (Err:%d)\n",
441 Err
442 ));
443 return EFI_INVALID_PARAMETER;
444 }
445
446 return EFI_SUCCESS;
447}
448
449INTN
450AndroidBootImgGetChosenNode (
451 IN INTN UpdatedFdtBase
452 )
453{
454 INTN ChosenNode;
455
456 ChosenNode = fdt_subnode_offset ((CONST VOID *)UpdatedFdtBase, 0, "chosen");
457 if (ChosenNode < 0) {
458 ChosenNode = fdt_add_subnode ((VOID *)UpdatedFdtBase, 0, "chosen");
459 if (ChosenNode < 0) {
460 DEBUG ((DEBUG_ERROR, "Fail to find fdt node chosen!\n"));
461 return 0;
462 }
463 }
464
465 return ChosenNode;
466}
467
468EFI_STATUS
469AndroidBootImgSetProperty64 (
470 IN INTN UpdatedFdtBase,
471 IN INTN ChosenNode,
472 IN CHAR8 *PropertyName,
473 IN UINT64 Val
474 )
475{
476 INTN Err;
477 struct fdt_property *Property;
478 int Len;
479
480 Property = fdt_get_property_w (
481 (VOID *)UpdatedFdtBase,
482 ChosenNode,
483 PropertyName,
484 &Len
485 );
486 if ((NULL == Property) && (Len == -FDT_ERR_NOTFOUND)) {
487 Val = cpu_to_fdt64 (Val);
488 Err = fdt_appendprop (
489 (VOID *)UpdatedFdtBase,
490 ChosenNode,
491 PropertyName,
492 &Val,
493 sizeof (UINT64)
494 );
495 if (Err) {
496 DEBUG ((DEBUG_ERROR, "fdt_appendprop() fail: %a\n", fdt_strerror (Err)));
497 return EFI_INVALID_PARAMETER;
498 }
499 } else if (Property != NULL) {
500 Err = fdt_setprop_u64 (
501 (VOID *)UpdatedFdtBase,
502 ChosenNode,
503 PropertyName,
504 Val
505 );
506 if (Err) {
507 DEBUG ((DEBUG_ERROR, "fdt_setprop_u64() fail: %a\n", fdt_strerror (Err)));
508 return EFI_INVALID_PARAMETER;
509 }
510 } else {
511 DEBUG ((DEBUG_ERROR, "Failed to set fdt Property %a\n", PropertyName));
512 return EFI_INVALID_PARAMETER;
513 }
514
515 return EFI_SUCCESS;
516}
517
518EFI_STATUS
519AndroidBootImgUpdateFdt (
520 IN VOID *BootImg,
521 IN VOID *FdtBase,
522 IN VOID *RamdiskData,
523 IN UINTN RamdiskSize
524 )
525{
526 INTN ChosenNode, Err, NewFdtSize;
527 EFI_STATUS Status;
528 EFI_PHYSICAL_ADDRESS UpdatedFdtBase, NewFdtBase;
529
530 NewFdtSize = (UINTN)fdt_totalsize (FdtBase)
531 + FDT_ADDITIONAL_ENTRIES_SIZE;
532 Status = gBS->AllocatePages (
533 AllocateAnyPages,
534 EfiBootServicesData,
535 EFI_SIZE_TO_PAGES (NewFdtSize),
536 &UpdatedFdtBase
537 );
538 if (EFI_ERROR (Status)) {
539 DEBUG ((
540 DEBUG_WARN,
541 "Warning: Failed to reallocate FDT, err %d.\n",
542 Status
543 ));
544 return Status;
545 }
546
547 // Load the Original FDT tree into the new region
548 Err = fdt_open_into (FdtBase, (VOID *)(INTN)UpdatedFdtBase, NewFdtSize);
549 if (Err) {
550 DEBUG ((DEBUG_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Err)));
551 Status = EFI_INVALID_PARAMETER;
552 goto Fdt_Exit;
553 }
554
555 if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
556 Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
557 if (EFI_ERROR (Status)) {
558 goto Fdt_Exit;
559 }
560 } else {
561 ChosenNode = AndroidBootImgGetChosenNode (UpdatedFdtBase);
562 if (!ChosenNode) {
563 goto Fdt_Exit;
564 }
565
566 Status = AndroidBootImgSetProperty64 (
567 UpdatedFdtBase,
568 ChosenNode,
569 "linux,initrd-start",
570 (UINTN)RamdiskData
571 );
572 if (EFI_ERROR (Status)) {
573 goto Fdt_Exit;
574 }
575
576 Status = AndroidBootImgSetProperty64 (
577 UpdatedFdtBase,
578 ChosenNode,
579 "linux,initrd-end",
580 (UINTN)RamdiskData + RamdiskSize
581 );
582 if (EFI_ERROR (Status)) {
583 goto Fdt_Exit;
584 }
585 }
586
587 if (mAndroidBootImg->UpdateDtb) {
588 Status = mAndroidBootImg->UpdateDtb (UpdatedFdtBase, &NewFdtBase);
589 if (EFI_ERROR (Status)) {
590 goto Fdt_Exit;
591 }
592 } else {
593 NewFdtBase = UpdatedFdtBase;
594 }
595
596 Status = gBS->InstallConfigurationTable (
597 &gFdtTableGuid,
598 (VOID *)(UINTN)NewFdtBase
599 );
600
601 if (!EFI_ERROR (Status)) {
602 return EFI_SUCCESS;
603 }
604
605Fdt_Exit:
606 gBS->FreePages (UpdatedFdtBase, EFI_SIZE_TO_PAGES (NewFdtSize));
607 return Status;
608}
609
610EFI_STATUS
611AndroidBootImgBoot (
612 IN VOID *Buffer,
613 IN UINTN BufferSize
614 )
615{
616 EFI_STATUS Status;
617 VOID *Kernel;
618 UINTN KernelSize;
619 MEMORY_DEVICE_PATH KernelDevicePath;
620 EFI_HANDLE ImageHandle;
621 VOID *NewKernelArg;
622 EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
623 VOID *RamdiskData;
624 UINTN RamdiskSize;
625 IN VOID *FdtBase;
626
627 if ((Buffer == NULL) || (BufferSize == 0)) {
628 return EFI_INVALID_PARAMETER;
629 }
630
631 NewKernelArg = NULL;
632 ImageHandle = NULL;
633
634 Status = gBS->LocateProtocol (
635 &gAndroidBootImgProtocolGuid,
636 NULL,
637 (VOID **)&mAndroidBootImg
638 );
639 if (EFI_ERROR (Status)) {
640 goto Exit;
641 }
642
643 Status = AndroidBootImgGetKernelInfo (
644 Buffer,
645 &Kernel,
646 &KernelSize
647 );
648 if (EFI_ERROR (Status)) {
649 goto Exit;
650 }
651
652 Status = AndroidBootImgUpdateArgs (Buffer, &NewKernelArg);
653 if (EFI_ERROR (Status)) {
654 goto Exit;
655 }
656
657 Status = AndroidBootImgGetRamdiskInfo (
658 Buffer,
659 &RamdiskData,
660 &RamdiskSize
661 );
662 if (EFI_ERROR (Status)) {
663 goto Exit;
664 }
665
666 if (AndroidBootImgAcpiSupported ()) {
667 Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
668 if (EFI_ERROR (Status)) {
669 goto Exit;
670 }
671 } else {
672 Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
673 if (EFI_ERROR (Status)) {
674 goto Exit;
675 }
676
677 Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
678 if (EFI_ERROR (Status)) {
679 goto Exit;
680 }
681 }
682
683 KernelDevicePath = mMemoryDevicePathTemplate;
684
685 KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel;
686 KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel
687 + KernelSize;
688
689 Status = gBS->LoadImage (
690 TRUE,
691 gImageHandle,
692 (EFI_DEVICE_PATH *)&KernelDevicePath,
693 (VOID *)(UINTN)Kernel,
694 KernelSize,
695 &ImageHandle
696 );
697 if (EFI_ERROR (Status)) {
698 goto Exit;
699 }
700
701 // Set kernel arguments
702 Status = gBS->HandleProtocol (
703 ImageHandle,
704 &gEfiLoadedImageProtocolGuid,
705 (VOID **)&ImageInfo
706 );
707 if (EFI_ERROR (Status)) {
708 goto Exit;
709 }
710
711 ImageInfo->LoadOptions = NewKernelArg;
712 ImageInfo->LoadOptionsSize = StrLen (NewKernelArg) * sizeof (CHAR16);
713
714 // Before calling the image, enable the Watchdog Timer for the 5 Minute period
715 gBS->SetWatchdogTimer (5 * 60, 0x10000, 0, NULL);
716 // Start the image
717 Status = gBS->StartImage (ImageHandle, NULL, NULL);
718 // Clear the Watchdog Timer if the image returns
719 gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);
720
721Exit:
722 // Unload image as it will not be used anymore
723 if (ImageHandle != NULL) {
724 gBS->UnloadImage (ImageHandle);
725 ImageHandle = NULL;
726 }
727
728 if (EFI_ERROR (Status)) {
729 if (NewKernelArg != NULL) {
730 FreePool (NewKernelArg);
731 NewKernelArg = NULL;
732 }
733 }
734
735 AndroidBootImgUninstallLoadFile2 ();
736 return Status;
737}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette