-/** @file
-*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
-*
-* This program and the accompanying materials
-* are licensed and made available under the terms and conditions of the BSD License
-* which accompanies this distribution. The full text of the license may be found at
-* http://opensource.org/licenses/bsd-license.php
-*
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include "BdsInternal.h"
-#include "BdsLinuxLoader.h"
-
-#define ALIGN32_BELOW(addr) ALIGN_POINTER(addr - 32,32)
-
-STATIC
-EFI_STATUS
-PreparePlatformHardware (
- VOID
- )
-{
- //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
-
- // Clean, invalidate, disable data cache
- ArmDisableDataCache();
- ArmCleanInvalidateDataCache();
-
- // Invalidate and disable the Instruction cache
- ArmDisableInstructionCache ();
- ArmInvalidateInstructionCache ();
-
- // Turn off MMU
- ArmDisableMmu();
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-StartLinux (
- IN EFI_PHYSICAL_ADDRESS LinuxImage,
- IN UINTN LinuxImageSize,
- IN EFI_PHYSICAL_ADDRESS KernelParamsAddress,
- IN UINTN KernelParamsSize,
- IN UINT32 MachineType
- )
-{
- EFI_STATUS Status;
- LINUX_KERNEL LinuxKernel;
-
- // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
- // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
- Status = ShutdownUefiBootServices ();
- if(EFI_ERROR(Status)) {
- DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
- goto Exit;
- }
-
- // Move the kernel parameters to any address inside the first 1MB.
- // This is necessary because the ARM Linux kernel requires
- // the FTD / ATAG List to reside entirely inside the first 1MB of
- // physical memory.
- //Note: There is no requirement on the alignment
- if (MachineType != ARM_FDT_MACHINE_TYPE) {
- if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {
- KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
- }
- } else {
- if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {
- KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
- }
- }
-
- if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {
- //Note: There is no requirement on the alignment
- LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);
- } else {
- LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;
- }
-
- // Check if the Linux Image is a uImage
- if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {
- // Assume the Image Entry Point is just after the uImage header (64-byte size)
- LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);
- LinuxImageSize -= 64;
- }
-
- //TODO: Check there is no overlapping between kernel and Atag
-
- //
- // Switch off interrupts, caches, mmu, etc
- //
- Status = PreparePlatformHardware ();
- ASSERT_EFI_ERROR(Status);
-
- // Register and print out performance information
- PERF_END (NULL, "BDS", NULL, 0);
- if (PerformanceMeasurementEnabled ()) {
- PrintPerformance ();
- }
-
- //
- // Start the Linux Kernel
- //
-
- // Outside BootServices, so can't use Print();
- DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));
-
- // Jump to kernel with register set
- LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);
-
- // Kernel should never exit
- // After Life services are not provided
- ASSERT(FALSE);
-
-Exit:
- // Only be here if we fail to start Linux
- Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status);
-
- // Free Runtimee Memory (kernel and FDT)
- return Status;
-}
-
-/**
- Start a Linux kernel from a Device Path
-
- @param LinuxKernel Device Path to the Linux Kernel
- @param Parameters Linux kernel arguments
- @param Fdt Device Path to the Flat Device Tree
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsBootLinuxAtag (
- IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
- IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
- IN CONST CHAR8* CommandLineArguments
- )
-{
- EFI_STATUS Status;
- UINT32 LinuxImageSize;
- UINT32 InitrdImageSize = 0;
- UINT32 AtagSize;
- EFI_PHYSICAL_ADDRESS AtagBase;
- EFI_PHYSICAL_ADDRESS LinuxImage;
- EFI_PHYSICAL_ADDRESS InitrdImage;
-
- PERF_START (NULL, "BDS", NULL, 0);
-
- // Load the Linux kernel from a device path
- LinuxImage = LINUX_KERNEL_MAX_OFFSET;
- Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
- if (EFI_ERROR(Status)) {
- Print (L"ERROR: Did not find Linux kernel.\n");
- return Status;
- }
-
- if (InitrdDevicePath) {
- // Load the initrd near to the Linux kernel
- InitrdImage = LINUX_KERNEL_MAX_OFFSET;
- Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);
- if (Status == EFI_OUT_OF_RESOURCES) {
- Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
- }
- if (EFI_ERROR(Status)) {
- Print (L"ERROR: Did not find initrd image.\n");
- return Status;
- }
-
- // Check if the initrd is a uInitrd
- if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {
- // Skip the 64-byte image header
- InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);
- InitrdImageSize -= 64;
- }
- }
-
- //
- // Setup the Linux Kernel Parameters
- //
-
- // By setting address=0 we leave the memory allocation to the function
- Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);
- if (EFI_ERROR(Status)) {
- Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);
- return Status;
- }
-
- return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));
-}
-
-/**
- Start a Linux kernel from a Device Path
-
- @param LinuxKernel Device Path to the Linux Kernel
- @param Parameters Linux kernel arguments
- @param Fdt Device Path to the Flat Device Tree
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsBootLinuxFdt (
- IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
- IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
- IN CONST CHAR8* CommandLineArguments,
- IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
- )
-{
- EFI_STATUS Status;
- UINT32 LinuxImageSize;
- UINT32 InitrdImageSize = 0;
- UINT32 FdtBlobSize;
- EFI_PHYSICAL_ADDRESS FdtBlobBase;
- EFI_PHYSICAL_ADDRESS LinuxImage;
- EFI_PHYSICAL_ADDRESS InitrdImage;
-
- PERF_START (NULL, "BDS", NULL, 0);
-
- // Load the Linux kernel from a device path
- LinuxImage = LINUX_KERNEL_MAX_OFFSET;
- Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
- if (EFI_ERROR(Status)) {
- Print (L"ERROR: Did not find Linux kernel.\n");
- return Status;
- }
-
- if (InitrdDevicePath) {
- InitrdImage = LINUX_KERNEL_MAX_OFFSET;
- Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);
- if (Status == EFI_OUT_OF_RESOURCES) {
- Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
- }
- if (EFI_ERROR(Status)) {
- Print (L"ERROR: Did not find initrd image.\n");
- return Status;
- }
-
- // Check if the initrd is a uInitrd
- if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {
- // Skip the 64-byte image header
- InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);
- InitrdImageSize -= 64;
- }
- }
-
- // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.
- FdtBlobBase = 0;
- Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);
- if (EFI_ERROR(Status)) {
- Print (L"ERROR: Did not find Device Tree blob.\n");
- return Status;
- }
-
- // Update the Fdt with the Initrd information. The FDT will increase in size.
- // By setting address=0 we leave the memory allocation to the function
- Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);
- if (EFI_ERROR(Status)) {
- Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);
- return Status;
- }
-
- return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);
-}
-
+/** @file\r
+*\r
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
+* \r
+* This program and the accompanying materials \r
+* are licensed and made available under the terms and conditions of the BSD License \r
+* which accompanies this distribution. The full text of the license may be found at \r
+* http://opensource.org/licenses/bsd-license.php \r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+*\r
+**/\r
+\r
+#include "BdsInternal.h"\r
+#include "BdsLinuxLoader.h"\r
+\r
+#define ALIGN32_BELOW(addr) ALIGN_POINTER(addr - 32,32)\r
+\r
+STATIC\r
+EFI_STATUS\r
+PreparePlatformHardware (\r
+ VOID\r
+ )\r
+{\r
+ //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.\r
+\r
+ // Clean, invalidate, disable data cache\r
+ ArmDisableDataCache();\r
+ ArmCleanInvalidateDataCache();\r
+\r
+ // Invalidate and disable the Instruction cache\r
+ ArmDisableInstructionCache ();\r
+ ArmInvalidateInstructionCache ();\r
+\r
+ // Turn off MMU\r
+ ArmDisableMmu();\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+StartLinux (\r
+ IN EFI_PHYSICAL_ADDRESS LinuxImage,\r
+ IN UINTN LinuxImageSize,\r
+ IN EFI_PHYSICAL_ADDRESS KernelParamsAddress,\r
+ IN UINTN KernelParamsSize,\r
+ IN UINT32 MachineType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LINUX_KERNEL LinuxKernel;\r
+\r
+ // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on\r
+ // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.\r
+ Status = ShutdownUefiBootServices ();\r
+ if(EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));\r
+ goto Exit;\r
+ }\r
+\r
+ // Move the kernel parameters to any address inside the first 1MB.\r
+ // This is necessary because the ARM Linux kernel requires\r
+ // the FTD / ATAG List to reside entirely inside the first 1MB of\r
+ // physical memory.\r
+ //Note: There is no requirement on the alignment\r
+ if (MachineType != ARM_FDT_MACHINE_TYPE) {\r
+ if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {\r
+ KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
+ }\r
+ } else {\r
+ if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {\r
+ KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
+ }\r
+ }\r
+\r
+ if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {\r
+ //Note: There is no requirement on the alignment\r
+ LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);\r
+ } else {\r
+ LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;\r
+ }\r
+\r
+ // Check if the Linux Image is a uImage\r
+ if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {\r
+ // Assume the Image Entry Point is just after the uImage header (64-byte size)\r
+ LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);\r
+ LinuxImageSize -= 64;\r
+ }\r
+\r
+ //TODO: Check there is no overlapping between kernel and Atag\r
+\r
+ //\r
+ // Switch off interrupts, caches, mmu, etc\r
+ //\r
+ Status = PreparePlatformHardware ();\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ // Register and print out performance information\r
+ PERF_END (NULL, "BDS", NULL, 0);\r
+ if (PerformanceMeasurementEnabled ()) {\r
+ PrintPerformance ();\r
+ }\r
+\r
+ //\r
+ // Start the Linux Kernel\r
+ //\r
+\r
+ // Outside BootServices, so can't use Print();\r
+ DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));\r
+\r
+ // Jump to kernel with register set\r
+ LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);\r
+\r
+ // Kernel should never exit\r
+ // After Life services are not provided\r
+ ASSERT(FALSE);\r
+\r
+Exit:\r
+ // Only be here if we fail to start Linux\r
+ Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status);\r
+\r
+ // Free Runtimee Memory (kernel and FDT)\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Start a Linux kernel from a Device Path\r
+\r
+ @param LinuxKernel Device Path to the Linux Kernel\r
+ @param Parameters Linux kernel arguments\r
+ @param Fdt Device Path to the Flat Device Tree\r
+\r
+ @retval EFI_SUCCESS All drivers have been connected\r
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsBootLinuxAtag (\r
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+ IN CONST CHAR8* CommandLineArguments\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 LinuxImageSize;\r
+ UINT32 InitrdImageSize = 0;\r
+ UINT32 AtagSize;\r
+ EFI_PHYSICAL_ADDRESS AtagBase;\r
+ EFI_PHYSICAL_ADDRESS LinuxImage;\r
+ EFI_PHYSICAL_ADDRESS InitrdImage;\r
+\r
+ PERF_START (NULL, "BDS", NULL, 0);\r
+\r
+ // Load the Linux kernel from a device path\r
+ LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
+ if (EFI_ERROR(Status)) {\r
+ Print (L"ERROR: Did not find Linux kernel.\n");\r
+ return Status;\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
+ if (Status == EFI_OUT_OF_RESOURCES) {\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+ }\r
+ if (EFI_ERROR(Status)) {\r
+ Print (L"ERROR: Did not find initrd image.\n");\r
+ return Status;\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
+ }\r
+ }\r
+\r
+ //\r
+ // Setup the Linux Kernel Parameters\r
+ //\r
+ \r
+ // By setting address=0 we leave the memory allocation to the function\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
+ }\r
+\r
+ return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));\r
+}\r
+\r
+/**\r
+ Start a Linux kernel from a Device Path\r
+\r
+ @param LinuxKernel Device Path to the Linux Kernel\r
+ @param Parameters Linux kernel arguments\r
+ @param Fdt Device Path to the Flat Device Tree\r
+\r
+ @retval EFI_SUCCESS All drivers have been connected\r
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsBootLinuxFdt (\r
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+ IN CONST CHAR8* CommandLineArguments,\r
+ IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 LinuxImageSize;\r
+ UINT32 InitrdImageSize = 0;\r
+ UINT32 FdtBlobSize;\r
+ EFI_PHYSICAL_ADDRESS FdtBlobBase;\r
+ EFI_PHYSICAL_ADDRESS LinuxImage;\r
+ EFI_PHYSICAL_ADDRESS InitrdImage;\r
+\r
+ PERF_START (NULL, "BDS", NULL, 0);\r
+\r
+ // Load the Linux kernel from a device path\r
+ LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
+ if (EFI_ERROR(Status)) {\r
+ Print (L"ERROR: Did not find Linux kernel.\n");\r
+ return Status;\r
+ }\r
+\r
+ if (InitrdDevicePath) {\r
+ InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
+ if (Status == EFI_OUT_OF_RESOURCES) {\r
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+ }\r
+ if (EFI_ERROR(Status)) {\r
+ Print (L"ERROR: Did not find initrd image.\n");\r
+ return Status;\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
+ }\r
+ }\r
+\r
+ // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.\r
+ FdtBlobBase = 0;\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
+ }\r
+\r
+ // Update the Fdt with the Initrd information. The FDT will increase in size.\r
+ // By setting address=0 we leave the memory allocation to the function\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
+ }\r
+\r
+ return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);\r
+}\r
+\r