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
ParseAndroidBootImg(IN VOID * BootImg,OUT VOID ** Kernel,OUT UINTN * KernelSize,OUT VOID ** Ramdisk,OUT UINTN * RamdiskSize,OUT CHAR8 * KernelArgs)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