From f6755908dee0d71926ec4f440edd384523746ef6 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Wed, 5 Mar 2014 04:15:44 +0000 Subject: EmbeddedPkg/AndroidFastboot: Introduce Android FastBoot Application This application enables Android FastBoot on UEFI. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15312 6f19259b-4bc3-4df7-8a09-765794883524 --- .../AndroidFastboot/Arm/BootAndroidBootImg.c | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c (limited to 'EmbeddedPkg/Application/AndroidFastboot/Arm') diff --git a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c new file mode 100644 index 0000000000..6f4b66beeb --- /dev/null +++ b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c @@ -0,0 +1,125 @@ +/** @file + + Copyright (c) 2013-2014, ARM Ltd. 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 "AndroidFastbootApp.h" + +#include + +#include +#include + +#include + +// Device Path representing an image in memory +#pragma pack(1) +typedef struct { + MEMMAP_DEVICE_PATH Node1; + EFI_DEVICE_PATH_PROTOCOL End; +} MEMORY_DEVICE_PATH; +#pragma pack() + +STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate = +{ + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8), + }, + }, // Header + 0, // StartingAddress (set at runtime) + 0 // EndingAddress (set at runtime) + }, // Node1 + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + sizeof (EFI_DEVICE_PATH_PROTOCOL), + 0 + } // End +}; + +EFI_STATUS +BootAndroidBootImg ( + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EFI_DEVICE_PATH_PROTOCOL *FdtDevicePath; + EFI_STATUS Status; + CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; + VOID *Kernel; + UINTN KernelSize; + VOID *Ramdisk; + UINTN RamdiskSize; + MEMORY_DEVICE_PATH KernelDevicePath; + MEMORY_DEVICE_PATH* RamdiskDevicePath; + + Status = ParseAndroidBootImg ( + Buffer, + &Kernel, + &KernelSize, + &Ramdisk, + &RamdiskSize, + KernelArgs + ); + if (EFI_ERROR (Status)) { + return Status; + } + + KernelDevicePath = MemoryDevicePathTemplate; + + // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to + // appease GCC. + KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel; + KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize; + + RamdiskDevicePath = NULL; + if (RamdiskSize != 0) { + RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate); + + RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk; + RamdiskDevicePath->Node1.EndingAddress = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize; + } + + // Get the default FDT device path + Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid, + NULL, 0, (VOID **)&FdtDevicePath); + if (Status == EFI_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "Error: Please update FDT path in boot manager\n")); + return EFI_DEVICE_ERROR; + } + ASSERT_EFI_ERROR (Status); + + Status = BdsBootLinuxFdt ( + (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath, + KernelArgs, + FdtDevicePath + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status)); + return EFI_DEVICE_ERROR; + } + + if (RamdiskDevicePath) { + FreePool (RamdiskDevicePath); + } + + // If we got here we do a confused face because BootLinuxFdt returned, + // reporting success. + DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n")); + return EFI_SUCCESS; +} -- cgit v1.2.3