From d71a732af45e2d3acef92649f4f7986a83175cf4 Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:03 +0100 Subject: android: boot: rename andr_img_hdr -> andr_boot_img_hdr_v0 Android introduced boot header version 3 or 4. The header structure change with version 3 and 4 to support the new updates such as: - Introducing Vendor boot image: with a vendor ramdisk - Bootconfig feature (v4) Change andr_img_hdr struct name to maintain support for version v0, v1 and v2 while introducing version 3 and 4. Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- include/android_image.h | 4 +- include/image.h | 107 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/android_image.h b/include/android_image.h index 54d25af0684..2bdcab9122d 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -20,9 +20,9 @@ #define ANDR_BOOT_ARGS_SIZE 512 #define ANDR_BOOT_EXTRA_ARGS_SIZE 1024 -/* The bootloader expects the structure of andr_img_hdr with header +/* The bootloader expects the structure of andr_boot_img_hdr_v0 with header * version 0 to be as follows: */ -struct andr_img_hdr { +struct andr_boot_img_hdr_v0 { /* Must be ANDR_BOOT_MAGIC. */ char magic[ANDR_BOOT_MAGIC_SIZE]; diff --git a/include/image.h b/include/image.h index 7717a4c13d3..735484117d7 100644 --- a/include/image.h +++ b/include/image.h @@ -1734,21 +1734,108 @@ int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo); struct cipher_algo *image_get_cipher_algo(const char *full_name); -struct andr_img_hdr; -int android_image_check_header(const struct andr_img_hdr *hdr); -int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, +struct andr_boot_img_hdr_v0; + +/** + * android_image_check_header() - Check the magic of boot image + * + * This checks the header of Android boot image and verifies the + * magic is "ANDROID!" + * + * @hdr: Pointer to image header + * Return: 0 if the magic is correct, non-zero if there is a magic mismatch + */ +int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); + +/** + * android_image_get_kernel() - Processes kernel part of Android boot images + * + * This function returns the os image's start address and length. Also, + * it appends the kernel command line to the bootargs env variable. + * + * @hdr: Pointer to image header, which is at the start + * of the image. + * @verify: Checksum verification flag. Currently unimplemented. + * @os_data: Pointer to a ulong variable, will hold os data start + * address. + * @os_len: Pointer to a ulong variable, will hold os data length. + * Return: Zero, os start address and length on success, + * otherwise on failure. + */ +int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len); -int android_image_get_ramdisk(const struct andr_img_hdr *hdr, + +/** + * android_image_get_ramdisk() - Extracts the ramdisk load address and its size + * + * This extracts the load address of the ramdisk and its size + * + * @hdr: Pointer to image header + * @rd_data: Pointer to a ulong variable, will hold ramdisk address + * @rd_len: Pointer to a ulong variable, will hold ramdisk length + * Return: 0 if succeeded, -1 if ramdisk size is 0 + */ +int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, ulong *rd_data, ulong *rd_len); -int android_image_get_second(const struct andr_img_hdr *hdr, - ulong *second_data, ulong *second_len); + +/** + * android_image_get_second() - Extracts the secondary bootloader address + * and its size + * + * This extracts the address of the secondary bootloader and its size + * + * @hdr: Pointer to image header + * @second_data: Pointer to a ulong variable, will hold secondary bootloader address + * @second_len : Pointer to a ulong variable, will hold secondary bootloader length + * Return: 0 if succeeded, -1 if secondary bootloader size is 0 + */ +int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, + ulong *second_data, ulong *second_len); bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size); bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, u32 *size); -ulong android_image_get_end(const struct andr_img_hdr *hdr); -ulong android_image_get_kload(const struct andr_img_hdr *hdr); -ulong android_image_get_kcomp(const struct andr_img_hdr *hdr); -void android_print_contents(const struct andr_img_hdr *hdr); + +/** + * android_image_get_end() - Get the end of Android boot image + * + * This returns the end address of Android boot image address + * + * @hdr: Pointer to image header + * Return: The end address of Android boot image + */ +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); + +/** + * android_image_get_kload() - Get the kernel load address + * + * This returns the kernel load address. The load address is extracted + * from the boot image header or the "kernel_addr_r" environment variable + * + * @hdr: Pointer to image header + * Return: The kernel load address + */ +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr); + +/** + * android_image_get_kcomp() - Get kernel compression type + * + * This gets the kernel compression type from the boot image header + * + * @hdr: Pointer to image header + * Return: Kernel compression type + */ +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr); + +/** + * android_print_contents() - Prints out the contents of the Android format image + * + * This formats a multi line Android image contents description. + * The routine prints out Android image properties + * + * @hdr: Pointer to the Android format image header + * Return: no returned results + */ +void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); /** -- cgit v1.3.1 From 734cb47d6de16d2e3b52a03bce5daab40e5bb29d Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:05 +0100 Subject: android: boot: replace android_image_check_header With the new vendor boot image introduced in versions 3 and 4 of boot image header, the header check must be done for both boot image and vendor boot image. Thus, replace android_image_check_header() by is_android_boot_image_header() to only refer to boot image header check. Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/image-android.c | 17 ++++------------- boot/image-board.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 3 +-- include/image.h | 22 +++++++++++----------- 5 files changed, 19 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/boot/image-android.c b/boot/image-android.c index b070974791a..ac7cb479c15 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -122,18 +122,9 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, return 0; } -/** - * android_image_check_header() - Check the magic of boot image - * - * This checks the header of Android boot image and verifies the - * magic is "ANDROID!" - * - * @hdr: Pointer to boot image - * Return: 0 if the magic is correct, non-zero if there is a magic mismatch - */ -int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr) +bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr) { - return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); + return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); } ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) @@ -240,7 +231,7 @@ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) bool ret = true; hdr = map_sysmem(hdr_addr, sizeof(*hdr)); - if (android_image_check_header(hdr)) { + if (!is_android_boot_image_header(hdr)) { printf("Error: Boot Image header is incorrect\n"); ret = false; goto exit; @@ -289,7 +280,7 @@ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr) bool ret = true; hdr = map_sysmem(hdr_addr, sizeof(*hdr)); - if (android_image_check_header(hdr)) { + if (!is_android_boot_image_header(hdr)) { printf("Error: Boot Image header is incorrect\n"); ret = false; goto exit; diff --git a/boot/image-board.c b/boot/image-board.c index 9bf70824cb7..e086103258f 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -284,7 +284,7 @@ int genimg_get_format(const void *img_addr) return IMAGE_FORMAT_FIT; } if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) && - !android_image_check_header(img_addr)) + is_android_boot_image_header(img_addr)) return IMAGE_FORMAT_ANDROID; return IMAGE_FORMAT_INVALID; diff --git a/cmd/abootimg.c b/cmd/abootimg.c index 026c03f91c7..b5cfb141ef7 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -26,7 +26,7 @@ static int abootimg_get_ver(int argc, char *const argv[]) return CMD_RET_USAGE; hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); - if (android_image_check_header(hdr)) { + if (!is_android_boot_image_header(hdr)) { printf("Error: Boot Image header is incorrect\n"); res = CMD_RET_FAILURE; goto exit; @@ -73,7 +73,7 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) return CMD_RET_USAGE; hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); - if (android_image_check_header(hdr)) { + if (!is_android_boot_image_header(hdr)) { printf("Error: Boot Image header is incorrect\n"); res = CMD_RET_FAILURE; goto exit; diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index 68677c55ce1..29c18cb82a4 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -313,8 +313,7 @@ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc, } /* Check boot header magic string */ - res = android_image_check_header(hdr); - if (res != 0) { + if (!is_android_boot_image_header(hdr)) { pr_err("bad boot image magic\n"); fastboot_fail("boot partition not initialized", response); return 0; diff --git a/include/image.h b/include/image.h index 735484117d7..6e67cf4817a 100644 --- a/include/image.h +++ b/include/image.h @@ -1736,17 +1736,6 @@ struct cipher_algo *image_get_cipher_algo(const char *full_name); struct andr_boot_img_hdr_v0; -/** - * android_image_check_header() - Check the magic of boot image - * - * This checks the header of Android boot image and verifies the - * magic is "ANDROID!" - * - * @hdr: Pointer to image header - * Return: 0 if the magic is correct, non-zero if there is a magic mismatch - */ -int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); - /** * android_image_get_kernel() - Processes kernel part of Android boot images * @@ -1838,6 +1827,17 @@ ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); +/** + * is_android_boot_image_header() - Check the magic of boot image + * + * This checks the header of Android boot image and verifies the + * magic is "ANDROID!" + * + * @hdr: Pointer to boot image + * Return: non-zero if the magic is correct, zero otherwise + */ +bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); + /** * board_fit_config_name_match() - Check for a matching board name * -- cgit v1.3.1 From fbb645e7d9bc1a0da05fff8421d398c8aa43a331 Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:06 +0100 Subject: android: boot: add boot image header v3 and v4 structures Add support for v3/v4 boot image format by adding the following structures: - andr_boot_img_hdr_v3 : describes boot image header - andr_vnd_boot_img_hdr : describes vendor boot image header These definitions have been copied over from the AOSP documentation at [1] and [2] Boot arg sizes are taken from [3]: commit: 35fb6262bc3f (ANDROID: Support for vendor boot) This also adds documentation for boot image header v3/v4 structure that was imported from [4], file: include/bootimg/bootimg.h commit: 8d0922bfb932 (Adding GKI signature in boot.img v4) Link:[1] https://source.android.com/docs/core/architecture/bootloader/boot-image-header Link:[2] https://source.android.com/docs/core/architecture/bootloader/partitions/vendor-boot-partitions#vendor-boot-header Link:[3] https://android.googlesource.com/platform/external/u-boot Link:[4] https://android.googlesource.com/platform/system/tools/mkbootimg Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- include/android_image.h | 183 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/android_image.h b/include/android_image.h index 2bdcab9122d..f0543630019 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -3,7 +3,7 @@ * This is from the Android Project, * Repository: https://android.googlesource.com/platform/system/tools/mkbootimg * File: include/bootimg/bootimg.h - * Commit: e55998a0f2b61b685d5eb4a486ca3a0c680b1a2f + * Commit: cce5b1923e3cd2fcb765b512610bdc5c42bc501d * * Copyright (C) 2007 The Android Open Source Project */ @@ -14,11 +14,58 @@ #include #include +#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_MAGIC_SIZE 8 +#define ANDR_VENDOR_BOOT_ARGS_SIZE 2048 +#define ANDR_VENDOR_BOOT_NAME_SIZE 16 + +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: */ @@ -136,4 +183,138 @@ struct andr_boot_img_hdr_v0 { * 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 + */ #endif -- cgit v1.3.1 From f48efa0edb6f65b2c382209871df7c9b61a905e2 Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:07 +0100 Subject: android: boot: kcomp: support andr_image_data andr_image_data structure is used as a global representation of boot image header structure. Introduce this new structure to support all boot header versions : v0,v1.v2.v3.v4 and to support v3 and v4 while maitaining support for v0,v1,v2. The need of using andr_image_data comes from the change of header structure in both version 3 and 4. Rework android_image_get_kcomp() to support this new struct. Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/image-android.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++- include/android_image.h | 27 ++++++++++++++++++ include/image.h | 12 ++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/boot/image-android.c b/boot/image-android.c index ac7cb479c15..ea05c1814f0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -18,6 +18,74 @@ static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; +static void android_boot_image_v0_v1_v2_parse_hdr(const struct andr_boot_img_hdr_v0 *hdr, + struct andr_image_data *data) +{ + ulong end; + + data->image_name = hdr->name; + data->kcmdline = hdr->cmdline; + data->kernel_addr = hdr->kernel_addr; + data->ramdisk_addr = hdr->ramdisk_addr; + data->header_version = hdr->header_version; + data->dtb_load_addr = hdr->dtb_addr; + + end = (ulong)hdr; + + /* + * The header takes a full page, the remaining components are aligned + * on page boundary + */ + + end += hdr->page_size; + + data->kernel_ptr = end; + data->kernel_size = hdr->kernel_size; + end += ALIGN(hdr->kernel_size, hdr->page_size); + + data->ramdisk_ptr = end; + data->ramdisk_size = hdr->ramdisk_size; + end += ALIGN(hdr->ramdisk_size, hdr->page_size); + + data->second_ptr = end; + data->second_size = hdr->second_size; + end += ALIGN(hdr->second_size, hdr->page_size); + + if (hdr->header_version >= 1) { + data->recovery_dtbo_ptr = end; + data->recovery_dtbo_size = hdr->recovery_dtbo_size; + end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); + } + + if (hdr->header_version >= 2) { + data->dtb_ptr = end; + data->dtb_size = hdr->dtb_size; + end += ALIGN(hdr->dtb_size, hdr->page_size); + } + + data->boot_img_total_size = end - (ulong)hdr; +} + +bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data) +{ + if (!boot_hdr || !data) { + printf("boot_hdr or data params can't be NULL\n"); + return false; + } + + if (!is_android_boot_image_header(boot_hdr)) { + printf("Incorrect boot image header\n"); + return false; + } + + if (((struct andr_boot_img_hdr_v0 *)boot_hdr)->header_version > 2) + printf("Only boot image header version 2 and below are supported\n"); + else + android_boot_image_v0_v1_v2_parse_hdr(boot_hdr, data); + + return true; +} + static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hdr) { /* @@ -157,8 +225,13 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr) ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr) { - const void *p = (void *)((uintptr_t)hdr + hdr->page_size); + struct andr_image_data img_data; + const void *p; + + if (!android_image_get_data(hdr, &img_data)) + return -EINVAL; + p = (const void *)img_data.kernel_ptr; if (image_get_magic((struct legacy_img_hdr *)p) == IH_MAGIC) return image_get_comp((struct legacy_img_hdr *)p); else if (get_unaligned_le32(p) == LZ4F_MAGIC) diff --git a/include/android_image.h b/include/android_image.h index f0543630019..fb3a9d9858b 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -317,4 +317,31 @@ struct andr_boot_img_hdr_v0 { * 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 */ + 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 */ + + u32 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 */ +}; + #endif diff --git a/include/image.h b/include/image.h index 6e67cf4817a..4bf6c98ced7 100644 --- a/include/image.h +++ b/include/image.h @@ -1733,7 +1733,19 @@ struct cipher_algo { int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo); struct cipher_algo *image_get_cipher_algo(const char *full_name); +struct andr_image_data; +/** + * android_image_get_data() - Parse Android boot image + * + * This is used to parse boot image header into andr_image_data + * generic structure. + * + * @boot_hdr: Pointer to boot image header + * @data: Pointer to generic boot format structure + * Return: true if succeeded, false otherwise + */ +bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data); struct andr_boot_img_hdr_v0; /** -- cgit v1.3.1 From e058176be32b09ca4f787442fd99d29e44079519 Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:11 +0100 Subject: android: boot: add vendor boot image to prepare for v3, v4 support Introduce vendor boot image for version 3 and 4 of boot image header. The vendor boot image will hold extra information about kernel, dtb and ramdisk. This is done to prepare for boot image version 3 and 4 support. Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/bootm.c | 8 ++++---- boot/image-android.c | 54 ++++++++++++++++++++++++++++++++++------------------ boot/image-board.c | 3 +-- boot/image-fdt.c | 3 ++- cmd/abootimg.c | 4 ++-- include/image.h | 48 +++++++++++++++++++++++++++++++++++----------- 6 files changed, 81 insertions(+), 39 deletions(-) (limited to 'include') diff --git a/boot/bootm.c b/boot/bootm.c index 2eec60ec7b5..28a8fc32612 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -182,11 +182,11 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: images.os.type = IH_TYPE_KERNEL; - images.os.comp = android_image_get_kcomp(os_hdr); + images.os.comp = android_image_get_kcomp(os_hdr, NULL); images.os.os = IH_OS_LINUX; - images.os.end = android_image_get_end(os_hdr); - images.os.load = android_image_get_kload(os_hdr); + images.os.end = android_image_get_end(os_hdr, NULL); + images.os.load = android_image_get_kload(os_hdr, NULL); images.ep = images.os.load; ep_found = true; break; @@ -965,7 +965,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: printf("## Booting Android Image at 0x%08lx ...\n", img_addr); - if (android_image_get_kernel(buf, images->verify, + if (android_image_get_kernel(buf, NULL, images->verify, os_data, os_len)) return NULL; break; diff --git a/boot/image-android.c b/boot/image-android.c index 748fd212ae6..f16eebff49e 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -66,7 +66,8 @@ static void android_boot_image_v0_v1_v2_parse_hdr(const struct andr_boot_img_hdr data->boot_img_total_size = end - (ulong)hdr; } -bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data) +bool android_image_get_data(const void *boot_hdr, const void *vendor_boot_hdr, + struct andr_image_data *data) { if (!boot_hdr || !data) { printf("boot_hdr or data params can't be NULL\n"); @@ -114,8 +115,10 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data) /** * android_image_get_kernel() - processes kernel part of Android boot images - * @hdr: Pointer to image header, which is at the start + * @hdr: Pointer to boot image header, which is at the start * of the image. + * @vendor_boot_img: Pointer to vendor boot image header, which is at the + * start of the image. * @verify: Checksum verification flag. Currently unimplemented. * @os_data: Pointer to a ulong variable, will hold os data start * address. @@ -127,14 +130,15 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data) * Return: Zero, os start address and length on success, * otherwise on failure. */ -int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, +int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img, int verify, ulong *os_data, ulong *os_len) { struct andr_image_data img_data = {0}; u32 kernel_addr; const struct legacy_img_hdr *ihdr; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; kernel_addr = android_image_get_kernel_addr(&img_data); @@ -201,11 +205,12 @@ bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr) return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); } -ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img) { struct andr_image_data img_data; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; if (img_data.header_version > 2) @@ -214,22 +219,24 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) return img_data.boot_img_total_size; } -ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr) +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img) { struct andr_image_data img_data; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; return android_image_get_kernel_addr(&img_data); } -ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr) +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img) { struct andr_image_data img_data; const void *p; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; p = (const void *)img_data.kernel_ptr; @@ -242,11 +249,11 @@ ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr) } int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, - ulong *rd_data, ulong *rd_len) + const void *vendor_boot_img, ulong *rd_data, ulong *rd_len) { struct andr_image_data img_data = {0}; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; if (!img_data.ramdisk_size) { @@ -268,7 +275,7 @@ int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, { struct andr_image_data img_data; - if (!android_image_get_data(hdr, &img_data)) + if (!android_image_get_data(hdr, NULL, &img_data)) return -EINVAL; if (!img_data.second_size) { @@ -348,11 +355,12 @@ exit: /** * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image. * @hdr_addr: Boot image header address + * @vhdr_addr: Vendor Boot image header address * @addr: Will contain the address of DTB area in boot image * * Return: true on success or false on fail. */ -static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr) +static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulong *addr) { const struct andr_boot_img_hdr_v0 *hdr; ulong dtb_img_addr; @@ -395,6 +403,7 @@ exit: /** * android_image_get_dtb_by_index() - Get address and size of blob in DTB area. * @hdr_addr: Boot image header address + * @vendor_boot_img: Pointer to vendor boot image header, which is at the start of the image. * @index: Index of desired DTB in DTB area (starting from 0) * @addr: If not NULL, will contain address to specified DTB * @size: If not NULL, will contain size of specified DTB @@ -404,17 +413,24 @@ exit: * * Return: true on success or false on error. */ -bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, - u32 *size) +bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, + u32 index, ulong *addr, u32 *size) { struct andr_image_data img_data; const struct andr_boot_img_hdr_v0 *hdr; + const struct andr_vnd_boot_img_hdr *vhdr; hdr = map_sysmem(hdr_addr, sizeof(*hdr)); - if (!android_image_get_data(hdr, &img_data)) { + if (vendor_boot_img != -1) + vhdr = map_sysmem(vendor_boot_img, sizeof(*vhdr)); + if (!android_image_get_data(hdr, vhdr, &img_data)) { + if (vendor_boot_img != -1) + unmap_sysmem(vhdr); unmap_sysmem(hdr); return false; } + if (vendor_boot_img != -1) + unmap_sysmem(vhdr); unmap_sysmem(hdr); ulong dtb_img_addr; /* address of DTB part in boot image */ @@ -422,7 +438,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, ulong dtb_addr; /* address of DTB blob with specified index */ u32 i; /* index iterator */ - android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr); + android_image_get_dtb_img_addr(hdr_addr, vendor_boot_img, &dtb_img_addr); /* Check if DTB area of boot image is in DTBO format */ if (android_dt_check_header(dtb_img_addr)) { return android_dt_get_fdt_by_index(dtb_img_addr, index, addr, @@ -578,7 +594,7 @@ bool android_image_print_dtb_contents(ulong hdr_addr) ulong dtb_addr; /* address of DTB blob with specified index */ u32 i; /* index iterator */ - res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr); + res = android_image_get_dtb_img_addr(hdr_addr, 0, &dtb_img_addr); if (!res) return false; diff --git a/boot/image-board.c b/boot/image-board.c index e086103258f..2d73c76a4af 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -428,8 +428,7 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { void *ptr = map_sysmem(images->os.start, 0); int ret; - - ret = android_image_get_ramdisk(ptr, rd_datap, rd_lenp); + ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp); unmap_sysmem(ptr); if (ret) return ret; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index ba44ecf8ef3..d639f37896a 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -536,7 +536,8 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, * Firstly check if this android boot image has dtb field. */ dtb_idx = (u32)env_get_ulong("adtb_idx", 10, 0); - if (android_image_get_dtb_by_index((ulong)hdr, dtb_idx, &fdt_addr, &fdt_size)) { + if (android_image_get_dtb_by_index((ulong)hdr, 0, + dtb_idx, &fdt_addr, &fdt_size)) { fdt_blob = (char *)map_sysmem(fdt_addr, 0); if (fdt_check_header(fdt_blob)) goto no_fdt; diff --git a/cmd/abootimg.c b/cmd/abootimg.c index f04a7c7c8e6..4d6cf0fa3eb 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -72,7 +72,7 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) const struct andr_boot_img_hdr_v0 *hdr; hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); - if (!android_image_get_data(hdr, &img_data)) { + if (!android_image_get_data(hdr, NULL, &img_data)) { unmap_sysmem(hdr); return CMD_RET_FAILURE; } @@ -119,7 +119,7 @@ static int abootimg_get_dtb_by_index(int argc, char *const argv[]) return CMD_RET_FAILURE; } - if (!android_image_get_dtb_by_index(abootimg_addr(), num, + if (!android_image_get_dtb_by_index(abootimg_addr(), 0, num, &addr, &size)) { return CMD_RET_FAILURE; } diff --git a/include/image.h b/include/image.h index 4bf6c98ced7..f84c03f08fb 100644 --- a/include/image.h +++ b/include/image.h @@ -1736,16 +1736,19 @@ struct cipher_algo *image_get_cipher_algo(const char *full_name); struct andr_image_data; /** - * android_image_get_data() - Parse Android boot image + * android_image_get_data() - Parse Android boot images * - * This is used to parse boot image header into andr_image_data - * generic structure. + * This is used to parse boot and vendor-boot header into + * andr_image_data generic structure. * * @boot_hdr: Pointer to boot image header + * @vendor_boot_hdr: Pointer to vendor boot image header * @data: Pointer to generic boot format structure * Return: true if succeeded, false otherwise */ -bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data); +bool android_image_get_data(const void *boot_hdr, const void *vendor_boot_hdr, + struct andr_image_data *data); + struct andr_boot_img_hdr_v0; /** @@ -1756,6 +1759,7 @@ struct andr_boot_img_hdr_v0; * * @hdr: Pointer to image header, which is at the start * of the image. + * @vendor_boot_img : Pointer to vendor boot image header * @verify: Checksum verification flag. Currently unimplemented. * @os_data: Pointer to a ulong variable, will hold os data start * address. @@ -1763,7 +1767,8 @@ struct andr_boot_img_hdr_v0; * Return: Zero, os start address and length on success, * otherwise on failure. */ -int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, +int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img, int verify, ulong *os_data, ulong *os_len); /** @@ -1772,12 +1777,13 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, * This extracts the load address of the ramdisk and its size * * @hdr: Pointer to image header + * @vendor_boot_img : Pointer to vendor boot image header * @rd_data: Pointer to a ulong variable, will hold ramdisk address * @rd_len: Pointer to a ulong variable, will hold ramdisk length * Return: 0 if succeeded, -1 if ramdisk size is 0 */ int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, - ulong *rd_data, ulong *rd_len); + const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); /** * android_image_get_second() - Extracts the secondary bootloader address @@ -1793,8 +1799,22 @@ int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, ulong *second_data, ulong *second_len); bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size); -bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, - u32 *size); + +/** + * android_image_get_dtb_by_index() - Get address and size of blob in DTB area. + * @hdr_addr: Boot image header address + * @vendor_boot_img: Pointer to vendor boot image header, which is at the start of the image. + * @index: Index of desired DTB in DTB area (starting from 0) + * @addr: If not NULL, will contain address to specified DTB + * @size: If not NULL, will contain size of specified DTB + * + * Get the address and size of DTB blob by its index in DTB area of Android + * Boot Image in RAM. + * + * Return: true on success or false on error. + */ +bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, + u32 index, ulong *addr, u32 *size); /** * android_image_get_end() - Get the end of Android boot image @@ -1802,9 +1822,11 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, * This returns the end address of Android boot image address * * @hdr: Pointer to image header + * @vendor_boot_img : Pointer to vendor boot image header * Return: The end address of Android boot image */ -ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); /** * android_image_get_kload() - Get the kernel load address @@ -1813,9 +1835,11 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); * from the boot image header or the "kernel_addr_r" environment variable * * @hdr: Pointer to image header + * @vendor_boot_img : Pointer to vendor boot image header * Return: The kernel load address */ -ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr); +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); /** * android_image_get_kcomp() - Get kernel compression type @@ -1823,9 +1847,11 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr); * This gets the kernel compression type from the boot image header * * @hdr: Pointer to image header + * @vendor_boot_img : Pointer to vendor boot image header * Return: Kernel compression type */ -ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr); +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); /** * android_print_contents() - Prints out the contents of the Android format image -- cgit v1.3.1 From 1115027d2f75ade805f0d4d44a6a2c21e74ea6b2 Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:12 +0100 Subject: android: boot: update android_image_get_data to support v3, v4 Since boot image header version 3 and 4 introduced vendor boot image, use the following functions to fill the generic android structure : andr_image_data: - android_boot_image_v3_v4_parse_hdr() - android_vendor_boot_image_v3_v4_parse_hdr() Update android_image_get_data() to support v3 and v4 Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/image-android.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 3 ++ include/image.h | 11 +++++++ 3 files changed, 91 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/boot/image-android.c b/boot/image-android.c index f16eebff49e..712d437766b 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -18,6 +18,65 @@ static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; +static void android_boot_image_v3_v4_parse_hdr(const struct andr_boot_img_hdr_v3 *hdr, + struct andr_image_data *data) +{ + ulong end; + + data->kcmdline = hdr->cmdline; + data->header_version = hdr->header_version; + + /* + * The header takes a full page, the remaining components are aligned + * on page boundary. + */ + end = (ulong)hdr; + end += ANDR_GKI_PAGE_SIZE; + data->kernel_ptr = end; + data->kernel_size = hdr->kernel_size; + end += ALIGN(hdr->kernel_size, ANDR_GKI_PAGE_SIZE); + data->ramdisk_size = hdr->ramdisk_size; + data->boot_ramdisk_size = hdr->ramdisk_size; + end += ALIGN(hdr->ramdisk_size, ANDR_GKI_PAGE_SIZE); + + if (hdr->header_version > 3) + end += ALIGN(hdr->signature_size, ANDR_GKI_PAGE_SIZE); + + data->boot_img_total_size = end - (ulong)hdr; +} + +static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vnd_boot_img_hdr + *hdr, struct andr_image_data *data) +{ + ulong end; + + /* + * The header takes a full page, the remaining components are aligned + * on page boundary. + */ + data->tags_addr = hdr->tags_addr; + data->image_name = hdr->name; + data->kernel_addr = hdr->kernel_addr; + data->ramdisk_addr = hdr->ramdisk_addr; + data->dtb_load_addr = hdr->dtb_addr; + end = (ulong)hdr; + end += hdr->page_size; + if (hdr->vendor_ramdisk_size) { + data->vendor_ramdisk_ptr = end; + data->vendor_ramdisk_size = hdr->vendor_ramdisk_size; + data->ramdisk_size += hdr->vendor_ramdisk_size; + end += ALIGN(hdr->vendor_ramdisk_size, hdr->page_size); + } + + data->dtb_ptr = end; + data->dtb_size = hdr->dtb_size; + + end += ALIGN(hdr->dtb_size, hdr->page_size); + end += ALIGN(hdr->vendor_ramdisk_table_size, hdr->page_size); + end += ALIGN(hdr->bootconfig_size, hdr->page_size); + data->vendor_boot_img_total_size = end - (ulong)hdr; +} + static void android_boot_image_v0_v1_v2_parse_hdr(const struct andr_boot_img_hdr_v0 *hdr, struct andr_image_data *data) { @@ -79,10 +138,20 @@ bool android_image_get_data(const void *boot_hdr, const void *vendor_boot_hdr, return false; } - if (((struct andr_boot_img_hdr_v0 *)boot_hdr)->header_version > 2) - printf("Only boot image header version 2 and below are supported\n"); - else + if (((struct andr_boot_img_hdr_v0 *)boot_hdr)->header_version > 2) { + if (!vendor_boot_hdr) { + printf("For boot header v3+ vendor boot image has to be provided\n"); + return false; + } + if (!is_android_vendor_boot_image_header(vendor_boot_hdr)) { + printf("Incorrect vendor boot image header\n"); + return false; + } + android_boot_image_v3_v4_parse_hdr(boot_hdr, data); + android_vendor_boot_image_v3_v4_parse_hdr(vendor_boot_hdr, data); + } else { android_boot_image_v0_v1_v2_parse_hdr(boot_hdr, data); + } return true; } @@ -200,6 +269,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, return 0; } +bool is_android_vendor_boot_image_header(const void *vendor_boot_img) +{ + return !memcmp(VENDOR_BOOT_MAGIC, vendor_boot_img, ANDR_VENDOR_BOOT_MAGIC_SIZE); +} + bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr) { return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); diff --git a/include/android_image.h b/include/android_image.h index fb3a9d9858b..99e78035082 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -323,6 +323,8 @@ 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 */ @@ -342,6 +344,7 @@ struct andr_image_data { 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 diff --git a/include/image.h b/include/image.h index f84c03f08fb..c2e751c1364 100644 --- a/include/image.h +++ b/include/image.h @@ -1876,6 +1876,17 @@ bool android_image_print_dtb_contents(ulong hdr_addr); */ bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +/** + * is_android_vendor_boot_image_header() - Check the magic of vendor boot image + * + * This checks the header of Android vendor boot image and verifies the magic + * is "VNDRBOOT" + * + * @vendor_boot_img: Pointer to boot image + * Return: non-zero if the magic is correct, zero otherwise + */ +bool is_android_vendor_boot_image_header(const void *vendor_boot_img); + /** * board_fit_config_name_match() - Check for a matching board name * -- cgit v1.3.1 From c79a2e6823d5a3a2813f66d03023c0a192c27e7e Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:13 +0100 Subject: android: boot: ramdisk: support vendor ramdisk Version 3 and 4 of boot image header introduced vendor boot ramdisk: Please check include/android_image.h for details. The ramdisk is now split into a generic ramdisk in boot image and a vendor ramdisk in vendor boot image. Support the new vendor ramdisk. Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/image-android.c | 13 +++++++++++-- include/image.h | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/boot/image-android.c b/boot/image-android.c index 712d437766b..35243fd5b16 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -25,6 +25,7 @@ static void android_boot_image_v3_v4_parse_hdr(const struct andr_boot_img_hdr_v3 data->kcmdline = hdr->cmdline; data->header_version = hdr->header_version; + data->ramdisk_ptr = env_get_ulong("ramdisk_addr_r", 16, 0); /* * The header takes a full page, the remaining components are aligned @@ -322,10 +323,11 @@ ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, return image_decomp_type(p, sizeof(u32)); } -int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, - const void *vendor_boot_img, ulong *rd_data, ulong *rd_len) +int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, + ulong *rd_data, ulong *rd_len) { struct andr_image_data img_data = {0}; + ulong ramdisk_ptr; if (!android_image_get_data(hdr, vendor_boot_img, &img_data)) return -EINVAL; @@ -334,6 +336,13 @@ int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, *rd_data = *rd_len = 0; return -1; } + if (img_data.header_version > 2) { + ramdisk_ptr = img_data.ramdisk_ptr; + memcpy((void *)(ramdisk_ptr), (void *)img_data.vendor_ramdisk_ptr, + img_data.vendor_ramdisk_size); + memcpy((void *)(ramdisk_ptr + img_data.vendor_ramdisk_size), + (void *)img_data.ramdisk_ptr, img_data.boot_ramdisk_size); + } printf("RAM disk load addr 0x%08lx size %u KiB\n", img_data.ramdisk_ptr, DIV_ROUND_UP(img_data.ramdisk_size, 1024)); diff --git a/include/image.h b/include/image.h index c2e751c1364..c4d9b1c5754 100644 --- a/include/image.h +++ b/include/image.h @@ -1782,8 +1782,8 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, * @rd_len: Pointer to a ulong variable, will hold ramdisk length * Return: 0 if succeeded, -1 if ramdisk size is 0 */ -int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, - const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); +int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, + ulong *rd_data, ulong *rd_len); /** * android_image_get_second() - Extracts the secondary bootloader address -- cgit v1.3.1 From 636da2039aea4ea3a638b14da0a9ec258897a10c Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:17 +0100 Subject: android: boot: support boot image header version 3 and 4 Enable the support for boot image header version 3 and 4 using abootimg command. In order to use version 3 or 4: 1- Vendor boot image address should be given to abootimg cmd. abootimg addr $1 $vendor_boot_load_addr 2- "ramdisk_addr_r" env variable (ramdisk address) should be set to host the ramdisk : generic ramdisk + vendor ramdisk Replace "struct andr_boot_img_hdr_v0*" by "void *" in some functions since v3 and v4 are now supported as well. Signed-off-by: Safae Ouajih Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/bootm.c | 37 ++++++++++++++++++++++++++++++++----- boot/image-android.c | 16 ++++++++++------ boot/image-board.c | 18 +++++++++++++++--- boot/image-fdt.c | 2 +- cmd/abootimg.c | 24 ++++++++++++++++++++++-- include/image.h | 25 +++++++++++++++++++------ 6 files changed, 99 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/boot/bootm.c b/boot/bootm.c index 28a8fc32612..4144ff3b031 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -113,6 +113,10 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { const void *os_hdr; +#ifdef CONFIG_ANDROID_BOOT_IMAGE + const void *vendor_boot_img; + const void *boot_img; +#endif bool ep_found = false; int ret; @@ -181,14 +185,23 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: + boot_img = os_hdr; + vendor_boot_img = NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + boot_img = map_sysmem(get_abootimg_addr(), 0); + vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + } images.os.type = IH_TYPE_KERNEL; - images.os.comp = android_image_get_kcomp(os_hdr, NULL); + images.os.comp = android_image_get_kcomp(boot_img, vendor_boot_img); images.os.os = IH_OS_LINUX; - - images.os.end = android_image_get_end(os_hdr, NULL); - images.os.load = android_image_get_kload(os_hdr, NULL); + images.os.end = android_image_get_end(boot_img, vendor_boot_img); + images.os.load = android_image_get_kload(boot_img, vendor_boot_img); images.ep = images.os.load; ep_found = true; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + unmap_sysmem(vendor_boot_img); + unmap_sysmem(boot_img); + } break; #endif default: @@ -889,6 +902,10 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, int os_noffset; #endif +#ifdef CONFIG_ANDROID_BOOT_IMAGE + const void *boot_img; + const void *vendor_boot_img; +#endif img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0], &fit_uname_config, &fit_uname_kernel); @@ -964,10 +981,20 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: + boot_img = buf; + vendor_boot_img = NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + boot_img = map_sysmem(get_abootimg_addr(), 0); + vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + } printf("## Booting Android Image at 0x%08lx ...\n", img_addr); - if (android_image_get_kernel(buf, NULL, images->verify, + if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify, os_data, os_len)) return NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + unmap_sysmem(vendor_boot_img); + unmap_sysmem(boot_img); + } break; #endif default: diff --git a/boot/image-android.c b/boot/image-android.c index 6be439ed12b..fb29ff403f9 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -201,7 +201,7 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data) * Return: Zero, os start address and length on success, * otherwise on failure. */ -int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, +int android_image_get_kernel(const void *hdr, const void *vendor_boot_img, int verify, ulong *os_data, ulong *os_len) { @@ -286,7 +286,7 @@ bool is_android_vendor_boot_image_header(const void *vendor_boot_img) return !memcmp(VENDOR_BOOT_MAGIC, vendor_boot_img, ANDR_VENDOR_BOOT_MAGIC_SIZE); } -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr) +bool is_android_boot_image_header(const void *hdr) { return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); } @@ -305,7 +305,7 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, return img_data.boot_img_total_size; } -ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, +ulong android_image_get_kload(const void *hdr, const void *vendor_boot_img) { struct andr_image_data img_data; @@ -316,7 +316,7 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, return android_image_get_kernel_addr(&img_data); } -ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, +ulong android_image_get_kcomp(const void *hdr, const void *vendor_boot_img) { struct andr_image_data img_data; @@ -364,14 +364,18 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, return 0; } -int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, - ulong *second_data, ulong *second_len) +int android_image_get_second(const void *hdr, ulong *second_data, ulong *second_len) { struct andr_image_data img_data; if (!android_image_get_data(hdr, NULL, &img_data)) return -EINVAL; + if (img_data.header_version > 2) { + printf("Second stage bootloader is only supported for boot image version <= 2\n"); + return -EOPNOTSUPP; + } + if (!img_data.second_size) { *second_data = *second_len = 0; return -1; diff --git a/boot/image-board.c b/boot/image-board.c index 2d73c76a4af..7dd0c32e6e1 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -426,10 +426,22 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a break; case IMAGE_FORMAT_ANDROID: if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { - void *ptr = map_sysmem(images->os.start, 0); int ret; - ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp); - unmap_sysmem(ptr); + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + void *boot_img = map_sysmem(get_abootimg_addr(), 0); + void *vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + + ret = android_image_get_ramdisk(boot_img, vendor_boot_img, + rd_datap, rd_lenp); + unmap_sysmem(vendor_boot_img); + unmap_sysmem(boot_img); + } else { + void *ptr = map_sysmem(images->os.start, 0); + + ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp); + unmap_sysmem(ptr); + } + if (ret) return ret; done = true; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index d639f37896a..f10200f6474 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -529,7 +529,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, } #ifdef CONFIG_ANDROID_BOOT_IMAGE } else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { - struct andr_boot_img_hdr_v0 *hdr = buf; + void *hdr = buf; ulong fdt_data, fdt_len; u32 fdt_size, dtb_idx; /* diff --git a/cmd/abootimg.c b/cmd/abootimg.c index 4d6cf0fa3eb..2653b555b10 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -17,6 +17,16 @@ static ulong _abootimg_addr = -1; static ulong _avendor_bootimg_addr = -1; +ulong get_abootimg_addr(void) +{ + return (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr); +} + +ulong get_avendor_bootimg_addr(void) +{ + return _avendor_bootimg_addr; +} + static int abootimg_get_ver(int argc, char *const argv[]) { const struct andr_boot_img_hdr_v0 *hdr; @@ -70,12 +80,21 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) return CMD_RET_USAGE; struct andr_image_data img_data = {0}; const struct andr_boot_img_hdr_v0 *hdr; + const struct andr_vnd_boot_img_hdr *vhdr; hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); - if (!android_image_get_data(hdr, NULL, &img_data)) { + if (get_avendor_bootimg_addr() != -1) + vhdr = map_sysmem(get_avendor_bootimg_addr(), sizeof(*vhdr)); + + if (!android_image_get_data(hdr, vhdr, &img_data)) { + if (get_avendor_bootimg_addr() != -1) + unmap_sysmem(vhdr); unmap_sysmem(hdr); return CMD_RET_FAILURE; } + + if (get_avendor_bootimg_addr() != -1) + unmap_sysmem(vhdr); unmap_sysmem(hdr); if (img_data.header_version < 2) { @@ -119,7 +138,8 @@ static int abootimg_get_dtb_by_index(int argc, char *const argv[]) return CMD_RET_FAILURE; } - if (!android_image_get_dtb_by_index(abootimg_addr(), 0, num, + if (!android_image_get_dtb_by_index(abootimg_addr(), + get_avendor_bootimg_addr(), num, &addr, &size)) { return CMD_RET_FAILURE; } diff --git a/include/image.h b/include/image.h index c4d9b1c5754..456197d6fda 100644 --- a/include/image.h +++ b/include/image.h @@ -1767,7 +1767,7 @@ struct andr_boot_img_hdr_v0; * Return: Zero, os start address and length on success, * otherwise on failure. */ -int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, +int android_image_get_kernel(const void *hdr, const void *vendor_boot_img, int verify, ulong *os_data, ulong *os_len); @@ -1796,8 +1796,7 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, * @second_len : Pointer to a ulong variable, will hold secondary bootloader length * Return: 0 if succeeded, -1 if secondary bootloader size is 0 */ -int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, - ulong *second_data, ulong *second_len); +int android_image_get_second(const void *hdr, ulong *second_data, ulong *second_len); bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size); /** @@ -1838,7 +1837,7 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, * @vendor_boot_img : Pointer to vendor boot image header * Return: The kernel load address */ -ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, +ulong android_image_get_kload(const void *hdr, const void *vendor_boot_img); /** @@ -1850,7 +1849,7 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, * @vendor_boot_img : Pointer to vendor boot image header * Return: Kernel compression type */ -ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, +ulong android_image_get_kcomp(const void *hdr, const void *vendor_boot_img); /** @@ -1874,7 +1873,7 @@ bool android_image_print_dtb_contents(ulong hdr_addr); * @hdr: Pointer to boot image * Return: non-zero if the magic is correct, zero otherwise */ -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +bool is_android_boot_image_header(const void *hdr); /** * is_android_vendor_boot_image_header() - Check the magic of vendor boot image @@ -1887,6 +1886,20 @@ bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); */ bool is_android_vendor_boot_image_header(const void *vendor_boot_img); +/** + * get_abootimg_addr() - Get Android boot image address + * + * Return: Android boot image address + */ +ulong get_abootimg_addr(void); + +/** + * get_avendor_bootimg_addr() - Get Android vendor boot image address + * + * Return: Android vendor boot image address + */ +ulong get_avendor_bootimg_addr(void); + /** * board_fit_config_name_match() - Check for a matching board name * -- cgit v1.3.1 From 57e405e1f4745cdca49a4a6b260afe68592b1d5c Mon Sep 17 00:00:00 2001 From: Safae Ouajih Date: Mon, 6 Feb 2023 00:50:18 +0100 Subject: android: boot: support bootconfig Support Bootconfig feature. - The bootconfig feature replaces the androidboot.* kernel cmdline options. This was adapted from downstream [1] commit : 7af0a0506d4d ("cuttlefish: support bootconfig parameters"). Link:[1] https://android.googlesource.com/platform/external/u-boot/ Signed-off-by: Safae Ouajih Reviewed-by: Simon Glass Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek --- boot/image-android.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 11 ++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/boot/image-android.c b/boot/image-android.c index fb29ff403f9..88e40bc7ec6 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -18,6 +18,45 @@ static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; +static ulong checksum(const unsigned char *buffer, ulong size) +{ + ulong sum = 0; + + for (ulong i = 0; i < size; i++) + sum += buffer[i]; + return sum; +} + +static bool is_trailer_present(ulong bootconfig_end_addr) +{ + return !strncmp((char *)(bootconfig_end_addr - BOOTCONFIG_MAGIC_SIZE), + BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_SIZE); +} + +static ulong add_trailer(ulong bootconfig_start_addr, ulong bootconfig_size) +{ + ulong end; + ulong sum; + + if (!bootconfig_start_addr) + return -1; + if (!bootconfig_size) + return 0; + + end = bootconfig_start_addr + bootconfig_size; + if (is_trailer_present(end)) + return 0; + + memcpy((void *)(end), &bootconfig_size, BOOTCONFIG_SIZE_SIZE); + sum = checksum((unsigned char *)bootconfig_start_addr, bootconfig_size); + memcpy((void *)(end + BOOTCONFIG_SIZE_SIZE), &sum, + BOOTCONFIG_CHECKSUM_SIZE); + memcpy((void *)(end + BOOTCONFIG_SIZE_SIZE + BOOTCONFIG_CHECKSUM_SIZE), + BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_SIZE); + + return BOOTCONFIG_TRAILER_SIZE; +} + static void android_boot_image_v3_v4_parse_hdr(const struct andr_boot_img_hdr_v3 *hdr, struct andr_image_data *data) { @@ -61,6 +100,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vnd_boot data->kernel_addr = hdr->kernel_addr; data->ramdisk_addr = hdr->ramdisk_addr; data->dtb_load_addr = hdr->dtb_addr; + data->bootconfig_size = hdr->bootconfig_size; end = (ulong)hdr; end += hdr->page_size; if (hdr->vendor_ramdisk_size) { @@ -75,7 +115,13 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vnd_boot end += ALIGN(hdr->dtb_size, hdr->page_size); end += ALIGN(hdr->vendor_ramdisk_table_size, hdr->page_size); - end += ALIGN(hdr->bootconfig_size, hdr->page_size); + data->bootconfig_addr = end; + if (hdr->bootconfig_size) { + data->bootconfig_size += add_trailer(data->bootconfig_addr, + data->bootconfig_size); + data->ramdisk_size += data->bootconfig_size; + } + end += ALIGN(data->bootconfig_size, hdr->page_size); data->vendor_boot_img_total_size = end - (ulong)hdr; } @@ -352,7 +398,15 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, memcpy((void *)(ramdisk_ptr), (void *)img_data.vendor_ramdisk_ptr, img_data.vendor_ramdisk_size); memcpy((void *)(ramdisk_ptr + img_data.vendor_ramdisk_size), - (void *)img_data.ramdisk_ptr, img_data.boot_ramdisk_size); + (void *)img_data.ramdisk_ptr, + img_data.boot_ramdisk_size); + if (img_data.bootconfig_size) { + memcpy((void *) + (ramdisk_ptr + img_data.vendor_ramdisk_size + + img_data.boot_ramdisk_size), + (void *)img_data.bootconfig_addr, + img_data.bootconfig_size); + } } printf("RAM disk load addr 0x%08lx size %u KiB\n", diff --git a/include/android_image.h b/include/android_image.h index 99e78035082..d503c980b23 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -25,6 +25,14 @@ #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]; @@ -337,6 +345,9 @@ struct andr_image_data { 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 */ + u32 kernel_addr; /* physical load addr */ ulong ramdisk_addr; /* physical load addr */ ulong ramdisk_ptr; /* ramdisk address */ -- cgit v1.3.1