mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-19 16:31:27 +01:00
The android boot header is page aligned but the current code made the
assumption that the header was always smaller than the current header
format.
When the page_size is defined as 2048, as this is the case with the
cuttlefish target, the current code sets the end of the header in the
middle of it as the v3 and v4 headers are respectively 2112 and 2128
bytes long.
Fix that by aligning to page_size
Fixes: 1115027d2f75 ("android: boot: update android_image_get_data to support v3, v4")
Signed-off-by: Guillaume Ranquet <ranquet.guillaume@gmail.com>
364 lines
14 KiB
C
364 lines
14 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause */
|
|
/*
|
|
* This is from the Android Project,
|
|
* Repository: https://android.googlesource.com/platform/system/tools/mkbootimg
|
|
* File: include/bootimg/bootimg.h
|
|
* Commit: cce5b1923e3cd2fcb765b512610bdc5c42bc501d
|
|
*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*/
|
|
|
|
#ifndef _ANDROID_IMAGE_H_
|
|
#define _ANDROID_IMAGE_H_
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/types.h>
|
|
|
|
#define ANDR_GKI_PAGE_SIZE 4096
|
|
#define ANDR_BOOT_MAGIC "ANDROID!"
|
|
#define ANDR_BOOT_MAGIC_SIZE 8
|
|
#define ANDR_BOOT_NAME_SIZE 16
|
|
#define ANDR_BOOT_ARGS_SIZE 512
|
|
#define ANDR_BOOT_EXTRA_ARGS_SIZE 1024
|
|
#define VENDOR_BOOT_MAGIC "VNDRBOOT"
|
|
#define ANDR_VENDOR_BOOT_V3_SIZE 2112 /* sz(andr_vnd_boot_img_hdr) - sz(vendor_ramdisk_table*) */
|
|
#define ANDR_VENDOR_BOOT_V4_SIZE 2128 /* sz(andr_vnd_boot_img_hdr) */
|
|
#define ANDR_VENDOR_BOOT_MAGIC_SIZE 8
|
|
#define ANDR_VENDOR_BOOT_ARGS_SIZE 2048
|
|
#define ANDR_VENDOR_BOOT_NAME_SIZE 16
|
|
|
|
#define BOOTCONFIG_MAGIC "#BOOTCONFIG\n"
|
|
#define BOOTCONFIG_MAGIC_SIZE 12
|
|
#define BOOTCONFIG_SIZE_SIZE 4
|
|
#define BOOTCONFIG_CHECKSUM_SIZE 4
|
|
#define BOOTCONFIG_TRAILER_SIZE BOOTCONFIG_MAGIC_SIZE + \
|
|
BOOTCONFIG_SIZE_SIZE + \
|
|
BOOTCONFIG_CHECKSUM_SIZE
|
|
|
|
struct andr_boot_img_hdr_v3 {
|
|
u8 magic[ANDR_BOOT_MAGIC_SIZE];
|
|
|
|
u32 kernel_size; /* size in bytes */
|
|
u32 ramdisk_size; /* size in bytes */
|
|
|
|
u32 os_version;
|
|
|
|
u32 header_size; /* size of boot image header in bytes */
|
|
u32 reserved[4];
|
|
u32 header_version; /* offset remains constant for version check */
|
|
|
|
u8 cmdline[ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE];
|
|
/* for boot image header v4 only */
|
|
u32 signature_size; /* size in bytes */
|
|
};
|
|
|
|
struct andr_vnd_boot_img_hdr {
|
|
u8 magic[ANDR_VENDOR_BOOT_MAGIC_SIZE];
|
|
u32 header_version;
|
|
u32 page_size; /* flash page size we assume */
|
|
|
|
u32 kernel_addr; /* physical load addr */
|
|
u32 ramdisk_addr; /* physical load addr */
|
|
|
|
u32 vendor_ramdisk_size; /* size in bytes */
|
|
|
|
u8 cmdline[ANDR_VENDOR_BOOT_ARGS_SIZE];
|
|
|
|
u32 tags_addr; /* physical addr for kernel tags */
|
|
|
|
u8 name[ANDR_VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
|
|
u32 header_size; /* size of vendor boot image header in bytes */
|
|
u32 dtb_size; /* size of dtb image */
|
|
u64 dtb_addr; /* physical load address */
|
|
/* for boot image header v4 only */
|
|
u32 vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
|
|
u32 vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
|
|
u32 vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
|
|
u32 bootconfig_size; /* size in bytes for the bootconfig section */
|
|
};
|
|
|
|
/* The bootloader expects the structure of andr_boot_img_hdr_v0 with header
|
|
* version 0 to be as follows: */
|
|
struct andr_boot_img_hdr_v0 {
|
|
/* Must be ANDR_BOOT_MAGIC. */
|
|
char magic[ANDR_BOOT_MAGIC_SIZE];
|
|
|
|
u32 kernel_size; /* size in bytes */
|
|
u32 kernel_addr; /* physical load addr */
|
|
|
|
u32 ramdisk_size; /* size in bytes */
|
|
u32 ramdisk_addr; /* physical load addr */
|
|
|
|
u32 second_size; /* size in bytes */
|
|
u32 second_addr; /* physical load addr */
|
|
|
|
u32 tags_addr; /* physical addr for kernel tags */
|
|
u32 page_size; /* flash page size we assume */
|
|
|
|
/* Version of the boot image header. */
|
|
u32 header_version;
|
|
|
|
/* Operating system version and security patch level.
|
|
* For version "A.B.C" and patch level "Y-M-D":
|
|
* (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M)
|
|
* os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] */
|
|
u32 os_version;
|
|
|
|
char name[ANDR_BOOT_NAME_SIZE]; /* asciiz product name */
|
|
|
|
char cmdline[ANDR_BOOT_ARGS_SIZE];
|
|
|
|
u32 id[8]; /* timestamp / checksum / sha1 / etc */
|
|
|
|
/* Supplemental command line data; kept here to maintain
|
|
* binary compatibility with older versions of mkbootimg. */
|
|
char extra_cmdline[ANDR_BOOT_EXTRA_ARGS_SIZE];
|
|
|
|
/* Fields in boot_img_hdr_v1 and newer. */
|
|
u32 recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */
|
|
u64 recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */
|
|
u32 header_size;
|
|
|
|
/* Fields in boot_img_hdr_v2 and newer. */
|
|
u32 dtb_size; /* size in bytes for DTB image */
|
|
u64 dtb_addr; /* physical load address for DTB image */
|
|
} __attribute__((packed));
|
|
|
|
/* When a boot header is of version 0, the structure of boot image is as
|
|
* follows:
|
|
*
|
|
* +-----------------+
|
|
* | boot header | 1 page
|
|
* +-----------------+
|
|
* | kernel | n pages
|
|
* +-----------------+
|
|
* | ramdisk | m pages
|
|
* +-----------------+
|
|
* | second stage | o pages
|
|
* +-----------------+
|
|
*
|
|
* n = (kernel_size + page_size - 1) / page_size
|
|
* m = (ramdisk_size + page_size - 1) / page_size
|
|
* o = (second_size + page_size - 1) / page_size
|
|
*
|
|
* 0. all entities are page_size aligned in flash
|
|
* 1. kernel and ramdisk are required (size != 0)
|
|
* 2. second is optional (second_size == 0 -> no second)
|
|
* 3. load each element (kernel, ramdisk, second) at
|
|
* the specified physical address (kernel_addr, etc)
|
|
* 4. prepare tags at tag_addr. kernel_args[] is
|
|
* appended to the kernel commandline in the tags.
|
|
* 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
|
|
* 6. if second_size != 0: jump to second_addr
|
|
* else: jump to kernel_addr
|
|
*/
|
|
|
|
/* When the boot image header has a version of 2, the structure of the boot
|
|
* image is as follows:
|
|
*
|
|
* +---------------------+
|
|
* | boot header | 1 page
|
|
* +---------------------+
|
|
* | kernel | n pages
|
|
* +---------------------+
|
|
* | ramdisk | m pages
|
|
* +---------------------+
|
|
* | second stage | o pages
|
|
* +---------------------+
|
|
* | recovery dtbo/acpio | p pages
|
|
* +---------------------+
|
|
* | dtb | q pages
|
|
* +---------------------+
|
|
*
|
|
* n = (kernel_size + page_size - 1) / page_size
|
|
* m = (ramdisk_size + page_size - 1) / page_size
|
|
* o = (second_size + page_size - 1) / page_size
|
|
* p = (recovery_dtbo_size + page_size - 1) / page_size
|
|
* q = (dtb_size + page_size - 1) / page_size
|
|
*
|
|
* 0. all entities are page_size aligned in flash
|
|
* 1. kernel, ramdisk and DTB are required (size != 0)
|
|
* 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B
|
|
* devices(recovery_dtbo_size != 0)
|
|
* 3. second is optional (second_size == 0 -> no second)
|
|
* 4. load each element (kernel, ramdisk, second, dtb) at
|
|
* the specified physical address (kernel_addr, etc)
|
|
* 5. If booting to recovery mode in a non-A/B device, extract recovery
|
|
* dtbo/acpio and apply the correct set of overlays on the base device tree
|
|
* depending on the hardware/product revision.
|
|
* 6. prepare tags at tag_addr. kernel_args[] is
|
|
* appended to the kernel commandline in the tags.
|
|
* 7. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
|
|
* 8. if second_size != 0: jump to second_addr
|
|
* else: jump to kernel_addr
|
|
*/
|
|
|
|
/* When the boot image header has a version of 3, the structure of the boot
|
|
* image is as follows:
|
|
*
|
|
* +---------------------+
|
|
* | boot header | 4096 bytes
|
|
* +---------------------+
|
|
* | kernel | m pages
|
|
* +---------------------+
|
|
* | ramdisk | n pages
|
|
* +---------------------+
|
|
*
|
|
* m = (kernel_size + 4096 - 1) / 4096
|
|
* n = (ramdisk_size + 4096 - 1) / 4096
|
|
*
|
|
* Note that in version 3 of the boot image header, page size is fixed at 4096 bytes.
|
|
*
|
|
* The structure of the vendor boot image (introduced with version 3 and
|
|
* required to be present when a v3 boot image is used) is as follows:
|
|
*
|
|
* +---------------------+
|
|
* | vendor boot header | o pages
|
|
* +---------------------+
|
|
* | vendor ramdisk | p pages
|
|
* +---------------------+
|
|
* | dtb | q pages
|
|
* +---------------------+
|
|
* o = (2112 + page_size - 1) / page_size
|
|
* p = (vendor_ramdisk_size + page_size - 1) / page_size
|
|
* q = (dtb_size + page_size - 1) / page_size
|
|
*
|
|
* 0. all entities in the boot image are 4096-byte aligned in flash, all
|
|
* entities in the vendor boot image are page_size (determined by the vendor
|
|
* and specified in the vendor boot image header) aligned in flash
|
|
* 1. kernel, ramdisk, vendor ramdisk, and DTB are required (size != 0)
|
|
* 2. load the kernel and DTB at the specified physical address (kernel_addr,
|
|
* dtb_addr)
|
|
* 3. load the vendor ramdisk at ramdisk_addr
|
|
* 4. load the generic ramdisk immediately following the vendor ramdisk in
|
|
* memory
|
|
* 5. set up registers for kernel entry as required by your architecture
|
|
* 6. if the platform has a second stage bootloader jump to it (must be
|
|
* contained outside boot and vendor boot partitions), otherwise
|
|
* jump to kernel_addr
|
|
*/
|
|
|
|
/* When the boot image header has a version of 4, the structure of the boot
|
|
* image is as follows:
|
|
*
|
|
* +---------------------+
|
|
* | boot header | 4096 bytes
|
|
* +---------------------+
|
|
* | kernel | m pages
|
|
* +---------------------+
|
|
* | ramdisk | n pages
|
|
* +---------------------+
|
|
* | boot signature | g pages
|
|
* +---------------------+
|
|
*
|
|
* m = (kernel_size + 4096 - 1) / 4096
|
|
* n = (ramdisk_size + 4096 - 1) / 4096
|
|
* g = (signature_size + 4096 - 1) / 4096
|
|
*
|
|
* Note that in version 4 of the boot image header, page size is fixed at 4096
|
|
* bytes.
|
|
*
|
|
* The structure of the vendor boot image version 4, which is required to be
|
|
* present when a version 4 boot image is used, is as follows:
|
|
*
|
|
* +------------------------+
|
|
* | vendor boot header | o pages
|
|
* +------------------------+
|
|
* | vendor ramdisk section | p pages
|
|
* +------------------------+
|
|
* | dtb | q pages
|
|
* +------------------------+
|
|
* | vendor ramdisk table | r pages
|
|
* +------------------------+
|
|
* | bootconfig | s pages
|
|
* +------------------------+
|
|
*
|
|
* o = (2128 + page_size - 1) / page_size
|
|
* p = (vendor_ramdisk_size + page_size - 1) / page_size
|
|
* q = (dtb_size + page_size - 1) / page_size
|
|
* r = (vendor_ramdisk_table_size + page_size - 1) / page_size
|
|
* s = (vendor_bootconfig_size + page_size - 1) / page_size
|
|
*
|
|
* Note that in version 4 of the vendor boot image, multiple vendor ramdisks can
|
|
* be included in the vendor boot image. The bootloader can select a subset of
|
|
* ramdisks to load at runtime. To help the bootloader select the ramdisks, each
|
|
* ramdisk is tagged with a type tag and a set of hardware identifiers
|
|
* describing the board, soc or platform that this ramdisk is intended for.
|
|
*
|
|
* The vendor ramdisk section is consist of multiple ramdisk images concatenated
|
|
* one after another, and vendor_ramdisk_size is the size of the section, which
|
|
* is the total size of all the ramdisks included in the vendor boot image.
|
|
*
|
|
* The vendor ramdisk table holds the size, offset, type, name and hardware
|
|
* identifiers of each ramdisk. The type field denotes the type of its content.
|
|
* The vendor ramdisk names are unique. The hardware identifiers are specified
|
|
* in the board_id field in each table entry. The board_id field is consist of a
|
|
* vector of unsigned integer words, and the encoding scheme is defined by the
|
|
* hardware vendor.
|
|
*
|
|
* For the different type of ramdisks, there are:
|
|
* - VENDOR_RAMDISK_TYPE_NONE indicates the value is unspecified.
|
|
* - VENDOR_RAMDISK_TYPE_PLATFORM ramdisks contain platform specific bits, so
|
|
* the bootloader should always load these into memory.
|
|
* - VENDOR_RAMDISK_TYPE_RECOVERY ramdisks contain recovery resources, so
|
|
* the bootloader should load these when booting into recovery.
|
|
* - VENDOR_RAMDISK_TYPE_DLKM ramdisks contain dynamic loadable kernel
|
|
* modules.
|
|
*
|
|
* Version 4 of the vendor boot image also adds a bootconfig section to the end
|
|
* of the image. This section contains Boot Configuration parameters known at
|
|
* build time. The bootloader is responsible for placing this section directly
|
|
* after the generic ramdisk, followed by the bootconfig trailer, before
|
|
* entering the kernel.
|
|
*
|
|
* 0. all entities in the boot image are 4096-byte aligned in flash, all
|
|
* entities in the vendor boot image are page_size (determined by the vendor
|
|
* and specified in the vendor boot image header) aligned in flash
|
|
* 1. kernel, ramdisk, and DTB are required (size != 0)
|
|
* 2. load the kernel and DTB at the specified physical address (kernel_addr,
|
|
* dtb_addr)
|
|
* 3. load the vendor ramdisks at ramdisk_addr
|
|
* 4. load the generic ramdisk immediately following the vendor ramdisk in
|
|
* memory
|
|
* 5. load the bootconfig immediately following the generic ramdisk. Add
|
|
* additional bootconfig parameters followed by the bootconfig trailer.
|
|
* 6. set up registers for kernel entry as required by your architecture
|
|
* 7. if the platform has a second stage bootloader jump to it (must be
|
|
* contained outside boot and vendor boot partitions), otherwise
|
|
* jump to kernel_addr
|
|
*/
|
|
|
|
/* Private struct */
|
|
struct andr_image_data {
|
|
ulong kernel_ptr; /* kernel address */
|
|
u32 kernel_size; /* size in bytes */
|
|
u32 ramdisk_size; /* size in bytes */
|
|
ulong vendor_ramdisk_ptr; /* vendor ramdisk address */
|
|
u32 vendor_ramdisk_size; /* vendor ramdisk size*/
|
|
u32 boot_ramdisk_size; /* size in bytes */
|
|
ulong second_ptr; /* secondary bootloader address */
|
|
u32 second_size; /* secondary bootloader size */
|
|
ulong dtb_ptr; /* address of dtb image */
|
|
u32 dtb_size; /* size of dtb image */
|
|
ulong recovery_dtbo_ptr; /* size in bytes for recovery DTBO/ACPIO image */
|
|
u32 recovery_dtbo_size; /* offset to recovery dtbo/acpio in boot image */
|
|
|
|
const char *kcmdline; /* boot kernel cmdline */
|
|
const char *kcmdline_extra; /* vendor-boot extra kernel cmdline */
|
|
const char *image_name; /* asciiz product name */
|
|
|
|
ulong bootconfig_addr; /* bootconfig image address */
|
|
ulong bootconfig_size; /* bootconfig image size */
|
|
|
|
ulong kernel_addr; /* physical load addr */
|
|
ulong ramdisk_addr; /* physical load addr */
|
|
ulong ramdisk_ptr; /* ramdisk address */
|
|
ulong dtb_load_addr; /* physical load address for DTB image */
|
|
ulong tags_addr; /* physical addr for kernel tags */
|
|
u32 header_version; /* version of the boot image header */
|
|
u32 boot_img_total_size; /* boot image size */
|
|
u32 vendor_boot_img_total_size; /* vendor boot image size */
|
|
};
|
|
|
|
#endif
|