1 /** @file 2 3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR> 4 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "AndroidFastbootApp.h" 16 17 #define BOOT_MAGIC "ANDROID!" 18 #define BOOT_MAGIC_LENGTH sizeof (BOOT_MAGIC) - 1 19 20 // Check Val (unsigned) is a power of 2 (has only one bit set) 21 #define IS_POWER_OF_2(Val) (Val != 0 && ((Val & (Val - 1)) == 0)) 22 23 // No documentation for this really - sizes of fields has been determined 24 // empirically. 25 #pragma pack(1) 26 typedef struct { 27 CHAR8 BootMagic[BOOT_MAGIC_LENGTH]; 28 UINT32 KernelSize; 29 UINT32 KernelAddress; 30 UINT32 RamdiskSize; 31 UINT32 RamdiskAddress; 32 UINT32 SecondStageBootloaderSize; 33 UINT32 SecondStageBootloaderAddress; 34 UINT32 KernelTaggsAddress; 35 UINT32 PageSize; 36 UINT32 Reserved[2]; 37 CHAR8 ProductName[16]; 38 CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; 39 UINT32 Id[32]; 40 } ANDROID_BOOTIMG_HEADER; 41 #pragma pack() 42 43 // Find the kernel and ramdisk in an Android boot.img. 44 // return EFI_INVALID_PARAMTER if the boot.img is invalid (i.e. doesn't have the 45 // right magic value), 46 // return EFI_NOT_FOUND if there was no kernel in the boot.img. 47 // Note that the Ramdisk is optional - *Ramdisk won't be touched if it isn't 48 // present, but RamdiskSize will be set to 0. 49 EFI_STATUS 50 ParseAndroidBootImg ( 51 IN VOID *BootImg, 52 OUT VOID **Kernel, 53 OUT UINTN *KernelSize, 54 OUT VOID **Ramdisk, 55 OUT UINTN *RamdiskSize, 56 OUT CHAR8 *KernelArgs 57 ) 58 { 59 ANDROID_BOOTIMG_HEADER *Header; 60 UINT8 *BootImgBytePtr; 61 62 // Cast to UINT8 so we can do pointer arithmetic 63 BootImgBytePtr = (UINT8 *) BootImg; 64 65 Header = (ANDROID_BOOTIMG_HEADER *) BootImg; 66 67 if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) { 68 return EFI_INVALID_PARAMETER; 69 } 70 71 if (Header->KernelSize == 0) { 72 return EFI_NOT_FOUND; 73 } 74 75 ASSERT (IS_POWER_OF_2 (Header->PageSize)); 76 77 *KernelSize = Header->KernelSize; 78 *Kernel = BootImgBytePtr + Header->PageSize; 79 *RamdiskSize = Header->RamdiskSize; 80 81 if (Header->RamdiskSize != 0) { 82 *Ramdisk = (VOID *) (BootImgBytePtr 83 + Header->PageSize 84 + ALIGN_VALUE (Header->KernelSize, Header->PageSize)); 85 } 86 87 AsciiStrnCpy (KernelArgs, Header->KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE); 88 89 return EFI_SUCCESS; 90 } 91