{\r
EFI_STATUS Status;\r
UINT32 LinuxImageSize;\r
+ UINT32 InitrdImageBaseSize = 0;\r
UINT32 InitrdImageSize = 0;\r
UINT32 AtagSize;\r
EFI_PHYSICAL_ADDRESS AtagBase;\r
EFI_PHYSICAL_ADDRESS LinuxImage;\r
- EFI_PHYSICAL_ADDRESS InitrdImage;\r
+ EFI_PHYSICAL_ADDRESS InitrdImageBase = 0;\r
+ EFI_PHYSICAL_ADDRESS InitrdImage = 0;\r
\r
PERF_START (NULL, "BDS", NULL, 0);\r
\r
\r
if (InitrdDevicePath) {\r
// Load the initrd near to the Linux kernel\r
- InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
- Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
+ InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);\r
if (Status == EFI_OUT_OF_RESOURCES) {\r
- Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);\r
}\r
if (EFI_ERROR(Status)) {\r
Print (L"ERROR: Did not find initrd image.\n");\r
- return Status;\r
+ goto EXIT_FREE_LINUX;\r
}\r
\r
// Check if the initrd is a uInitrd\r
- if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
+ if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {\r
// Skip the 64-byte image header\r
- InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
- InitrdImageSize -= 64;\r
+ InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);\r
+ InitrdImageSize = InitrdImageBaseSize - 64;\r
+ } else {\r
+ InitrdImage = InitrdImageBase;\r
+ InitrdImageSize = InitrdImageBaseSize;\r
}\r
}\r
\r
Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);\r
if (EFI_ERROR(Status)) {\r
Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);\r
- return Status;\r
+ goto EXIT_FREE_INITRD;\r
}\r
\r
return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));\r
+\r
+EXIT_FREE_INITRD:\r
+ if (InitrdDevicePath) {\r
+ gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));\r
+ }\r
+\r
+EXIT_FREE_LINUX:\r
+ gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));\r
+\r
+ return Status;\r
}\r
\r
/**\r
{\r
EFI_STATUS Status;\r
UINT32 LinuxImageSize;\r
+ UINT32 InitrdImageBaseSize = 0;\r
UINT32 InitrdImageSize = 0;\r
UINT32 FdtBlobSize;\r
EFI_PHYSICAL_ADDRESS FdtBlobBase;\r
EFI_PHYSICAL_ADDRESS LinuxImage;\r
- EFI_PHYSICAL_ADDRESS InitrdImage;\r
+ EFI_PHYSICAL_ADDRESS InitrdImageBase = 0;\r
+ EFI_PHYSICAL_ADDRESS InitrdImage = 0;\r
\r
PERF_START (NULL, "BDS", NULL, 0);\r
\r
}\r
\r
if (InitrdDevicePath) {\r
- InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
- Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
+ InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);\r
if (Status == EFI_OUT_OF_RESOURCES) {\r
- Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);\r
}\r
if (EFI_ERROR(Status)) {\r
Print (L"ERROR: Did not find initrd image.\n");\r
- return Status;\r
+ goto EXIT_FREE_LINUX;\r
}\r
\r
// Check if the initrd is a uInitrd\r
if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
// Skip the 64-byte image header\r
- InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
- InitrdImageSize -= 64;\r
+ InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);\r
+ InitrdImageSize = InitrdImageBaseSize - 64;\r
+ } else {\r
+ InitrdImage = InitrdImageBase;\r
+ InitrdImageSize = InitrdImageBaseSize;\r
}\r
}\r
\r
Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);\r
if (EFI_ERROR(Status)) {\r
Print (L"ERROR: Did not find Device Tree blob.\n");\r
- return Status;\r
+ goto EXIT_FREE_INITRD;\r
}\r
\r
// Update the Fdt with the Initrd information. The FDT will increase in size.\r
Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);\r
if (EFI_ERROR(Status)) {\r
Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);\r
- return Status;\r
+ goto EXIT_FREE_FDT;\r
}\r
\r
return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);\r
+\r
+EXIT_FREE_FDT:\r
+ gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));\r
+\r
+EXIT_FREE_INITRD:\r
+ if (InitrdDevicePath) {\r
+ gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));\r
+ }\r
+\r
+EXIT_FREE_LINUX:\r
+ gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));\r
+\r
+ return Status;\r
}\r
\r