]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/BdsLib: Use two distinct functions to boot Linux either by Atag or Fdt
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 22 Sep 2011 22:54:38 +0000 (22:54 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 22 Sep 2011 22:54:38 +0000 (22:54 +0000)
Separate the BdsBootLinux() function into two functions for Atag and Fdt specific Linux booting
- BdsBootLinuxAtag ()
- BdsBootLinuxFdt ()

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12408 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Include/Library/BdsLib.h
ArmPkg/Library/BdsLib/BdsInternal.h
ArmPkg/Library/BdsLib/BdsLinuxLoader.c
ArmPkg/Library/BdsLib/BdsLinuxLoader.h
ArmPlatformPkg/Bds/BootOption.c

index e9337d68cb28f1c3b620c148ec51acc0e4303fbb..c8e02c934eadb641365380f0f522e6ffcee20dfe 100644 (file)
@@ -96,6 +96,24 @@ BootOptionAllocateBootIndex (
   VOID\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
+\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*              Arguments\r
+  );\r
+\r
 /**\r
   Start a Linux kernel from a Device Path\r
 \r
@@ -109,7 +127,7 @@ BootOptionAllocateBootIndex (
 \r
 **/\r
 EFI_STATUS\r
-BdsBootLinux (\r
+BdsBootLinuxFdt (\r
   IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
   IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
   IN  CONST CHAR8*              Arguments,\r
index d450e8e6b2563bc2669b587eea3e6bb283628c75..9b73376f96a1d64661daed563edc4bfcc9df0527 100644 (file)
 #define __BDS_INTERNAL_H__
 
 #include <PiDxe.h>
+#include <Library/ArmLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/DebugLib.h>
 #include <Library/BdsLib.h>
+#include <Library/PcdLib.h>
 #include <Library/PerformanceLib.h>
 #include <Library/PrintLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
@@ -38,6 +41,7 @@
 #include <Protocol/LoadFile.h>
 #include <Protocol/PxeBaseCode.h>
 
+#include "BdsLinuxLoader.h"
 
 typedef BOOLEAN (*BDS_FILE_LOADER_SUPPORT) (
   IN EFI_DEVICE_PATH            *DevicePath,
index ce4b2a43b66aaa0dbbac7e7d79a281fb6803db4e..06baf49c55d4a05cee90fc91f42cd813774205ee 100644 (file)
 **/
 
 #include "BdsInternal.h"
-#include "BdsLinuxLoader.h"
-
-#include <Library/PcdLib.h>
-#include <Library/ArmLib.h>
-#include <Library/HobLib.h>
 
 #define ALIGN32_BELOW(addr)   ALIGN_POINTER(addr - 32,32)
 
-#define LINUX_ATAG_MAX_OFFSET     (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset))
-#define LINUX_KERNEL_MAX_OFFSET   (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset))
-
 // Point to the current ATAG
 STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;
 
@@ -178,7 +170,7 @@ PreparePlatformHardware (
 {
   //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
 
-  // clean, invalidate, disable data cache
+  // Clean, invalidate, disable data cache
   ArmCleanInvalidateDataCache();
   ArmDisableDataCache();
 
@@ -186,97 +178,24 @@ PreparePlatformHardware (
   ArmInvalidateInstructionCache ();
   ArmDisableInstructionCache ();
 
-  // turn off MMU
+  // Turn off MMU
   ArmDisableMmu();
 
   return EFI_SUCCESS;
 }
 
-/**
-  Start a Linux kernel from a Device Path
-
-  @param  LinuxKernel           Device Path to the Linux Kernel
-  @param  Parameters            Linux kernel agruments
-  @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.
-
-**/
+STATIC
 EFI_STATUS
-BdsBootLinux (
-  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
-  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
-  IN  CONST CHAR8*  Arguments,
-  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
+StartLinux (
+  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,
+  IN  UINTN                 LinuxImageSize,
+  IN  EFI_PHYSICAL_ADDRESS  KernelParamsAddress,
+  IN  UINTN                 KernelParamsSize,
+  IN  UINT32                MachineType
   )
 {
   EFI_STATUS            Status;
-  UINT32                LinuxImageSize;
-  UINT32                InitrdImageSize;
-  UINT32                KernelParamsSize;
-  EFI_PHYSICAL_ADDRESS  KernelParamsAddress;
-  UINT32                MachineType;
-  BOOLEAN               FdtSupported;
   LINUX_KERNEL          LinuxKernel;
-  EFI_PHYSICAL_ADDRESS  LinuxImage;
-  EFI_PHYSICAL_ADDRESS  InitrdImage;
-
-  InitrdImageSize = 0;
-  FdtSupported = FALSE;
-       
-  // Ensure the System Memory PCDs have been initialized (PcdSystemMemoryBase and PcdSystemMemorySize)
-  ASSERT (PcdGet32(PcdSystemMemorySize) != 0);
-
-  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;
-  }
-  LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;
-
-  if (InitrdDevicePath) {
-    Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
-    if (EFI_ERROR(Status)) {
-      Print (L"ERROR: Did not find initrd image.\n");
-      return Status;
-    }
-  }
-
-  if (FdtDevicePath) {
-    // Load the FDT binary from a device path
-    KernelParamsAddress = LINUX_ATAG_MAX_OFFSET;
-    Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &KernelParamsAddress, &KernelParamsSize);
-    if (EFI_ERROR(Status)) {
-      Print (L"ERROR: Did not find Device Tree blob.\n");
-      return Status;
-    }
-    FdtSupported = TRUE;
-  }
-
-  //
-  // Setup the Linux Kernel Parameters
-  //
-  if (!FdtSupported) {
-    // Non-FDT requires a specific machine type.
-    // This OS Boot loader supports just one machine type,
-    // but that could change in the future.
-    MachineType = PcdGet32(PcdArmMachineType);
-
-    // By setting address=0 we leave the memory allocation to the function
-    Status = PrepareAtagList (Arguments, InitrdImage, InitrdImageSize, (LINUX_ATAG**)&KernelParamsAddress, &KernelParamsSize);
-    if(EFI_ERROR(Status)) {
-      Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);
-      goto Exit;
-    }
-  } else {
-    MachineType = 0xFFFFFFFF;
-  }
 
   // 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.
@@ -298,6 +217,8 @@ BdsBootLinux (
   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;
   }
 
   //TODO: Check there is no overlapping between kernel and Atag
@@ -322,7 +243,7 @@ BdsBootLinux (
   DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));
 
   // jump to kernel with register set
-  LinuxKernel ((UINTN)0, (UINTN)MachineType, (UINTN)KernelParamsAddress);
+  LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);
 
   // Kernel should never exit
   // After Life services are not provided
@@ -335,3 +256,122 @@ Exit:
   // 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 agruments
+  @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*              Arguments
+  )
+{
+  EFI_STATUS            Status;
+  UINT32                LinuxImageSize;
+  UINT32                InitrdImageSize = 0;
+  UINT32                KernelParamsSize;
+  EFI_PHYSICAL_ADDRESS  KernelParamsAddress;
+  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) {
+    Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
+    if (EFI_ERROR(Status)) {
+      Print (L"ERROR: Did not find initrd image.\n");
+      return Status;
+    }
+  }
+
+  //
+  // Setup the Linux Kernel Parameters
+  //
+  // By setting address=0 we leave the memory allocation to the function
+  Status = PrepareAtagList (Arguments, InitrdImage, InitrdImageSize, (LINUX_ATAG**)&KernelParamsAddress, &KernelParamsSize);
+  if (EFI_ERROR(Status)) {
+    Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);
+    return Status;
+  }
+
+  return StartLinux (LinuxImage, LinuxImageSize, KernelParamsAddress, KernelParamsSize, PcdGet32(PcdArmMachineType));
+}
+
+/**
+  Start a Linux kernel from a Device Path
+
+  @param  LinuxKernel           Device Path to the Linux Kernel
+  @param  Parameters            Linux kernel agruments
+  @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*              Arguments,
+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
+  )
+{
+  EFI_STATUS            Status;
+  UINT32                LinuxImageSize;
+  UINT32                InitrdImageSize = 0;
+  UINT32                KernelParamsSize;
+  EFI_PHYSICAL_ADDRESS  KernelParamsAddress;
+  UINT32                FdtMachineType;
+  EFI_PHYSICAL_ADDRESS  LinuxImage;
+  EFI_PHYSICAL_ADDRESS  InitrdImage;
+
+  FdtMachineType = 0xFFFFFFFF;
+
+  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) {
+    Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);
+    if (EFI_ERROR(Status)) {
+      Print (L"ERROR: Did not find initrd image.\n");
+      return Status;
+    }
+  }
+
+  // Load the FDT binary from a device path
+  KernelParamsAddress = LINUX_ATAG_MAX_OFFSET;
+  Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &KernelParamsAddress, &KernelParamsSize);
+  if (EFI_ERROR(Status)) {
+    Print (L"ERROR: Did not find Device Tree blob.\n");
+    return Status;
+  }
+  return StartLinux (LinuxImage, LinuxImageSize, KernelParamsAddress, KernelParamsSize, FdtMachineType);
+}
+
index 82b7a4f081263fe51e31f1c2256b2a5bc4700748..e951e2a4bec9354191c5db76e96118f2a901962b 100644 (file)
@@ -15,6 +15,9 @@
 #ifndef __BDSLINUXLOADER_H
 #define __BDSLINUXLOADER_H
 
+#define LINUX_ATAG_MAX_OFFSET     (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset))
+#define LINUX_KERNEL_MAX_OFFSET   (PcdGet32(PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset))
+
 #define ATAG_MAX_SIZE       0x3000
 
 /* ATAG : list of possible tags */
index 86f2ac2dcad1c9c2c7d82287275302176ec4240e..305892a8d68435fcc2afd7ed6f3095a33ea799b9 100644 (file)
@@ -54,10 +54,9 @@ BootOptionStart (
         Initrd = NULL;\r
       }\r
 \r
-      Status = BdsBootLinux (BootOption->FilePathList,\r
+      Status = BdsBootLinuxAtag (BootOption->FilePathList,\r
                                  Initrd, // Initrd\r
-                                 (CHAR8*)(LinuxArguments + 1), // CmdLine\r
-                                 NULL);\r
+                                 (CHAR8*)(LinuxArguments + 1)); // CmdLine\r
     } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
       LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
       CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
@@ -79,7 +78,7 @@ BootOptionStart (
       Status = GetEnvironmentVariable ((CHAR16 *)L"FDT", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
       ASSERT_EFI_ERROR(Status);\r
 \r
-      Status = BdsBootLinux (BootOption->FilePathList,\r
+      Status = BdsBootLinuxFdt (BootOption->FilePathList,\r
                                 Initrd, // Initrd\r
                                 (CHAR8*)(LinuxArguments + 1),\r
                                 FdtDevicePath);\r