Home | History | Annotate | Download | only in AndroidFastboot
      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