summaryrefslogtreecommitdiff
path: root/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2012-09-28 09:58:42 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2012-09-28 09:58:42 +0000
commit0a6653bc2aecaa621eb42c7137b6f13815a34a92 (patch)
tree20b450e1bfbdb014095d74786871e23c6e3a5d4b /ArmPkg/Library/BdsLib/BdsLinuxLoader.c
parent619b3998880e3c28c46d3a20bbbfa879e08b3579 (diff)
downloadedk2-platforms-0a6653bc2aecaa621eb42c7137b6f13815a34a92.tar.xz
ArmPkg/BdsLib: Added FDT support for BdsLib
Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13768 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg/Library/BdsLib/BdsLinuxLoader.c')
-rw-r--r--ArmPkg/Library/BdsLib/BdsLinuxLoader.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
index a3ba58023a..901781f2f8 100644
--- a/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
+++ b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
@@ -64,9 +64,15 @@ StartLinux (
// This is necessary because the ARM Linux kernel requires
// the FTD / ATAG List to reside entirely inside the first 1MB of
// physical memory.
- if ((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) {
- //Note: There is no requirement on the alignment
- KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
+ //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) {
@@ -135,14 +141,14 @@ EFI_STATUS
BdsBootLinuxAtag (
IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
- IN CONST CHAR8* Arguments
+ IN CONST CHAR8* CommandLineArguments
)
{
EFI_STATUS Status;
UINT32 LinuxImageSize;
UINT32 InitrdImageSize = 0;
- UINT32 KernelParamsSize;
- EFI_PHYSICAL_ADDRESS KernelParamsAddress;
+ UINT32 AtagSize;
+ EFI_PHYSICAL_ADDRESS AtagBase;
EFI_PHYSICAL_ADDRESS LinuxImage;
EFI_PHYSICAL_ADDRESS InitrdImage;
@@ -181,13 +187,13 @@ BdsBootLinuxAtag (
//
// By setting address=0 we leave the memory allocation to the function
- Status = PrepareAtagList (Arguments, InitrdImage, InitrdImageSize, &KernelParamsAddress, &KernelParamsSize);
+ 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, KernelParamsAddress, KernelParamsSize, PcdGet32(PcdArmMachineType));
+ return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));
}
/**
@@ -206,21 +212,18 @@ EFI_STATUS
BdsBootLinuxFdt (
IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
- IN CONST CHAR8* Arguments,
+ IN CONST CHAR8* CommandLineArguments,
IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
)
{
EFI_STATUS Status;
UINT32 LinuxImageSize;
UINT32 InitrdImageSize = 0;
- UINT32 KernelParamsSize;
- EFI_PHYSICAL_ADDRESS KernelParamsAddress;
- UINT32 FdtMachineType;
+ UINT32 FdtBlobSize;
+ EFI_PHYSICAL_ADDRESS FdtBlobBase;
EFI_PHYSICAL_ADDRESS LinuxImage;
EFI_PHYSICAL_ADDRESS InitrdImage;
- FdtMachineType = 0xFFFFFFFF;
-
PERF_START (NULL, "BDS", NULL, 0);
// Load the Linux kernel from a device path
@@ -250,13 +253,22 @@ BdsBootLinuxFdt (
}
}
- // Load the FDT binary from a device path
- KernelParamsAddress = LINUX_ATAG_MAX_OFFSET;
- Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &KernelParamsAddress, &KernelParamsSize);
+ // 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;
}
- return StartLinux (LinuxImage, LinuxImageSize, KernelParamsAddress, KernelParamsSize, FdtMachineType);
+
+ // 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);
}