[PATCH v2 00/17] Support android boot image v3/v4

Hello everyone,
* This is based on Roman Stratiienko's work to support boot image header version 3 and 4.
* This supports the new boot image headers v3, v4 and bootconfig feature. https://source.android.com/docs/core/architecture/bootloader/boot-image-head... https://source.android.com/docs/core/architecture/bootloader/implementing-bo...
- Tested on Amlogic Khadas vim3l, a reference board for Android Open Source Project https://www.khadas.com/vim3l
And on AM625 Texas Instruments board with 5.10 linux kernel
Main changes : - New partition : vendor boot, with a specific vendor ramdisk - DTB is stored in the vendor boot partition - The generic ramdisk is placed after the vendor ramdisk - Bootconfig feature support
Here is a link to see the related android boot flow changes on KHADAS vim3l as an example: https://gitlab.baylibre.com/baylibre/amlogic/atv/u-boot/-/commits/souajih/Bo...
Changes in v2: - Rework parts of the code to fix the abootimg test: test_abootimg - Update test_abootimg to support boot image header v4 - Remove LIBXBC library, import and adapt the functions to support bootconfig feature - Rename the used structures : andr_boot_img_hdr_v0_v1_v2 -> andr_boot_img_hdr_v0 andr_boot_img_hdr_v3_v4 -> andr_boot_img_hdr_v3 andr_vendor_boot_img_hdr_v3_v4 -> andr_vendor_img_hdr
Safae Ouajih (17): android: boot: rename andr_img_hdr -> andr_boot_img_hdr_v0 android: boot: support vendor boot image in abootimg android: boot: replace android_image_check_header android: boot: add boot image header v3 and v4 structures android: boot: kcomp: support andr_image_data android: boot: move to andr_image_data structure android: boot: content print is not supported for v3,v4 header version android: boot: boot image header v3,v4 do not support recovery DTBO android: boot: add vendor boot image to prepare for v3,v4 support android: boot: update android_image_get_data to support v3,v4 android: boot: ramdisk: support vendor ramdisk android: boot: support extra command line android: boot: update android_image_get_dtb_img_addr to support v3,v4 drivers: fastboot: zImage flashing is not supported for v3,v4 android: boot: support boot image header version 3 and 4 android: boot: support bootconfig test/py: android: extend abootimg test
boot/bootm.c | 29 +- boot/image-android.c | 467 ++++++++++++++++---- boot/image-board.c | 15 +- boot/image-fdt.c | 5 +- cmd/abootimg.c | 75 +++- drivers/fastboot/fb_mmc.c | 19 +- include/android_image.h | 228 +++++++++- include/image.h | 37 +- test/py/tests/test_android/test_abootimg.py | 135 +++++- 9 files changed, 850 insertions(+), 160 deletions(-)
-- 2.34.1

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)
To maintain support for version v0, v1 and v2 while introducing version 3 and 4, this struct name must change to refer to the header structure before v3.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 26 +++++++++++++------------- boot/image-fdt.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 8 ++++---- include/android_image.h | 4 ++-- include/image.h | 18 +++++++++--------- 6 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 2628db3741..8c0a304cc0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -18,7 +18,7 @@
static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
-static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) +static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hdr) { /* * All the Android tools that generate a boot.img use this @@ -59,7 +59,7 @@ static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) * Return: Zero, os start address and length on success, * otherwise on failure. */ -int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, +int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len) { u32 kernel_addr = android_image_get_kernel_addr(hdr); @@ -122,12 +122,12 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, return 0; }
-int android_image_check_header(const struct andr_img_hdr *hdr) +int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr) { return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); }
-ulong android_image_get_end(const struct andr_img_hdr *hdr) +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) { ulong end;
@@ -150,12 +150,12 @@ ulong android_image_get_end(const struct andr_img_hdr *hdr) return end; }
-ulong android_image_get_kload(const struct andr_img_hdr *hdr) +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr) { return android_image_get_kernel_addr(hdr); }
-ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr) { const void *p = (void *)((uintptr_t)hdr + hdr->page_size);
@@ -167,7 +167,7 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) return image_decomp_type(p, sizeof(u32)); }
-int android_image_get_ramdisk(const struct andr_img_hdr *hdr, +int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, ulong *rd_data, ulong *rd_len) { if (!hdr->ramdisk_size) { @@ -186,7 +186,7 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr, return 0; }
-int android_image_get_second(const struct andr_img_hdr *hdr, +int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, ulong *second_data, ulong *second_len) { if (!hdr->second_size) { @@ -226,7 +226,7 @@ int android_image_get_second(const struct andr_img_hdr *hdr, */ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; ulong dtbo_img_addr; bool ret = true;
@@ -275,7 +275,7 @@ exit: */ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; ulong dtb_img_addr; bool ret = true;
@@ -328,7 +328,7 @@ exit: bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, u32 *size) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; bool res; ulong dtb_img_addr; /* address of DTB part in boot image */ u32 dtb_img_size; /* size of DTB payload in boot image */ @@ -393,7 +393,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, * returns: * no returned results */ -void android_print_contents(const struct andr_img_hdr *hdr) +void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr) { const char * const p = IMAGE_INDENT_STRING; /* os_version = ver << 11 | lvl */ @@ -485,7 +485,7 @@ static bool android_image_print_dtb_info(const struct fdt_header *fdt, */ bool android_image_print_dtb_contents(ulong hdr_addr) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; bool res; ulong dtb_img_addr; /* address of DTB part in boot image */ u32 dtb_img_size; /* size of DTB payload in boot image */ diff --git a/boot/image-fdt.c b/boot/image-fdt.c index b830a0ab41..1181cb60f0 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_img_hdr *hdr = buf; + struct andr_boot_img_hdr_v0 *hdr = buf; ulong fdt_data, fdt_len; u32 fdt_size, dtb_idx; /* diff --git a/cmd/abootimg.c b/cmd/abootimg.c index f48a9dcb02..0262adb1e5 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -18,7 +18,7 @@ static ulong _abootimg_addr = -1;
static int abootimg_get_ver(int argc, char *const argv[]) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; int res = CMD_RET_SUCCESS;
if (argc > 1) @@ -65,7 +65,7 @@ static int abootimg_get_recovery_dtbo(int argc, char *const argv[])
static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) { - const struct andr_img_hdr *hdr; + const struct andr_boot_img_hdr_v0 *hdr; int res = CMD_RET_SUCCESS;
if (argc > 1) diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index 033c510bc0..6d0112fdf4 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -287,7 +287,7 @@ static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer, */ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc, struct disk_partition *info, - struct andr_img_hdr *hdr, + struct andr_boot_img_hdr_v0 *hdr, char *response) { ulong sector_size; /* boot partition sector size */ @@ -296,7 +296,7 @@ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
/* Calculate boot image sectors count */ sector_size = info->blksz; - hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size); + hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_boot_img_hdr_v0), sector_size); if (hdr_sectors == 0) { pr_err("invalid number of boot sectors: 0\n"); fastboot_fail("invalid number of boot sectors: 0", response); @@ -338,7 +338,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc, char *response) { uintptr_t hdr_addr; /* boot image header address */ - struct andr_img_hdr *hdr; /* boot image header */ + struct andr_boot_img_hdr_v0 *hdr; /* boot image header */ lbaint_t hdr_sectors; /* boot image header sectors */ u8 *ramdisk_buffer; u32 ramdisk_sector_start; @@ -361,7 +361,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
/* Put boot image header in fastboot buffer after downloaded zImage */ hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE); - hdr = (struct andr_img_hdr *)hdr_addr; + hdr = (struct andr_boot_img_hdr_v0 *)hdr_addr;
/* Read boot image header */ hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response); diff --git a/include/android_image.h b/include/android_image.h index 54d25af068..2bdcab9122 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 7717a4c13d..bcb24d92de 100644 --- a/include/image.h +++ b/include/image.h @@ -1734,21 +1734,21 @@ 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; +int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); +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, +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, +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); +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); +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); +void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr);
/**

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
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)
To maintain support for version v0, v1 and v2 while introducing version 3 and 4, this struct name must change to refer to the header structure before v3.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 26 +++++++++++++------------- boot/image-fdt.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 8 ++++---- include/android_image.h | 4 ++-- include/image.h | 18 +++++++++--------- 6 files changed, 31 insertions(+), 31 deletions(-)
Please add full comments to the functions you change in image.h
With that:
Reviewed-by: Simon Glass sjg@chromium.org

On Thu, Jan 26, 2023 at 17:04, Safae Ouajih souajih@baylibre.com wrote:
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)
To maintain support for version v0, v1 and v2 while introducing version 3 and 4, this struct name must change to refer to the header structure before v3.
Signed-off-by: Safae Ouajih souajih@baylibre.com
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
boot/image-android.c | 26 +++++++++++++------------- boot/image-fdt.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 8 ++++---- include/android_image.h | 4 ++-- include/image.h | 18 +++++++++--------- 6 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 2628db3741..8c0a304cc0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -18,7 +18,7 @@
static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
-static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) +static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hdr) { /* * All the Android tools that generate a boot.img use this @@ -59,7 +59,7 @@ static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
- Return: Zero, os start address and length on success,
otherwise on failure.
*/ -int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, +int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len) { u32 kernel_addr = android_image_get_kernel_addr(hdr); @@ -122,12 +122,12 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, return 0; }
-int android_image_check_header(const struct andr_img_hdr *hdr) +int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr) { return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); }
-ulong android_image_get_end(const struct andr_img_hdr *hdr) +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) { ulong end;
@@ -150,12 +150,12 @@ ulong android_image_get_end(const struct andr_img_hdr *hdr) return end; }
-ulong android_image_get_kload(const struct andr_img_hdr *hdr) +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr) { return android_image_get_kernel_addr(hdr); }
-ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr) { const void *p = (void *)((uintptr_t)hdr + hdr->page_size);
@@ -167,7 +167,7 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) return image_decomp_type(p, sizeof(u32)); }
-int android_image_get_ramdisk(const struct andr_img_hdr *hdr, +int android_image_get_ramdisk(const struct andr_boot_img_hdr_v0 *hdr, ulong *rd_data, ulong *rd_len) { if (!hdr->ramdisk_size) { @@ -186,7 +186,7 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr, return 0; }
-int android_image_get_second(const struct andr_img_hdr *hdr, +int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, ulong *second_data, ulong *second_len) { if (!hdr->second_size) { @@ -226,7 +226,7 @@ int android_image_get_second(const struct andr_img_hdr *hdr, */ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) {
- const struct andr_img_hdr *hdr;
- const struct andr_boot_img_hdr_v0 *hdr; ulong dtbo_img_addr; bool ret = true;
@@ -275,7 +275,7 @@ exit: */ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr) {
- const struct andr_img_hdr *hdr;
- const struct andr_boot_img_hdr_v0 *hdr; ulong dtb_img_addr; bool ret = true;
@@ -328,7 +328,7 @@ exit: bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, u32 *size) {
- const struct andr_img_hdr *hdr;
- const struct andr_boot_img_hdr_v0 *hdr; bool res; ulong dtb_img_addr; /* address of DTB part in boot image */ u32 dtb_img_size; /* size of DTB payload in boot image */
@@ -393,7 +393,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr,
- returns:
no returned results
*/ -void android_print_contents(const struct andr_img_hdr *hdr) +void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr) { const char * const p = IMAGE_INDENT_STRING; /* os_version = ver << 11 | lvl */ @@ -485,7 +485,7 @@ static bool android_image_print_dtb_info(const struct fdt_header *fdt, */ bool android_image_print_dtb_contents(ulong hdr_addr) {
- const struct andr_img_hdr *hdr;
- const struct andr_boot_img_hdr_v0 *hdr; bool res; ulong dtb_img_addr; /* address of DTB part in boot image */ u32 dtb_img_size; /* size of DTB payload in boot image */
diff --git a/boot/image-fdt.c b/boot/image-fdt.c index b830a0ab41..1181cb60f0 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_img_hdr *hdr = buf;
ulong fdt_data, fdt_len; u32 fdt_size, dtb_idx; /*struct andr_boot_img_hdr_v0 *hdr = buf;
diff --git a/cmd/abootimg.c b/cmd/abootimg.c index f48a9dcb02..0262adb1e5 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -18,7 +18,7 @@ static ulong _abootimg_addr = -1;
static int abootimg_get_ver(int argc, char *const argv[]) {
- const struct andr_img_hdr *hdr;
const struct andr_boot_img_hdr_v0 *hdr; int res = CMD_RET_SUCCESS;
if (argc > 1)
@@ -65,7 +65,7 @@ static int abootimg_get_recovery_dtbo(int argc, char *const argv[])
static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) {
- const struct andr_img_hdr *hdr;
const struct andr_boot_img_hdr_v0 *hdr; int res = CMD_RET_SUCCESS;
if (argc > 1)
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index 033c510bc0..6d0112fdf4 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -287,7 +287,7 @@ static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer, */ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc, struct disk_partition *info,
struct andr_img_hdr *hdr,
struct andr_boot_img_hdr_v0 *hdr, char *response)
{ ulong sector_size; /* boot partition sector size */ @@ -296,7 +296,7 @@ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
/* Calculate boot image sectors count */ sector_size = info->blksz;
- hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
- hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_boot_img_hdr_v0), sector_size); if (hdr_sectors == 0) { pr_err("invalid number of boot sectors: 0\n"); fastboot_fail("invalid number of boot sectors: 0", response);
@@ -338,7 +338,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc, char *response) { uintptr_t hdr_addr; /* boot image header address */
- struct andr_img_hdr *hdr; /* boot image header */
- struct andr_boot_img_hdr_v0 *hdr; /* boot image header */ lbaint_t hdr_sectors; /* boot image header sectors */ u8 *ramdisk_buffer; u32 ramdisk_sector_start;
@@ -361,7 +361,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
/* Put boot image header in fastboot buffer after downloaded zImage */ hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
- hdr = (struct andr_img_hdr *)hdr_addr;
hdr = (struct andr_boot_img_hdr_v0 *)hdr_addr;
/* Read boot image header */ hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response);
diff --git a/include/android_image.h b/include/android_image.h index 54d25af068..2bdcab9122 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 7717a4c13d..bcb24d92de 100644 --- a/include/image.h +++ b/include/image.h @@ -1734,21 +1734,21 @@ 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; +int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); +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, +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, +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); +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); +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); +void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr);
/**
2.34.1

Vendor boot image is introduced in boot image header version 3 and 4. Please check [1] for more details.
To prepare for boot image v3/v4 support, allow the abootimg command to store the vendor_boot image address.
Full support for this new format will be done in a future patch.
Link:[1] https://source.android.com/docs/core/architecture/bootloader/partitions/vend...
Signed-off-by: Safae Ouajih souajih@baylibre.com --- cmd/abootimg.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/cmd/abootimg.c b/cmd/abootimg.c index 0262adb1e5..026c03f91c 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -15,6 +15,7 @@
/* Please use abootimg_addr() macro to obtain the boot image address */ static ulong _abootimg_addr = -1; +static ulong _avendor_bootimg_addr = -1;
static int abootimg_get_ver(int argc, char *const argv[]) { @@ -158,7 +159,7 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, int flag, int argc, char *endp; ulong img_addr;
- if (argc != 2) + if (argc < 2 || argc > 3) return CMD_RET_USAGE;
img_addr = hextoul(argv[1], &endp); @@ -168,6 +169,17 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, int flag, int argc, }
_abootimg_addr = img_addr; + + if (argc == 3) { + img_addr = simple_strtoul(argv[2], &endp, 16); + if (*endp != '\0') { + printf("Error: Wrong vendor image address\n"); + return CMD_RET_FAILURE; + } + + _avendor_bootimg_addr = img_addr; + } + return CMD_RET_SUCCESS; }
@@ -211,7 +223,7 @@ static int do_abootimg_dump(struct cmd_tbl *cmdtp, int flag, int argc, }
static struct cmd_tbl cmd_abootimg_sub[] = { - U_BOOT_CMD_MKENT(addr, 2, 1, do_abootimg_addr, "", ""), + U_BOOT_CMD_MKENT(addr, 3, 1, do_abootimg_addr, "", ""), U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""), U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""), }; @@ -239,7 +251,7 @@ static int do_abootimg(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_CMD( abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg, "manipulate Android Boot Image", - "addr <addr>\n" + "addr <boot_img_addr> [<vendor_boot_img_addr>]>\n" " - set the address in RAM where boot image is located\n" " ($loadaddr is used by default)\n" "abootimg dump dtb\n"

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Vendor boot image is introduced in boot image header version 3 and 4. Please check [1] for more details.
To prepare for boot image v3/v4 support, allow the abootimg command to store the vendor_boot image address.
Full support for this new format will be done in a future patch.
Link:[1] https://source.android.com/docs/core/architecture/bootloader/partitions/vend...
Signed-off-by: Safae Ouajih souajih@baylibre.com
cmd/abootimg.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Thu, Jan 26, 2023 at 17:54, Simon Glass sjg@chromium.org wrote:
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Vendor boot image is introduced in boot image header version 3 and 4. Please check [1] for more details.
To prepare for boot image v3/v4 support, allow the abootimg command to store the vendor_boot image address.
Full support for this new format will be done in a future patch.
Link:[1] https://source.android.com/docs/core/architecture/bootloader/partitions/vend...
Signed-off-by: Safae Ouajih souajih@baylibre.com
cmd/abootimg.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com

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, android_image_check_header() is being replaced by is_android_boot_image_header() to only refer to boot image header check.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 8 ++++---- boot/image-board.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 3 +-- include/image.h | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 8c0a304cc0..ed51e8b47e 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -122,9 +122,9 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, return 0; }
-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) @@ -231,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; @@ -280,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 e5d71a3d54..9295b6d0c8 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 026c03f91c..b5cfb141ef 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 6d0112fdf4..086e5f7843 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 bcb24d92de..c1594ee169 100644 --- a/include/image.h +++ b/include/image.h @@ -1735,7 +1735,6 @@ 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_boot_img_hdr_v0; -int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); 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_boot_img_hdr_v0 *hdr, @@ -1750,6 +1749,7 @@ 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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); +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

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
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, android_image_check_header() is being replaced by is_android_boot_image_header() to only refer to boot image header check.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 8 ++++---- boot/image-board.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 3 +-- include/image.h | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-)
[..]
diff --git a/include/image.h b/include/image.h index bcb24d92de..c1594ee169 100644 --- a/include/image.h +++ b/include/image.h @@ -1735,7 +1735,6 @@ 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_boot_img_hdr_v0; -int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); 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_boot_img_hdr_v0 *hdr, @@ -1750,6 +1749,7 @@ 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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); +bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr);
Please add a full comment
/**
- board_fit_config_name_match() - Check for a matching board name
-- 2.34.1
With that:
Reviewed-by: Simon Glass sjg@chromium.org
Regards, SImon

On Thu, Jan 26, 2023 at 17:54, Simon Glass sjg@chromium.org wrote:
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
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, android_image_check_header() is being replaced by is_android_boot_image_header() to only refer to boot image header check.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 8 ++++---- boot/image-board.c | 2 +- cmd/abootimg.c | 4 ++-- drivers/fastboot/fb_mmc.c | 3 +-- include/image.h | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-)
[..]
diff --git a/include/image.h b/include/image.h index bcb24d92de..c1594ee169 100644 --- a/include/image.h +++ b/include/image.h @@ -1735,7 +1735,6 @@ 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_boot_img_hdr_v0; -int android_image_check_header(const struct andr_boot_img_hdr_v0 *hdr); 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_boot_img_hdr_v0 *hdr, @@ -1750,6 +1749,7 @@ 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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); +bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr);
Please add a full comment
/**
- board_fit_config_name_match() - Check for a matching board name
-- 2.34.1
With that:
Reviewed-by: Simon Glass sjg@chromium.org
Regards, SImon
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com

This adds support for v3/v4 boot image format by adding the following structures:
- andr_boot_img_hdr_v3 : describes boot image header - andr_vendor_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-head... Link:[2] https://source.android.com/docs/core/architecture/bootloader/partitions/vend... 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 souajih@baylibre.com --- include/android_image.h | 183 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-)
diff --git a/include/android_image.h b/include/android_image.h index 2bdcab9122..4fce363ff7 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 <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_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_vendor_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

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for v3/v4 boot image format by adding the following structures:
- andr_boot_img_hdr_v3 : describes boot image header
- andr_vendor_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-head... Link:[2] https://source.android.com/docs/core/architecture/bootloader/partitions/vend... 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 souajih@baylibre.com
include/android_image.h | 183 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
You might consider using the sphinx style for struct comments so you can include this header file into the docs directly.

On Thu, Jan 26, 2023 at 17:54, Simon Glass sjg@chromium.org wrote:
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for v3/v4 boot image format by adding the following structures:
- andr_boot_img_hdr_v3 : describes boot image header
- andr_vendor_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-head... Link:[2] https://source.android.com/docs/core/architecture/bootloader/partitions/vend... 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 souajih@baylibre.com
include/android_image.h | 183 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
You might consider using the sphinx style for struct comments so you can include this header file into the docs directly.
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com

andr_image_data structure is used as a global representation of boot image header structure. This new structure is introduced to support all boot header versions : v0,v1.v2.v3.v4 and will be used 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.
android_image_get_kcomp() is reworked to support this new struct.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 75 ++++++++++++++++++++++++++++++++++++++++- include/android_image.h | 27 +++++++++++++++ include/image.h | 2 ++ 3 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/boot/image-android.c b/boot/image-android.c index ed51e8b47e..487223d850 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 4fce363ff7..5b36f96d7b 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; + u32 kernel_size; + u32 ramdisk_size; + u32 boot_ramdisk_size; + ulong second_ptr; + u32 second_size; + ulong dtb_ptr; + u32 dtb_size; + ulong recovery_dtbo_ptr; + u32 recovery_dtbo_size; + + const char *kcmdline; + const char *kcmdline_extra; + const char *image_name; + + u32 kernel_addr; + ulong ramdisk_addr; + ulong ramdisk_ptr; + ulong dtb_load_addr; + ulong tags_addr; + u32 header_version; + u32 boot_img_total_size; +}; + #endif diff --git a/include/image.h b/include/image.h index c1594ee169..9a0bd9d8f2 100644 --- a/include/image.h +++ b/include/image.h @@ -1733,7 +1733,9 @@ 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;
+bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data); struct andr_boot_img_hdr_v0; int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len);

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
andr_image_data structure is used as a global representation of boot image header structure. This new structure is introduced to support all boot header versions : v0,v1.v2.v3.v4 and will be used 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.
android_image_get_kcomp() is reworked to support this new struct.
nit: Your commit messages should be in imperative tense. See [1] for some thoughts on this.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 75 ++++++++++++++++++++++++++++++++++++++++- include/android_image.h | 27 +++++++++++++++ include/image.h | 2 ++ 3 files changed, 103 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
But please comment struct andr_image_data.
[..]
diff --git a/include/android_image.h b/include/android_image.h index 4fce363ff7..5b36f96d7b 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;
u32 kernel_size;
u32 ramdisk_size;
u32 boot_ramdisk_size;
ulong second_ptr;
u32 second_size;
ulong dtb_ptr;
u32 dtb_size;
ulong recovery_dtbo_ptr;
u32 recovery_dtbo_size;
const char *kcmdline;
const char *kcmdline_extra;
const char *image_name;
u32 kernel_addr;
ulong ramdisk_addr;
ulong ramdisk_ptr;
ulong dtb_load_addr;
ulong tags_addr;
u32 header_version;
u32 boot_img_total_size;
+};
#endif diff --git a/include/image.h b/include/image.h index c1594ee169..9a0bd9d8f2 100644 --- a/include/image.h +++ b/include/image.h @@ -1733,7 +1733,9 @@ 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;
+bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data); struct andr_boot_img_hdr_v0; int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len); -- 2.34.1
[1] https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md#com...

On Thu, Jan 26, 2023 at 17:54, Simon Glass sjg@chromium.org wrote:
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
andr_image_data structure is used as a global representation of boot image header structure. This new structure is introduced to support all boot header versions : v0,v1.v2.v3.v4 and will be used 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.
android_image_get_kcomp() is reworked to support this new struct.
nit: Your commit messages should be in imperative tense. See [1] for some thoughts on this.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 75 ++++++++++++++++++++++++++++++++++++++++- include/android_image.h | 27 +++++++++++++++ include/image.h | 2 ++ 3 files changed, 103 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
But please comment struct andr_image_data.
[..]
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
diff --git a/include/android_image.h b/include/android_image.h index 4fce363ff7..5b36f96d7b 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;
u32 kernel_size;
u32 ramdisk_size;
u32 boot_ramdisk_size;
ulong second_ptr;
u32 second_size;
ulong dtb_ptr;
u32 dtb_size;
ulong recovery_dtbo_ptr;
u32 recovery_dtbo_size;
const char *kcmdline;
const char *kcmdline_extra;
const char *image_name;
u32 kernel_addr;
ulong ramdisk_addr;
ulong ramdisk_ptr;
ulong dtb_load_addr;
ulong tags_addr;
u32 header_version;
u32 boot_img_total_size;
+};
#endif diff --git a/include/image.h b/include/image.h index c1594ee169..9a0bd9d8f2 100644 --- a/include/image.h +++ b/include/image.h @@ -1733,7 +1733,9 @@ 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;
+bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data); struct andr_boot_img_hdr_v0; int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len); -- 2.34.1
[1] https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md#com...

Move from andr_boot_img_hdr_v0 to andr_image_data structure to prepare for boot image header version 3 and 4.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 127 ++++++++++++++++++++++++------------------- cmd/abootimg.c | 31 ++++++----- include/image.h | 2 + 3 files changed, 89 insertions(+), 71 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 487223d850..9dab09a69a 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -86,7 +86,7 @@ bool android_image_get_data(const void *boot_hdr, struct andr_image_data *data) return true; }
-static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hdr) +static ulong android_image_get_kernel_addr(struct andr_image_data *img_data) { /* * All the Android tools that generate a boot.img use this @@ -99,17 +99,17 @@ static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hd * * Otherwise, we will return the actual value set by the user. */ - if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) - return (ulong)hdr + hdr->page_size; + if (img_data->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) + return img_data->kernel_ptr;
/* * abootimg creates images where all load addresses are 0 * and we need to fix them. */ - if (hdr->kernel_addr == 0 && hdr->ramdisk_addr == 0) + if (img_data->kernel_addr == 0 && img_data->ramdisk_addr == 0) return env_get_ulong("kernel_addr_r", 16, 0);
- return hdr->kernel_addr; + return img_data->kernel_addr; }
/** @@ -130,27 +130,33 @@ static ulong android_image_get_kernel_addr(const struct andr_boot_img_hdr_v0 *hd int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, ulong *os_data, ulong *os_len) { - u32 kernel_addr = android_image_get_kernel_addr(hdr); - const struct legacy_img_hdr *ihdr = (const struct legacy_img_hdr *) - ((uintptr_t)hdr + hdr->page_size); + struct andr_image_data img_data = {0}; + u32 kernel_addr; + const struct legacy_img_hdr *ihdr; + + if (!android_image_get_data(hdr, &img_data)) + return -EINVAL; + + kernel_addr = android_image_get_kernel_addr(&img_data); + ihdr = (const struct legacy_img_hdr *)img_data.kernel_ptr;
/* * Not all Android tools use the id field for signing the image with * sha1 (or anything) so we don't check it. It is not obvious that the * string is null terminated so we take care of this. */ - strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE); + strncpy(andr_tmp_str, img_data.image_name, ANDR_BOOT_NAME_SIZE); andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0'; if (strlen(andr_tmp_str)) printf("Android's image name: %s\n", andr_tmp_str);
printf("Kernel load addr 0x%08x size %u KiB\n", - kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024)); + kernel_addr, DIV_ROUND_UP(img_data.kernel_size, 1024));
int len = 0; - if (*hdr->cmdline) { - printf("Kernel command line: %s\n", hdr->cmdline); - len += strlen(hdr->cmdline); + if (*img_data.kcmdline) { + printf("Kernel command line: %s\n", img_data.kcmdline); + len += strlen(img_data.kcmdline); }
char *bootargs = env_get("bootargs"); @@ -168,8 +174,9 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, strcpy(newbootargs, bootargs); strcat(newbootargs, " "); } - if (*hdr->cmdline) - strcat(newbootargs, hdr->cmdline); + + if (*img_data.kcmdline) + strcat(newbootargs, img_data.kcmdline);
env_set("bootargs", newbootargs);
@@ -177,15 +184,14 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, int verify, if (image_get_magic(ihdr) == IH_MAGIC) { *os_data = image_get_data(ihdr); } else { - *os_data = (ulong)hdr; - *os_data += hdr->page_size; + *os_data = img_data.kernel_ptr; } } if (os_len) { if (image_get_magic(ihdr) == IH_MAGIC) *os_len = image_get_data_size(ihdr); else - *os_len = hdr->kernel_size; + *os_len = img_data.kernel_size; } return 0; } @@ -197,30 +203,25 @@ bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr)
ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr) { - ulong end; - - /* - * The header takes a full page, the remaining components are aligned - * on page boundary - */ - end = (ulong)hdr; - end += hdr->page_size; - end += ALIGN(hdr->kernel_size, hdr->page_size); - end += ALIGN(hdr->ramdisk_size, hdr->page_size); - end += ALIGN(hdr->second_size, hdr->page_size); + struct andr_image_data img_data;
- if (hdr->header_version >= 1) - end += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); + if (!android_image_get_data(hdr, &img_data)) + return -EINVAL;
- if (hdr->header_version >= 2) - end += ALIGN(hdr->dtb_size, hdr->page_size); + if (img_data.header_version > 2) + return 0;
- return end; + return img_data.boot_img_total_size; }
ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr) { - return android_image_get_kernel_addr(hdr); + struct andr_image_data img_data; + + if (!android_image_get_data(hdr, &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) @@ -243,38 +244,43 @@ 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) { - if (!hdr->ramdisk_size) { + struct andr_image_data img_data = {0}; + + if (!android_image_get_data(hdr, &img_data)) + return -EINVAL; + + if (!img_data.ramdisk_size) { *rd_data = *rd_len = 0; return -1; }
- printf("RAM disk load addr 0x%08x size %u KiB\n", - hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024)); + printf("RAM disk load addr 0x%08lx size %u KiB\n", + img_data.ramdisk_ptr, DIV_ROUND_UP(img_data.ramdisk_size, 1024));
- *rd_data = (unsigned long)hdr; - *rd_data += hdr->page_size; - *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); + *rd_data = img_data.ramdisk_ptr;
- *rd_len = hdr->ramdisk_size; + *rd_len = img_data.ramdisk_size; return 0; }
int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, ulong *second_data, ulong *second_len) { - if (!hdr->second_size) { + struct andr_image_data img_data; + + if (!android_image_get_data(hdr, &img_data)) + return -EINVAL; + + if (!img_data.second_size) { *second_data = *second_len = 0; return -1; }
- *second_data = (unsigned long)hdr; - *second_data += hdr->page_size; - *second_data += ALIGN(hdr->kernel_size, hdr->page_size); - *second_data += ALIGN(hdr->ramdisk_size, hdr->page_size); + *second_data = img_data.second_ptr;
printf("second address is 0x%lx\n",*second_data);
- *second_len = hdr->second_size; + *second_len = img_data.second_size; return 0; }
@@ -339,6 +345,8 @@ exit: return ret; }
+#if !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_CMD_ABOOTIMG /** * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image. * @hdr_addr: Boot image header address @@ -385,6 +393,8 @@ exit: unmap_sysmem(hdr); return ret; } +#endif +#endif
/** * android_image_get_dtb_by_index() - Get address and size of blob in DTB area. @@ -401,17 +411,22 @@ exit: bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, u32 *size) { + struct andr_image_data img_data; const struct andr_boot_img_hdr_v0 *hdr; - bool res; + + hdr = map_sysmem(hdr_addr, sizeof(*hdr)); + if (!android_image_get_data(hdr, &img_data)) { + unmap_sysmem(hdr); + return false; + } + unmap_sysmem(hdr); + ulong dtb_img_addr; /* address of DTB part in boot image */ u32 dtb_img_size; /* size of DTB payload in boot image */ 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); - if (!res) - return false; - + android_image_get_dtb_img_addr(hdr_addr, &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, @@ -419,9 +434,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, }
/* Find out the address of DTB with specified index in concat blobs */ - hdr = map_sysmem(hdr_addr, sizeof(*hdr)); - dtb_img_size = hdr->dtb_size; - unmap_sysmem(hdr); + dtb_img_size = img_data.dtb_size; i = 0; dtb_addr = dtb_img_addr; while (dtb_addr < dtb_img_addr + dtb_img_size) { @@ -506,6 +519,7 @@ void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr) } }
+#ifdef CONFIG_CMD_ABOOTIMG /** * android_image_print_dtb_info - Print info for one DTB blob in DTB area. * @fdt: DTB header @@ -610,3 +624,4 @@ bool android_image_print_dtb_contents(ulong hdr_addr) return true; } #endif +#endif diff --git a/cmd/abootimg.c b/cmd/abootimg.c index b5cfb141ef..f04a7c7c8e 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -66,33 +66,34 @@ static int abootimg_get_recovery_dtbo(int argc, char *const argv[])
static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) { - const struct andr_boot_img_hdr_v0 *hdr; - int res = CMD_RET_SUCCESS; - if (argc > 1) return CMD_RET_USAGE; + struct andr_image_data img_data = {0}; + const struct andr_boot_img_hdr_v0 *hdr;
hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); - if (!is_android_boot_image_header(hdr)) { - printf("Error: Boot Image header is incorrect\n"); - res = CMD_RET_FAILURE; - goto exit; + if (!android_image_get_data(hdr, &img_data)) { + unmap_sysmem(hdr); + return CMD_RET_FAILURE; } + unmap_sysmem(hdr);
- if (hdr->header_version < 2) { + if (img_data.header_version < 2) { printf("Error: header_version must be >= 2 for this\n"); - res = CMD_RET_FAILURE; - goto exit; + return CMD_RET_FAILURE; + } + + if (!img_data.dtb_load_addr) { + printf("Error: failed to read dtb_load_addr\n"); + return CMD_RET_FAILURE; }
if (argc == 0) - printf("%lx\n", (ulong)hdr->dtb_addr); + printf("%lx\n", (ulong)img_data.dtb_load_addr); else - env_set_hex(argv[0], (ulong)hdr->dtb_addr); + env_set_hex(argv[0], (ulong)img_data.dtb_load_addr);
-exit: - unmap_sysmem(hdr); - return res; + return CMD_RET_SUCCESS; }
static int abootimg_get_dtb_by_index(int argc, char *const argv[]) diff --git a/include/image.h b/include/image.h index 9a0bd9d8f2..6264d13e0c 100644 --- a/include/image.h +++ b/include/image.h @@ -1750,7 +1750,9 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr); 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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); +#ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); +#endif bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr);
/**

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Move from andr_boot_img_hdr_v0 to andr_image_data structure to prepare for boot image header version 3 and 4.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 127 ++++++++++++++++++++++++------------------- cmd/abootimg.c | 31 ++++++----- include/image.h | 2 + 3 files changed, 89 insertions(+), 71 deletions(-)
Do you need the #ifdef CONFIG_CMD_ABOOTIMG? We try to avoid adding those.
Regards, Simon

On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Move from andr_boot_img_hdr_v0 to andr_image_data structure to prepare for boot image header version 3 and 4.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 127 ++++++++++++++++++++++++------------------- cmd/abootimg.c | 31 ++++++----- include/image.h | 2 + 3 files changed, 89 insertions(+), 71 deletions(-)
Do you need the #ifdef CONFIG_CMD_ABOOTIMG? We try to avoid adding those.
Regards, Simon
Hi Simon,
This is needed to avoid warnings such as "unused function warnings" when
CONFIG_CMD_ABOOTIMG is not defined.
Best regards,
--safae

Hi Safae,
On Fri, 27 Jan 2023 at 08:50, Safae Ouajih souajih@baylibre.com wrote:
On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Move from andr_boot_img_hdr_v0 to andr_image_data structure to prepare for boot image header version 3 and 4.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 127 ++++++++++++++++++++++++------------------- cmd/abootimg.c | 31 ++++++----- include/image.h | 2 + 3 files changed, 89 insertions(+), 71 deletions(-)
Do you need the #ifdef CONFIG_CMD_ABOOTIMG? We try to avoid adding those.
Regards, Simon
Hi Simon,
This is needed to avoid warnings such as "unused function warnings" when
CONFIG_CMD_ABOOTIMG is not defined.
It is quite rare that this is needed and I cannot see it myself. Can you please check again?
You should call the function from an IS_ENABLED() check, not an #ifdef. Also, if it is in another file there is no need to #ifdef it since it will just be dropped by the linker.
Regards, Simon

Content print is not supported for version 3 and 4 of boot image header. Thus, only print that content when v2 is used.
Update android_print_contents() to print an error message when trying to print boot image header version 3 or 4 content.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 9dab09a69a..a6e7a7abb0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -481,6 +481,10 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr, */ void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr) { + if (hdr->header_version >= 3) { + printf("Content print is not supported for boot image header version > 2"); + return; + } const char * const p = IMAGE_INDENT_STRING; /* os_version = ver << 11 | lvl */ u32 os_ver = hdr->os_version >> 11; @@ -513,7 +517,7 @@ void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr) hdr->header_size); }
- if (hdr->header_version >= 2) { + if (hdr->header_version == 2) { printf("%sdtb size: %x\n", p, hdr->dtb_size); printf("%sdtb addr: %llx\n", p, hdr->dtb_addr); }

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Content print is not supported for version 3 and 4 of boot image header. Thus, only print that content when v2 is used.
Update android_print_contents() to print an error message when trying to print boot image header version 3 or 4 content.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Why is that?
Regards, Simon

On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Content print is not supported for version 3 and 4 of boot image header. Thus, only print that content when v2 is used.
Update android_print_contents() to print an error message when trying to print boot image header version 3 or 4 content.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Why is that?
Regards, Simon
Hi Simon,
Thank you for the review.
Content print for boot image header v4 can be supported
and only requires updating the existing functions.
This is something I intend to support later on.
Best regards,
--safae

On Fri, 27 Jan 2023 at 08:50, Safae Ouajih souajih@baylibre.com wrote:
On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Content print is not supported for version 3 and 4 of boot image header. Thus, only print that content when v2 is used.
Update android_print_contents() to print an error message when trying to print boot image header version 3 or 4 content.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Why is that?
Regards, Simon
Hi Simon,
Thank you for the review.
Content print for boot image header v4 can be supported
and only requires updating the existing functions.
This is something I intend to support later on.
OK thanks
Reviewed-by: Simon Glass sjg@chromium.org

On Fri, Jan 27, 2023 at 10:15, Simon Glass sjg@chromium.org wrote:
On Fri, 27 Jan 2023 at 08:50, Safae Ouajih souajih@baylibre.com wrote:
On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Content print is not supported for version 3 and 4 of boot image header. Thus, only print that content when v2 is used.
Update android_print_contents() to print an error message when trying to print boot image header version 3 or 4 content.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Why is that?
Regards, Simon
Hi Simon,
Thank you for the review.
Content print for boot image header v4 can be supported
and only requires updating the existing functions.
This is something I intend to support later on.
OK thanks
Reviewed-by: Simon Glass sjg@chromium.org
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com

android_image_get_dtbo() is used to get recovery DTBO via abootimg cmd. This is not supported in boot image header v3 and v4. Thus, we print an error message when v1,v2 header version are not used.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index a6e7a7abb0..d797270a32 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -316,8 +316,8 @@ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) goto exit; }
- if (hdr->header_version < 1) { - printf("Error: header_version must be >= 1 to get dtbo\n"); + if (hdr->header_version != 1 && hdr->header_version != 2) { + printf("Error: header version must be >= 1 and <= 2 to get dtbo\n"); ret = false; goto exit; }

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
android_image_get_dtbo() is used to get recovery DTBO via abootimg cmd. This is not supported in boot image header v3 and v4. Thus, we print an error message when v1,v2 header version are not used.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
log_err() might be better
diff --git a/boot/image-android.c b/boot/image-android.c index a6e7a7abb0..d797270a32 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -316,8 +316,8 @@ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) goto exit; }
if (hdr->header_version < 1) {
printf("Error: header_version must be >= 1 to get dtbo\n");
if (hdr->header_version != 1 && hdr->header_version != 2) {
printf("Error: header version must be >= 1 and <= 2 to get dtbo\n"); ret = false; goto exit; }
-- 2.34.1

On Thu, Jan 26, 2023 at 17:54, Simon Glass sjg@chromium.org wrote:
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
android_image_get_dtbo() is used to get recovery DTBO via abootimg cmd. This is not supported in boot image header v3 and v4. Thus, we print an error message when v1,v2 header version are not used.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
log_err() might be better
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
diff --git a/boot/image-android.c b/boot/image-android.c index a6e7a7abb0..d797270a32 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -316,8 +316,8 @@ bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size) goto exit; }
if (hdr->header_version < 1) {
printf("Error: header_version must be >= 1 to get dtbo\n");
if (hdr->header_version != 1 && hdr->header_version != 2) {
printf("Error: header version must be >= 1 and <= 2 to get dtbo\n"); ret = false; goto exit; }
-- 2.34.1

This is done to prepare for boot image version 3 and 4 support.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- 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 | 22 +++++++++++------- 6 files changed, 58 insertions(+), 36 deletions(-)
diff --git a/boot/bootm.c b/boot/bootm.c index 15fce8ad95..a58e6f391e 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 d797270a32..66922355e5 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) { @@ -350,11 +357,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; @@ -399,6 +407,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 @@ -408,17 +417,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_vendor_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 */ @@ -426,7 +442,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, @@ -583,7 +599,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 9295b6d0c8..b6c9bbe8f5 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 1181cb60f0..f270d00a5f 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 f04a7c7c8e..4d6cf0fa3e 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 6264d13e0c..df8a9075fa 100644 --- a/include/image.h +++ b/include/image.h @@ -1735,20 +1735,26 @@ 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;
-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; -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); 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); 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_boot_img_hdr_v0 *hdr); -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); +bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, + u32 index, ulong *addr, u32 *size); +ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); +ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); +ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, + const void *vendor_boot_img); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr);

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This is done to prepare for boot image version 3 and 4 support.
Signed-off-by: Safae Ouajih souajih@baylibre.com
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 | 22 +++++++++++------- 6 files changed, 58 insertions(+), 36 deletions(-)
diff --git a/include/image.h b/include/image.h index 6264d13e0c..df8a9075fa 100644 --- a/include/image.h +++ b/include/image.h @@ -1735,20 +1735,26 @@ 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;
-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; -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);
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);
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_boot_img_hdr_v0 *hdr); -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); +bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img,
u32 index, ulong *addr, u32 *size);
+ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr,
const void *vendor_boot_img);
+ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr,
const void *vendor_boot_img);
+ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr,
const void *vendor_boot_img);
void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); -- 2.34.1
Please add comments for those that you change. Really all of these should have proper comments.
Regards, Simon

Since boot image header version 3 and 4 introduced vendor boot image, the following functions are used to fill the generic android structure : andr_image_data:
- android_boot_image_v3_v4_parse_hdr() - android_vendor_boot_image_v3_v4_parse_hdr()
android_image_get_data() is then updated to support v3 and v4
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 80 +++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 3 ++ include/image.h | 1 + 3 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 66922355e5..0e78ca0dac 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_vendor_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 5b36f96d7b..351e17750e 100644 --- a/include/android_image.h +++ b/include/android_image.h @@ -323,6 +323,8 @@ struct andr_image_data { ulong kernel_ptr; u32 kernel_size; u32 ramdisk_size; + ulong vendor_ramdisk_ptr; + u32 vendor_ramdisk_size; u32 boot_ramdisk_size; ulong second_ptr; u32 second_size; @@ -342,6 +344,7 @@ struct andr_image_data { ulong tags_addr; u32 header_version; u32 boot_img_total_size; + u32 vendor_boot_img_total_size; };
#endif diff --git a/include/image.h b/include/image.h index df8a9075fa..a1a14403d5 100644 --- a/include/image.h +++ b/include/image.h @@ -1760,6 +1760,7 @@ void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); bool android_image_print_dtb_contents(ulong hdr_addr); #endif 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);
/** * board_fit_config_name_match() - Check for a matching board name

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Since boot image header version 3 and 4 introduced vendor boot image, the following functions are used to fill the generic android structure : andr_image_data:
- android_boot_image_v3_v4_parse_hdr()
- android_vendor_boot_image_v3_v4_parse_hdr()
android_image_get_data() is then updated to support v3 and v4
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 80 +++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 3 ++ include/image.h | 1 + 3 files changed, 81 insertions(+), 3 deletions(-)
Comments again, for struct and image.h
Otherwise: Reviewed-by: Simon Glass sjg@chromium.org

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.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 13 +++++++++++-- include/image.h | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index 0e78ca0dac..5b270e4417 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 a1a14403d5..ac94ecaa14 100644 --- a/include/image.h +++ b/include/image.h @@ -1742,8 +1742,8 @@ struct andr_boot_img_hdr_v0; 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); -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); 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);

On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
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.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 13 +++++++++++-- include/image.h | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-)
Some comment re comments
With that:
Reviewed-by: Simon Glass sjg@chromium.org

In version 3 and 4 of boot image header, the vendor specific command line are located in vendor boot image. Thus, using extra command line to add those cmd to bootargs.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/boot/image-android.c b/boot/image-android.c index 5b270e4417..cb4fc22b00 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -55,6 +55,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vendor_i * The header takes a full page, the remaining components are aligned * on page boundary. */ + data->kcmdline_extra = hdr->cmdline; data->tags_addr = hdr->tags_addr; data->image_name = hdr->name; data->kernel_addr = hdr->kernel_addr; @@ -233,6 +234,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, len += strlen(img_data.kcmdline); }
+ if (img_data.kcmdline_extra) { + printf("Kernel extra command line: %s\n", img_data.kcmdline_extra); + len += strlen(img_data.kcmdline_extra); + } + char *bootargs = env_get("bootargs"); if (bootargs) len += strlen(bootargs); @@ -252,6 +258,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, if (*img_data.kcmdline) strcat(newbootargs, img_data.kcmdline);
+ if (img_data.kcmdline_extra) { + strcat(newbootargs, " "); + strcat(newbootargs, img_data.kcmdline_extra); + } + env_set("bootargs", newbootargs);
if (os_data) {

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
In version 3 and 4 of boot image header, the vendor specific
vendor-spefcific
command line are located in vendor boot image. Thus, using
use the
extra command line to add those cmd to bootargs.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/boot/image-android.c b/boot/image-android.c index 5b270e4417..cb4fc22b00 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -55,6 +55,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vendor_i * The header takes a full page, the remaining components are aligned * on page boundary. */
data->kcmdline_extra = hdr->cmdline; data->tags_addr = hdr->tags_addr; data->image_name = hdr->name; data->kernel_addr = hdr->kernel_addr;
@@ -233,6 +234,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, len += strlen(img_data.kcmdline); }
if (img_data.kcmdline_extra) {
printf("Kernel extra command line: %s\n", img_data.kcmdline_extra);
len += strlen(img_data.kcmdline_extra);
}
char *bootargs = env_get("bootargs"); if (bootargs) len += strlen(bootargs);
@@ -252,6 +258,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, if (*img_data.kcmdline) strcat(newbootargs, img_data.kcmdline);
if (img_data.kcmdline_extra) {
strcat(newbootargs, " ");
strcat(newbootargs, img_data.kcmdline_extra);
Do we need to worry about overflow?
}
env_set("bootargs", newbootargs); if (os_data) {
-- 2.34.1
Regards, Simon

On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
In version 3 and 4 of boot image header, the vendor specific
vendor-spefcific
command line are located in vendor boot image. Thus, using
use the
extra command line to add those cmd to bootargs.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/boot/image-android.c b/boot/image-android.c index 5b270e4417..cb4fc22b00 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -55,6 +55,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vendor_i * The header takes a full page, the remaining components are aligned * on page boundary. */
data->kcmdline_extra = hdr->cmdline; data->tags_addr = hdr->tags_addr; data->image_name = hdr->name; data->kernel_addr = hdr->kernel_addr;
@@ -233,6 +234,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, len += strlen(img_data.kcmdline); }
if (img_data.kcmdline_extra) {
printf("Kernel extra command line: %s\n", img_data.kcmdline_extra);
len += strlen(img_data.kcmdline_extra);
}
char *bootargs = env_get("bootargs"); if (bootargs) len += strlen(bootargs);
@@ -252,6 +258,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, if (*img_data.kcmdline) strcat(newbootargs, img_data.kcmdline);
if (img_data.kcmdline_extra) {
strcat(newbootargs, " ");
strcat(newbootargs, img_data.kcmdline_extra);
Do we need to worry about overflow?
Hi Simon,
This line adds kcmdline_extra length to the len variable:
len += strlen(img_data.kcmdline_extra);
newbootargs is allocated just after in :
char *newbootargs = malloc(len + 2);
I can not see a possible overflow, please let me know if you
think this is not enough.
Thank you,
BR,
--safae
}
env_set("bootargs", newbootargs); if (os_data) {
-- 2.34.1
Regards, Simon

On Fri, 27 Jan 2023 at 08:51, Safae Ouajih souajih@baylibre.com wrote:
On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
In version 3 and 4 of boot image header, the vendor specific
vendor-spefcific
command line are located in vendor boot image. Thus, using
use the
extra command line to add those cmd to bootargs.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/boot/image-android.c b/boot/image-android.c index 5b270e4417..cb4fc22b00 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -55,6 +55,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vendor_i * The header takes a full page, the remaining components are aligned * on page boundary. */
data->kcmdline_extra = hdr->cmdline; data->tags_addr = hdr->tags_addr; data->image_name = hdr->name; data->kernel_addr = hdr->kernel_addr;
@@ -233,6 +234,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, len += strlen(img_data.kcmdline); }
if (img_data.kcmdline_extra) {
printf("Kernel extra command line: %s\n", img_data.kcmdline_extra);
len += strlen(img_data.kcmdline_extra);
}
char *bootargs = env_get("bootargs"); if (bootargs) len += strlen(bootargs);
@@ -252,6 +258,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, if (*img_data.kcmdline) strcat(newbootargs, img_data.kcmdline);
if (img_data.kcmdline_extra) {
strcat(newbootargs, " ");
strcat(newbootargs, img_data.kcmdline_extra);
Do we need to worry about overflow?
Hi Simon,
This line adds kcmdline_extra length to the len variable:
len += strlen(img_data.kcmdline_extra);
newbootargs is allocated just after in :
char *newbootargs = malloc(len + 2);
I can not see a possible overflow, please let me know if you
think this is not enough.
OK I see, thank you.
Reviewed-by: Simon Glass sjg@chromium.org

On Fri, Jan 27, 2023 at 10:15, Simon Glass sjg@chromium.org wrote:
On Fri, 27 Jan 2023 at 08:51, Safae Ouajih souajih@baylibre.com wrote:
On 27/01/2023 01:54, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
In version 3 and 4 of boot image header, the vendor specific
vendor-spefcific
command line are located in vendor boot image. Thus, using
use the
extra command line to add those cmd to bootargs.
Signed-off-by: Safae Ouajih souajih@baylibre.com
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
boot/image-android.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/boot/image-android.c b/boot/image-android.c index 5b270e4417..cb4fc22b00 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -55,6 +55,7 @@ static void android_vendor_boot_image_v3_v4_parse_hdr(const struct andr_vendor_i * The header takes a full page, the remaining components are aligned * on page boundary. */
data->kcmdline_extra = hdr->cmdline; data->tags_addr = hdr->tags_addr; data->image_name = hdr->name; data->kernel_addr = hdr->kernel_addr;
@@ -233,6 +234,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, len += strlen(img_data.kcmdline); }
if (img_data.kcmdline_extra) {
printf("Kernel extra command line: %s\n", img_data.kcmdline_extra);
len += strlen(img_data.kcmdline_extra);
}
char *bootargs = env_get("bootargs"); if (bootargs) len += strlen(bootargs);
@@ -252,6 +258,11 @@ int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, if (*img_data.kcmdline) strcat(newbootargs, img_data.kcmdline);
if (img_data.kcmdline_extra) {
strcat(newbootargs, " ");
strcat(newbootargs, img_data.kcmdline_extra);
Do we need to worry about overflow?
Hi Simon,
This line adds kcmdline_extra length to the len variable:
len += strlen(img_data.kcmdline_extra);
newbootargs is allocated just after in :
char *newbootargs = malloc(len + 2);
I can not see a possible overflow, please let me know if you
think this is not enough.
OK I see, thank you.
Reviewed-by: Simon Glass sjg@chromium.org

This adds support for boot image version 3 and 4 in android_image_get_dtb_img_addr(). Since the dtb is now included in vendor_boot image instead of boot image, the dtb address should be extracted from vendor_boot image when a v3 or v4 is used.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/image-android.c | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index cb4fc22b00..edeeaaaee0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -459,6 +459,7 @@ exit: static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulong *addr) { const struct andr_boot_img_hdr_v0 *hdr; + const struct andr_vendor_img_hdr *v_hdr; ulong dtb_img_addr; bool ret = true;
@@ -475,22 +476,40 @@ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulon goto exit; }
- if (hdr->dtb_size == 0) { - printf("Error: dtb_size is 0\n"); - ret = false; - goto exit; + if (hdr->header_version == 2) { + if (hdr->dtb_size == 0) { + printf("Error: dtb_size is 0\n"); + ret = false; + goto exit; + } + /* Calculate the address of DTB area in boot image */ + dtb_img_addr = hdr_addr; + dtb_img_addr += hdr->page_size; + dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size); + dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); + + *addr = dtb_img_addr; }
- /* Calculate the address of DTB area in boot image */ - dtb_img_addr = hdr_addr; - dtb_img_addr += hdr->page_size; - dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size); - dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size); - dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size); - dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); - - *addr = dtb_img_addr; - + if (hdr->header_version > 2) { + v_hdr = map_sysmem(vhdr_addr, sizeof(*v_hdr)); + if (v_hdr->dtb_size == 0) { + printf("Error: dtb_size is 0\n"); + ret = false; + unmap_sysmem(v_hdr); + goto exit; + } + /* Calculate the address of DTB area in boot image */ + dtb_img_addr = vhdr_addr; + dtb_img_addr += v_hdr->page_size; + if (v_hdr->vendor_ramdisk_size) + dtb_img_addr += ALIGN(v_hdr->vendor_ramdisk_size, v_hdr->page_size); + *addr = dtb_img_addr; + unmap_sysmem(v_hdr); + goto exit; + } exit: unmap_sysmem(hdr); return ret;

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for boot image version 3 and 4 in android_image_get_dtb_img_addr(). Since the dtb is now included in vendor_boot image instead of boot image, the dtb address should be extracted from vendor_boot image when a v3 or v4 is used.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nits below
diff --git a/boot/image-android.c b/boot/image-android.c index cb4fc22b00..edeeaaaee0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -459,6 +459,7 @@ exit: static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulong *addr) { const struct andr_boot_img_hdr_v0 *hdr;
const struct andr_vendor_img_hdr *v_hdr; ulong dtb_img_addr; bool ret = true;
@@ -475,22 +476,40 @@ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulon goto exit; }
if (hdr->dtb_size == 0) {
printf("Error: dtb_size is 0\n");
ret = false;
goto exit;
if (hdr->header_version == 2) {
if (hdr->dtb_size == 0) {
if (!hdr->dtb_size)
printf("Error: dtb_size is 0\n");
ret = false;
goto exit;
}
/* Calculate the address of DTB area in boot image */
dtb_img_addr = hdr_addr;
dtb_img_addr += hdr->page_size;
dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
*addr = dtb_img_addr; }
/* Calculate the address of DTB area in boot image */
dtb_img_addr = hdr_addr;
dtb_img_addr += hdr->page_size;
dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
*addr = dtb_img_addr;
if (hdr->header_version > 2) {
v_hdr = map_sysmem(vhdr_addr, sizeof(*v_hdr));
if (v_hdr->dtb_size == 0) {
same here
printf("Error: dtb_size is 0\n");
ret = false;
unmap_sysmem(v_hdr);
goto exit;
}
/* Calculate the address of DTB area in boot image */
dtb_img_addr = vhdr_addr;
dtb_img_addr += v_hdr->page_size;
if (v_hdr->vendor_ramdisk_size)
dtb_img_addr += ALIGN(v_hdr->vendor_ramdisk_size, v_hdr->page_size);
*addr = dtb_img_addr;
unmap_sysmem(v_hdr);
goto exit;
}
exit: unmap_sysmem(hdr); return ret; -- 2.34.1
Regards, Simon

On Thu, Jan 26, 2023 at 17:55, Simon Glass sjg@chromium.org wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for boot image version 3 and 4 in android_image_get_dtb_img_addr(). Since the dtb is now included in vendor_boot image instead of boot image, the dtb address should be extracted from vendor_boot image when a v3 or v4 is used.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/image-android.c | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
nits below
diff --git a/boot/image-android.c b/boot/image-android.c index cb4fc22b00..edeeaaaee0 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -459,6 +459,7 @@ exit: static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulong *addr) { const struct andr_boot_img_hdr_v0 *hdr;
const struct andr_vendor_img_hdr *v_hdr; ulong dtb_img_addr; bool ret = true;
@@ -475,22 +476,40 @@ static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong vhdr_addr, ulon goto exit; }
if (hdr->dtb_size == 0) {
printf("Error: dtb_size is 0\n");
ret = false;
goto exit;
if (hdr->header_version == 2) {
if (hdr->dtb_size == 0) {
if (!hdr->dtb_size)
printf("Error: dtb_size is 0\n");
ret = false;
goto exit;
}
/* Calculate the address of DTB area in boot image */
dtb_img_addr = hdr_addr;
dtb_img_addr += hdr->page_size;
dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
*addr = dtb_img_addr; }
/* Calculate the address of DTB area in boot image */
dtb_img_addr = hdr_addr;
dtb_img_addr += hdr->page_size;
dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
*addr = dtb_img_addr;
if (hdr->header_version > 2) {
v_hdr = map_sysmem(vhdr_addr, sizeof(*v_hdr));
if (v_hdr->dtb_size == 0) {
same here
printf("Error: dtb_size is 0\n");
ret = false;
unmap_sysmem(v_hdr);
goto exit;
}
/* Calculate the address of DTB area in boot image */
dtb_img_addr = vhdr_addr;
dtb_img_addr += v_hdr->page_size;
if (v_hdr->vendor_ramdisk_size)
dtb_img_addr += ALIGN(v_hdr->vendor_ramdisk_size, v_hdr->page_size);
*addr = dtb_img_addr;
unmap_sysmem(v_hdr);
goto exit;
}
exit: unmap_sysmem(hdr); return ret; -- 2.34.1
Regards, Simon

Print an error message when the boot image header version is greater than 2 as this is not supported for v3 and v4.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- drivers/fastboot/fb_mmc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index 086e5f7843..9fb2ab3820 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -370,6 +370,14 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc, return -1; }
+ /* Check if boot image header version is 2 or less */ + if (hdr->header_version > 2) { + pr_err("zImage flashing supported only for boot images v2 and less\n"); + fastboot_fail("zImage flashing supported only for boot images v2 and less", + response); + return -1; + } + /* Check if boot image has second stage in it (we don't support it) */ if (hdr->second_size > 0) { pr_err("moving second stage is not supported yet\n");

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
Print an error message when the boot image header version is greater than 2 as this is not supported for v3 and v4.
But why is is not supported? Please add this here.
Signed-off-by: Safae Ouajih souajih@baylibre.com
drivers/fastboot/fb_mmc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index 086e5f7843..9fb2ab3820 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -370,6 +370,14 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc, return -1; }
/* Check if boot image header version is 2 or less */
if (hdr->header_version > 2) {
pr_err("zImage flashing supported only for boot images v2 and less\n");
fastboot_fail("zImage flashing supported only for boot images v2 and less",
response);
return -1;
That is not an error message. Perhaps -ENOTSUPP ?
}
/* Check if boot image has second stage in it (we don't support it) */ if (hdr->second_size > 0) { pr_err("moving second stage is not supported yet\n");
-- 2.34.1
Regards, Simon

This enables 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
"struct andr_boot_img_hdr_v0*" is replaced by "void *" in some functions since v3 and v4 are now supported as well.
Signed-off-by: Safae Ouajih souajih@baylibre.com --- boot/bootm.c | 29 ++++++++++++++++++++++++----- boot/image-android.c | 16 ++++++++++------ boot/image-board.c | 14 +++++++++++--- boot/image-fdt.c | 2 +- cmd/abootimg.c | 24 ++++++++++++++++++++++-- include/image.h | 14 ++++++++------ 6 files changed, 76 insertions(+), 23 deletions(-)
diff --git a/boot/bootm.c b/boot/bootm.c index a58e6f391e..3e130c175c 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,12 +185,17 @@ 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 = (void *)get_abootimg_addr(); + vendor_boot_img = (void *)get_avendor_bootimg_addr(); + } 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; break; @@ -889,6 +898,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,8 +977,14 @@ 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 = (void *)get_abootimg_addr(); + vendor_boot_img = (void *)get_avendor_bootimg_addr(); + } 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; break; diff --git a/boot/image-android.c b/boot/image-android.c index edeeaaaee0..dd06c09279 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 -1; + } + 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 b6c9bbe8f5..a20b57900e 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -426,10 +426,18 @@ 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)) { + ret = android_image_get_ramdisk((void *)get_abootimg_addr(), + (void *)get_avendor_bootimg_addr(), + rd_datap, rd_lenp); + } 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 f270d00a5f..5f9cf7b4e6 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 4d6cf0fa3e..ef7130da0b 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_vendor_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 ac94ecaa14..5bd4bf5d57 100644 --- a/include/image.h +++ b/include/image.h @@ -1739,29 +1739,31 @@ 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; -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); int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); -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); bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, u32 index, ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, const void *vendor_boot_img); -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); -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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); #endif -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +bool is_android_boot_image_header(const void *hdr); bool is_android_vendor_boot_image_header(const void *vendor_boot_img);
+ulong get_abootimg_addr(void); +ulong get_avendor_bootimg_addr(void); + /** * board_fit_config_name_match() - Check for a matching board name *

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This enables 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
"struct andr_boot_img_hdr_v0*" is replaced by "void *" in some functions since v3 and v4 are now supported as well.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/bootm.c | 29 ++++++++++++++++++++++++----- boot/image-android.c | 16 ++++++++++------ boot/image-board.c | 14 +++++++++++--- boot/image-fdt.c | 2 +- cmd/abootimg.c | 24 ++++++++++++++++++++++-- include/image.h | 14 ++++++++------ 6 files changed, 76 insertions(+), 23 deletions(-)
diff --git a/boot/bootm.c b/boot/bootm.c index a58e6f391e..3e130c175c 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,12 +185,17 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
map_sysmem() so it owrks on sandbox
} 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; break;
@@ -889,6 +898,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,8 +977,14 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
and here
} 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; break;
diff --git a/boot/image-android.c b/boot/image-android.c index edeeaaaee0..dd06c09279 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 -1;
Use proper error number. This is -EPERM which seems wrong. Perhaps -ENOTSUPP ?
}
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 b6c9bbe8f5..a20b57900e 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -426,10 +426,18 @@ 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)) {
ret = android_image_get_ramdisk((void *)get_abootimg_addr(),
map_sysmem() again. Or perhaps update that function to take an address?
(void *)get_avendor_bootimg_addr(),
rd_datap, rd_lenp);
} 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 f270d00a5f..5f9cf7b4e6 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 4d6cf0fa3e..ef7130da0b 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_vendor_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 ac94ecaa14..5bd4bf5d57 100644 --- a/include/image.h +++ b/include/image.h @@ -1739,29 +1739,31 @@ 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; -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); int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); -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); bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, u32 index, ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, const void *vendor_boot_img); -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); -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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); #endif -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +bool is_android_boot_image_header(const void *hdr); bool is_android_vendor_boot_image_header(const void *vendor_boot_img);
+ulong get_abootimg_addr(void); +ulong get_avendor_bootimg_addr(void);
again please add comments to all of these.
/**
- board_fit_config_name_match() - Check for a matching board name
-- 2.34.1
Regards, Simon

On Thu, Jan 26, 2023 at 17:55, Simon Glass sjg@chromium.org wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This enables 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
"struct andr_boot_img_hdr_v0*" is replaced by "void *" in some functions since v3 and v4 are now supported as well.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/bootm.c | 29 ++++++++++++++++++++++++----- boot/image-android.c | 16 ++++++++++------ boot/image-board.c | 14 +++++++++++--- boot/image-fdt.c | 2 +- cmd/abootimg.c | 24 ++++++++++++++++++++++-- include/image.h | 14 ++++++++------ 6 files changed, 76 insertions(+), 23 deletions(-)
Since this introduces the new formats (v3 and v4), can we also update the doc/android/boot-image.rst files which lists all the boot formats for android?
diff --git a/boot/bootm.c b/boot/bootm.c index a58e6f391e..3e130c175c 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,12 +185,17 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
map_sysmem() so it owrks on sandbox
} 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; break;
@@ -889,6 +898,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,8 +977,14 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
and here
} 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; break;
diff --git a/boot/image-android.c b/boot/image-android.c index edeeaaaee0..dd06c09279 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 -1;
Use proper error number. This is -EPERM which seems wrong. Perhaps -ENOTSUPP ?
}
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 b6c9bbe8f5..a20b57900e 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -426,10 +426,18 @@ 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)) {
ret = android_image_get_ramdisk((void *)get_abootimg_addr(),
map_sysmem() again. Or perhaps update that function to take an address?
(void *)get_avendor_bootimg_addr(),
rd_datap, rd_lenp);
} 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 f270d00a5f..5f9cf7b4e6 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 4d6cf0fa3e..ef7130da0b 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_vendor_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 ac94ecaa14..5bd4bf5d57 100644 --- a/include/image.h +++ b/include/image.h @@ -1739,29 +1739,31 @@ 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; -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); int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); -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); bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, u32 index, ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, const void *vendor_boot_img); -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); -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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); #endif -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +bool is_android_boot_image_header(const void *hdr); bool is_android_vendor_boot_image_header(const void *vendor_boot_img);
+ulong get_abootimg_addr(void); +ulong get_avendor_bootimg_addr(void);
again please add comments to all of these.
/**
- board_fit_config_name_match() - Check for a matching board name
-- 2.34.1
Regards, Simon

On 01/02/2023 09:44, Mattijs Korpershoek wrote:
On Thu, Jan 26, 2023 at 17:55, Simon Glass sjg@chromium.org wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This enables 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
"struct andr_boot_img_hdr_v0*" is replaced by "void *" in some functions since v3 and v4 are now supported as well.
Signed-off-by: Safae Ouajih souajih@baylibre.com
boot/bootm.c | 29 ++++++++++++++++++++++++----- boot/image-android.c | 16 ++++++++++------ boot/image-board.c | 14 +++++++++++--- boot/image-fdt.c | 2 +- cmd/abootimg.c | 24 ++++++++++++++++++++++-- include/image.h | 14 ++++++++------ 6 files changed, 76 insertions(+), 23 deletions(-)
Since this introduces the new formats (v3 and v4), can we also update the doc/android/boot-image.rst files which lists all the boot formats for android?
Hi Mattijs,
Thank you for the review,
I will update the documentation in a v3.
Best Regards,
Safae
diff --git a/boot/bootm.c b/boot/bootm.c index a58e6f391e..3e130c175c 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,12 +185,17 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
map_sysmem() so it owrks on sandbox
} 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; break;
@@ -889,6 +898,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,8 +977,14 @@ 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 = (void *)get_abootimg_addr();
vendor_boot_img = (void *)get_avendor_bootimg_addr();
and here
} 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; break;
diff --git a/boot/image-android.c b/boot/image-android.c index edeeaaaee0..dd06c09279 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 -1;
Use proper error number. This is -EPERM which seems wrong. Perhaps -ENOTSUPP ?
}
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 b6c9bbe8f5..a20b57900e 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -426,10 +426,18 @@ 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)) {
ret = android_image_get_ramdisk((void *)get_abootimg_addr(),
map_sysmem() again. Or perhaps update that function to take an address?
(void *)get_avendor_bootimg_addr(),
rd_datap, rd_lenp);
} 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 f270d00a5f..5f9cf7b4e6 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 4d6cf0fa3e..ef7130da0b 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_vendor_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 ac94ecaa14..5bd4bf5d57 100644 --- a/include/image.h +++ b/include/image.h @@ -1739,29 +1739,31 @@ 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; -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); int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, ulong *rd_data, ulong *rd_len); -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); bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, u32 index, ulong *addr, u32 *size); ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, const void *vendor_boot_img); -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); -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); void android_print_contents(const struct andr_boot_img_hdr_v0 *hdr); #ifdef CONFIG_CMD_ABOOTIMG bool android_image_print_dtb_contents(ulong hdr_addr); #endif -bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); +bool is_android_boot_image_header(const void *hdr); bool is_android_vendor_boot_image_header(const void *vendor_boot_img);
+ulong get_abootimg_addr(void); +ulong get_avendor_bootimg_addr(void);
again please add comments to all of these.
- /**
- board_fit_config_name_match() - Check for a matching board name
-- 2.34.1
Regards, Simon

This adds support for 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 souajih@baylibre.com --- boot/image-android.c | 58 +++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 11 ++++++++ 2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c index dd06c09279..5c2217676e 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_vendor_i 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_vendor_i
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 351e17750e..6e1afae4c0 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];
@@ -333,6 +341,9 @@ struct andr_image_data { ulong recovery_dtbo_ptr; u32 recovery_dtbo_size;
+ ulong bootconfig_addr; + ulong bootconfig_size; + const char *kcmdline; const char *kcmdline_extra; const char *image_name;

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for 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 souajih@baylibre.com
boot/image-android.c | 58 +++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 11 ++++++++ 2 files changed, 67 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
nit below
[..]
diff --git a/include/android_image.h b/include/android_image.h index 351e17750e..6e1afae4c0 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];
@@ -333,6 +341,9 @@ struct andr_image_data { ulong recovery_dtbo_ptr; u32 recovery_dtbo_size;
ulong bootconfig_addr;
ulong bootconfig_size;
const char *kcmdline; const char *kcmdline_extra; const char *image_name;
-- 2.34.1
That struct needs a full comment
REgards, Simon

On Thu, Jan 26, 2023 at 17:55, Simon Glass sjg@chromium.org wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
This adds support for 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 souajih@baylibre.com
boot/image-android.c | 58 +++++++++++++++++++++++++++++++++++++++-- include/android_image.h | 11 ++++++++ 2 files changed, 67 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com
nit below
[..]
diff --git a/include/android_image.h b/include/android_image.h index 351e17750e..6e1afae4c0 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];
@@ -333,6 +341,9 @@ struct andr_image_data { ulong recovery_dtbo_ptr; u32 recovery_dtbo_size;
ulong bootconfig_addr;
ulong bootconfig_size;
const char *kcmdline; const char *kcmdline_extra; const char *image_name;
-- 2.34.1
That struct needs a full comment
REgards, Simon

test_abootimg is extended to include the testing of boot images version 4. For this, boot.img and vendor_boot.img have been generated using mkbootimg tool with setting the header version to 4.
This tests: - Getting the header version using abootimg - Extracting the load address of the dtb - Extracting the dtb start address in RAM
Running test: $ ./test/py/test.py --bd sandbox --build -k test_abootimg
Signed-off-by: Safae Ouajih souajih@baylibre.com --- test/py/tests/test_android/test_abootimg.py | 135 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-)
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py index 43a7099c46..a5c734b9c5 100644 --- a/test/py/tests/test_android/test_abootimg.py +++ b/test/py/tests/test_android/test_abootimg.py @@ -32,6 +32,23 @@ Now one can obtain original boot.img from this hex dump like this:
$ xxd -r -p boot.img.gz.hex boot.img.gz $ gunzip -9 boot.img.gz + +For boot image header version 4, these tests rely on two images that are generated +using the same steps above : + +1- boot.img : + $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \ + --cmdline "cmdline test" --dtb ./dtb.img \ + --os_version R --os_patch_level 2019-06-05 \ + --header_version 4 --output ./boot.img + +2- vendor_boot.img + $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \ + --cmdline "cmdline test" --dtb ./dtb.img \ + --os_version R --os_patch_level 2019-06-05 \ + --pagesize 4096 --vendor_ramdisk ./ramdisk.img \ + --header_version 4 --vendor_boot ./vboot.img \ + """
# boot.img.gz hex dump @@ -44,6 +61,24 @@ b7762ffff07d345446c1281805e8a0868d81e117a45e111c0d8dc101b253 9c03c41a0c90f17fe85400986d82452b6c3680198a192a0ce17c3610ae34 d4a9820881a70f3873f35352731892f3730b124b32937252a96bb9119ae5 463a5546f82c1f05a360148c8251300a462e000085bf67f200200000""" + +# boot img v4 hex dump +boot_img_hex = """1f8b080827b0cd630203626f6f742e696d6700edd8bd0d82601885d1d7c4 +58d8c808b88195bd098d8d246e40e42b083f1aa0717be99d003d277916b8 +e5bddc8a7b792d8e8788c896ce9b88d32ebe6c971e7ddd3543cae734cd01 +c0ffc84c0000b0766d1a87d4e5afeadd3dab7a6f10000000f84163d5d7cd +d43a000000000000000060c53e7544995700400000""" + +# vendor boot image v4 hex dump +vboot_img_hex = """1f8b0808baaecd63020376626f6f742e696d6700edd8310b824018c6f1b3 +222a08f41b3436b4280dcdd19c11d16ee9109d18d59042d047ec8b04cd0d +d19d5a4345534bf6ffc173ef29272f38e93b1d0ec67dd79d548462aa1cd2 +d5d20b0000f8438678f90c18d584b8a4bbb3a557991ecb2a0000f80d6b2f +f4179b656be5c532f2fc066f040000000080e23936af2755f62a3d918df1 +db2a7ab67f9ffdeb7df7cda3465ecb79c4ce7e5c577562bb9364b74449a5 +1e467e20c53c0a57de763193c1779b3b4fcd9d4ee27c6a0e00000000c0ff +309ffea7010000000040f1dc004129855400400000""" + # Expected response for "abootimg dtb_dump" command dtb_dump_resp="""## DTB area contents (concat format): - DTB #0: @@ -56,15 +91,21 @@ dtb_dump_resp="""## DTB area contents (concat format): (DTB)compatible = y2,z2""" # Address in RAM where to load the boot image ('abootimg' looks in $loadaddr) loadaddr = 0x1000 +# Address in RAM where to load the vendor boot image ('abootimg' looks in $vloadaddr) +vloadaddr= 0x10000 # Expected DTB #1 offset from the boot image start address dtb1_offset = 0x187d +# Expected DTB offset from the vendor boot image start address +dtb2_offset = 0x207d # DTB #1 start address in RAM dtb1_addr = loadaddr + dtb1_offset +# DTB #2 start address in RAM +dtb2_addr = vloadaddr + dtb2_offset
class AbootimgTestDiskImage(object): """Disk image used by abootimg tests."""
- def __init__(self, u_boot_console): + def __init__(self, u_boot_console, image_name, hex_img): """Initialize a new AbootimgDiskImage object.
Args: @@ -74,13 +115,13 @@ class AbootimgTestDiskImage(object): Nothing. """
- gz_hex = u_boot_console.config.persistent_data_dir + '/boot.img.gz.hex' - gz = u_boot_console.config.persistent_data_dir + '/boot.img.gz' + gz_hex = u_boot_console.config.persistent_data_dir + '/' + image_name + '.gz.hex' + gz = u_boot_console.config.persistent_data_dir + '/' + image_name + '.gz'
- filename = 'boot.img' + filename = image_name persistent = u_boot_console.config.persistent_data_dir + '/' + filename self.path = u_boot_console.config.result_dir + '/' + filename - + u_boot_console.log.action('persistent is ' + persistent) with u_boot_utils.persistent_file_helper(u_boot_console.log, persistent): if os.path.exists(persistent): u_boot_console.log.action('Disk image file ' + persistent + @@ -89,19 +130,17 @@ class AbootimgTestDiskImage(object): u_boot_console.log.action('Generating ' + persistent)
f = open(gz_hex, "w") - f.write(img_hex) + f.write(hex_img) f.close() - cmd = ('xxd', '-r', '-p', gz_hex, gz) u_boot_utils.run_and_log(u_boot_console, cmd) - cmd = ('gunzip', '-9', gz) u_boot_utils.run_and_log(u_boot_console, cmd)
cmd = ('cp', persistent, self.path) u_boot_utils.run_and_log(u_boot_console, cmd)
-gtdi = None +gtdi1 = None @pytest.fixture(scope='function') def abootimg_disk_image(u_boot_console): """pytest fixture to provide a AbootimgTestDiskImage object to tests. @@ -109,10 +148,36 @@ def abootimg_disk_image(u_boot_console): function-scoped. However, we don't need to actually do any function-scope work, so this simply returns the same object over and over each time."""
- global gtdi - if not gtdi: - gtdi = AbootimgTestDiskImage(u_boot_console) - return gtdi + global gtdi1 + if not gtdi1: + gtdi1 = AbootimgTestDiskImage(u_boot_console, 'boot.img', img_hex) + return gtdi1 + +gtdi2 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_vboot(u_boot_console): + """pytest fixture to provide a AbootimgTestDiskImage object to tests. + This is function-scoped because it uses u_boot_console, which is also + function-scoped. However, we don't need to actually do any function-scope + work, so this simply returns the same object over and over each time.""" + + global gtdi2 + if not gtdi2: + gtdi2 = AbootimgTestDiskImage(u_boot_console, 'vendor_boot.img', vboot_img_hex) + return gtdi2 + +gtdi3 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_boot(u_boot_console): + """pytest fixture to provide a AbootimgTestDiskImage object to tests. + This is function-scoped because it uses u_boot_console, which is also + function-scoped. However, we don't need to actually do any function-scope + work, so this simply returns the same object over and over each time.""" + + global gtdi3 + if not gtdi3: + gtdi3 = AbootimgTestDiskImage(u_boot_console, 'bootv4.img', boot_img_hex) + return gtdi3
@pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('android_boot_image') @@ -157,3 +222,47 @@ def test_abootimg(abootimg_disk_image, u_boot_console): u_boot_console.run_command('fdt get value v / model') response = u_boot_console.run_command('env print v') assert response == 'v=x2' + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('android_boot_image') +@pytest.mark.buildconfigspec('cmd_abootimg') +@pytest.mark.buildconfigspec('cmd_fdt') +@pytest.mark.requiredtool('xxd') +@pytest.mark.requiredtool('gunzip') +def test_abootimgv4(abootimgv4_disk_image_vboot, abootimgv4_disk_image_boot, u_boot_console): + """Test the 'abootimg' command with boot image header v4.""" + + u_boot_console.log.action('Loading disk image to RAM...') + u_boot_console.run_command('setenv loadaddr 0x%x' % (loadaddr)) + u_boot_console.run_command('setenv vloadaddr 0x%x' % (vloadaddr)) + u_boot_console.run_command('host load hostfs - 0x%x %s' % (vloadaddr, + abootimgv4_disk_image_vboot.path)) + u_boot_console.run_command('host load hostfs - 0x%x %s' % (loadaddr, + abootimgv4_disk_image_boot.path)) + u_boot_console.run_command('abootimg addr 0x%x 0x%x' % (loadaddr, vloadaddr)) + u_boot_console.log.action('Testing 'abootimg get ver'...') + response = u_boot_console.run_command('abootimg get ver') + assert response == "4" + u_boot_console.run_command('abootimg get ver v') + response = u_boot_console.run_command('env print v') + assert response == 'v=4' + + u_boot_console.log.action('Testing 'abootimg get recovery_dtbo'...') + response = u_boot_console.run_command('abootimg get recovery_dtbo a') + assert response == 'Error: header version must be >= 1 and <= 2 to get dtbo' + + u_boot_console.log.action('Testing 'abootimg get dtb_load_addr'...') + u_boot_console.run_command('abootimg get dtb_load_addr a') + response = u_boot_console.run_command('env print a') + assert response == 'a=11f00000' + + u_boot_console.log.action('Testing 'abootimg get dtb --index'...') + u_boot_console.run_command('abootimg get dtb --index=1 dtb2_start') + response = u_boot_console.run_command('env print dtb2_start') + correct_str = "dtb2_start=%x" % (dtb2_addr) + assert response == correct_str + + u_boot_console.run_command('fdt addr $dtb2_start') + u_boot_console.run_command('fdt get value v / model') + response = u_boot_console.run_command('env print v') + assert response == 'v=x2'

Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
test_abootimg is extended to include the testing of boot images version 4. For this, boot.img and vendor_boot.img have been generated using mkbootimg tool with setting the header version to 4.
This tests:
- Getting the header version using abootimg
- Extracting the load address of the dtb
- Extracting the dtb start address in RAM
Running test: $ ./test/py/test.py --bd sandbox --build -k test_abootimg
Signed-off-by: Safae Ouajih souajih@baylibre.com
test/py/tests/test_android/test_abootimg.py | 135 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Question below
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py index 43a7099c46..a5c734b9c5 100644 --- a/test/py/tests/test_android/test_abootimg.py +++ b/test/py/tests/test_android/test_abootimg.py @@ -32,6 +32,23 @@ Now one can obtain original boot.img from this hex dump like this:
$ xxd -r -p boot.img.gz.hex boot.img.gz $ gunzip -9 boot.img.gz
+For boot image header version 4, these tests rely on two images that are generated +using the same steps above :
+1- boot.img :
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--header_version 4 --output ./boot.img
+2- vendor_boot.img
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--pagesize 4096 --vendor_ramdisk ./ramdisk.img \
--header_version 4 --vendor_boot ./vboot.img \
Is it possible for us to run these commands in the test, to avoid hassle when we want to change the disk image? See test_ut.py
"""
# boot.img.gz hex dump @@ -44,6 +61,24 @@ b7762ffff07d345446c1281805e8a0868d81e117a45e111c0d8dc101b253 9c03c41a0c90f17fe85400986d82452b6c3680198a192a0ce17c3610ae34 d4a9820881a70f3873f35352731892f3730b124b32937252a96bb9119ae5 463a5546f82c1f05a360148c8251300a462e000085bf67f200200000"""
+# boot img v4 hex dump +boot_img_hex = """1f8b080827b0cd630203626f6f742e696d6700edd8bd0d82601885d1d7c4 +58d8c808b88195bd098d8d246e40e42b083f1aa0717be99d003d277916b8 +e5bddc8a7b792d8e8788c896ce9b88d32ebe6c971e7ddd3543cae734cd01 +c0ffc84c0000b0766d1a87d4e5afeadd3dab7a6f10000000f84163d5d7cd +d43a000000000000000060c53e7544995700400000"""
+# vendor boot image v4 hex dump +vboot_img_hex = """1f8b0808baaecd63020376626f6f742e696d6700edd8310b824018c6f1b3 +222a08f41b3436b4280dcdd19c11d16ee9109d18d59042d047ec8b04cd0d +d19d5a4345534bf6ffc173ef29272f38e93b1d0ec67dd79d548462aa1cd2 +d5d20b0000f8438678f90c18d584b8a4bbb3a557991ecb2a0000f80d6b2f +f4179b656be5c532f2fc066f040000000080e23936af2755f62a3d918df1 +db2a7ab67f9ffdeb7df7cda3465ecb79c4ce7e5c577562bb9364b74449a5 +1e467e20c53c0a57de763193c1779b3b4fcd9d4ee27c6a0e00000000c0ff +309ffea7010000000040f1dc004129855400400000"""
[..]
-gtdi = None +gtdi1 = None @pytest.fixture(scope='function') def abootimg_disk_image(u_boot_console): """pytest fixture to provide a AbootimgTestDiskImage object to tests. @@ -109,10 +148,36 @@ def abootimg_disk_image(u_boot_console): function-scoped. However, we don't need to actually do any function-scope work, so this simply returns the same object over and over each time."""
- global gtdi
- if not gtdi:
gtdi = AbootimgTestDiskImage(u_boot_console)
- return gtdi
- global gtdi1
- if not gtdi1:
gtdi1 = AbootimgTestDiskImage(u_boot_console, 'boot.img', img_hex)
- return gtdi1
+gtdi2 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_vboot(u_boot_console):
- """pytest fixture to provide a AbootimgTestDiskImage object to tests.
- This is function-scoped because it uses u_boot_console, which is also
- function-scoped. However, we don't need to actually do any function-scope
- work, so this simply returns the same object over and over each time."""
- global gtdi2
- if not gtdi2:
gtdi2 = AbootimgTestDiskImage(u_boot_console, 'vendor_boot.img', vboot_img_hex)
- return gtdi2
+gtdi3 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_boot(u_boot_console):
- """pytest fixture to provide a AbootimgTestDiskImage object to tests.
blank line here (please fix throughout)
- This is function-scoped because it uses u_boot_console, which is also
- function-scoped. However, we don't need to actually do any function-scope
- work, so this simply returns the same object over and over each time."""
- global gtdi3
- if not gtdi3:
gtdi3 = AbootimgTestDiskImage(u_boot_console, 'bootv4.img', boot_img_hex)
- return gtdi3
@pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('android_boot_image') @@ -157,3 +222,47 @@ def test_abootimg(abootimg_disk_image, u_boot_console): u_boot_console.run_command('fdt get value v / model') response = u_boot_console.run_command('env print v') assert response == 'v=x2'
+@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('android_boot_image') +@pytest.mark.buildconfigspec('cmd_abootimg') +@pytest.mark.buildconfigspec('cmd_fdt') +@pytest.mark.requiredtool('xxd') +@pytest.mark.requiredtool('gunzip') +def test_abootimgv4(abootimgv4_disk_image_vboot, abootimgv4_disk_image_boot, u_boot_console):
- """Test the 'abootimg' command with boot image header v4."""
- u_boot_console.log.action('Loading disk image to RAM...')
Can you put u_boot_console in a var like 'cons' to make it less verbose?
- u_boot_console.run_command('setenv loadaddr 0x%x' % (loadaddr))
- u_boot_console.run_command('setenv vloadaddr 0x%x' % (vloadaddr))
- u_boot_console.run_command('host load hostfs - 0x%x %s' % (vloadaddr,
abootimgv4_disk_image_vboot.path))
- u_boot_console.run_command('host load hostfs - 0x%x %s' % (loadaddr,
abootimgv4_disk_image_boot.path))
- u_boot_console.run_command('abootimg addr 0x%x 0x%x' % (loadaddr, vloadaddr))
- u_boot_console.log.action('Testing 'abootimg get ver'...')
- response = u_boot_console.run_command('abootimg get ver')
- assert response == "4"
- u_boot_console.run_command('abootimg get ver v')
- response = u_boot_console.run_command('env print v')
- assert response == 'v=4'
- u_boot_console.log.action('Testing 'abootimg get recovery_dtbo'...')
- response = u_boot_console.run_command('abootimg get recovery_dtbo a')
- assert response == 'Error: header version must be >= 1 and <= 2 to get dtbo'
- u_boot_console.log.action('Testing 'abootimg get dtb_load_addr'...')
- u_boot_console.run_command('abootimg get dtb_load_addr a')
- response = u_boot_console.run_command('env print a')
- assert response == 'a=11f00000'
- u_boot_console.log.action('Testing 'abootimg get dtb --index'...')
- u_boot_console.run_command('abootimg get dtb --index=1 dtb2_start')
- response = u_boot_console.run_command('env print dtb2_start')
- correct_str = "dtb2_start=%x" % (dtb2_addr)
- assert response == correct_str
- u_boot_console.run_command('fdt addr $dtb2_start')
- u_boot_console.run_command('fdt get value v / model')
- response = u_boot_console.run_command('env print v')
- assert response == 'v=x2'
-- 2.34.1
Regards, Simon

On 27/01/2023 01:55, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
test_abootimg is extended to include the testing of boot images version 4. For this, boot.img and vendor_boot.img have been generated using mkbootimg tool with setting the header version to 4.
This tests:
- Getting the header version using abootimg
- Extracting the load address of the dtb
- Extracting the dtb start address in RAM
Running test: $ ./test/py/test.py --bd sandbox --build -k test_abootimg
Signed-off-by: Safae Ouajih souajih@baylibre.com
test/py/tests/test_android/test_abootimg.py | 135 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Question below
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py index 43a7099c46..a5c734b9c5 100644 --- a/test/py/tests/test_android/test_abootimg.py +++ b/test/py/tests/test_android/test_abootimg.py @@ -32,6 +32,23 @@ Now one can obtain original boot.img from this hex dump like this:
$ xxd -r -p boot.img.gz.hex boot.img.gz $ gunzip -9 boot.img.gz
+For boot image header version 4, these tests rely on two images that are generated +using the same steps above :
+1- boot.img :
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--header_version 4 --output ./boot.img
+2- vendor_boot.img
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--pagesize 4096 --vendor_ramdisk ./ramdisk.img \
--header_version 4 --vendor_boot ./vboot.img \
Is it possible for us to run these commands in the test, to avoid hassle when we want to change the disk image? See test_ut.py
Hi Simon,
I think that it is possible to run these commands in the test. However,
this requires adding "mkbootimg" android tool with the last updates
to generate the new vendor boot image and boot image with header version 4.
I think this change may come as an update for the whole test_abootimg later.
"""
# boot.img.gz hex dump
@@ -44,6 +61,24 @@ b7762ffff07d345446c1281805e8a0868d81e117a45e111c0d8dc101b253 9c03c41a0c90f17fe85400986d82452b6c3680198a192a0ce17c3610ae34 d4a9820881a70f3873f35352731892f3730b124b32937252a96bb9119ae5 463a5546f82c1f05a360148c8251300a462e000085bf67f200200000"""
+# boot img v4 hex dump +boot_img_hex = """1f8b080827b0cd630203626f6f742e696d6700edd8bd0d82601885d1d7c4 +58d8c808b88195bd098d8d246e40e42b083f1aa0717be99d003d277916b8 +e5bddc8a7b792d8e8788c896ce9b88d32ebe6c971e7ddd3543cae734cd01 +c0ffc84c0000b0766d1a87d4e5afeadd3dab7a6f10000000f84163d5d7cd +d43a000000000000000060c53e7544995700400000"""
+# vendor boot image v4 hex dump +vboot_img_hex = """1f8b0808baaecd63020376626f6f742e696d6700edd8310b824018c6f1b3 +222a08f41b3436b4280dcdd19c11d16ee9109d18d59042d047ec8b04cd0d +d19d5a4345534bf6ffc173ef29272f38e93b1d0ec67dd79d548462aa1cd2 +d5d20b0000f8438678f90c18d584b8a4bbb3a557991ecb2a0000f80d6b2f +f4179b656be5c532f2fc066f040000000080e23936af2755f62a3d918df1 +db2a7ab67f9ffdeb7df7cda3465ecb79c4ce7e5c577562bb9364b74449a5 +1e467e20c53c0a57de763193c1779b3b4fcd9d4ee27c6a0e00000000c0ff +309ffea7010000000040f1dc004129855400400000"""
[..]
-gtdi = None +gtdi1 = None @pytest.fixture(scope='function') def abootimg_disk_image(u_boot_console): """pytest fixture to provide a AbootimgTestDiskImage object to tests. @@ -109,10 +148,36 @@ def abootimg_disk_image(u_boot_console): function-scoped. However, we don't need to actually do any function-scope work, so this simply returns the same object over and over each time."""
- global gtdi
- if not gtdi:
gtdi = AbootimgTestDiskImage(u_boot_console)
- return gtdi
- global gtdi1
- if not gtdi1:
gtdi1 = AbootimgTestDiskImage(u_boot_console, 'boot.img', img_hex)
- return gtdi1
+gtdi2 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_vboot(u_boot_console):
- """pytest fixture to provide a AbootimgTestDiskImage object to tests.
- This is function-scoped because it uses u_boot_console, which is also
- function-scoped. However, we don't need to actually do any function-scope
- work, so this simply returns the same object over and over each time."""
- global gtdi2
- if not gtdi2:
gtdi2 = AbootimgTestDiskImage(u_boot_console, 'vendor_boot.img', vboot_img_hex)
- return gtdi2
+gtdi3 = None +@pytest.fixture(scope='function') +def abootimgv4_disk_image_boot(u_boot_console):
- """pytest fixture to provide a AbootimgTestDiskImage object to tests.
blank line here (please fix throughout)
This is function-scoped because it uses u_boot_console, which is also
function-scoped. However, we don't need to actually do any function-scope
work, so this simply returns the same object over and over each time."""
global gtdi3
if not gtdi3:
gtdi3 = AbootimgTestDiskImage(u_boot_console, 'bootv4.img', boot_img_hex)
return gtdi3
@pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('android_boot_image')
@@ -157,3 +222,47 @@ def test_abootimg(abootimg_disk_image, u_boot_console): u_boot_console.run_command('fdt get value v / model') response = u_boot_console.run_command('env print v') assert response == 'v=x2'
+@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('android_boot_image') +@pytest.mark.buildconfigspec('cmd_abootimg') +@pytest.mark.buildconfigspec('cmd_fdt') +@pytest.mark.requiredtool('xxd') +@pytest.mark.requiredtool('gunzip') +def test_abootimgv4(abootimgv4_disk_image_vboot, abootimgv4_disk_image_boot, u_boot_console):
- """Test the 'abootimg' command with boot image header v4."""
- u_boot_console.log.action('Loading disk image to RAM...')
Can you put u_boot_console in a var like 'cons' to make it less verbose?
I will try to add this change and all the remarks/fixes
you have pointed out earlier in a v3.
Thank you for the review,
--safae
- u_boot_console.run_command('setenv loadaddr 0x%x' % (loadaddr))
- u_boot_console.run_command('setenv vloadaddr 0x%x' % (vloadaddr))
- u_boot_console.run_command('host load hostfs - 0x%x %s' % (vloadaddr,
abootimgv4_disk_image_vboot.path))
- u_boot_console.run_command('host load hostfs - 0x%x %s' % (loadaddr,
abootimgv4_disk_image_boot.path))
- u_boot_console.run_command('abootimg addr 0x%x 0x%x' % (loadaddr, vloadaddr))
- u_boot_console.log.action('Testing 'abootimg get ver'...')
- response = u_boot_console.run_command('abootimg get ver')
- assert response == "4"
- u_boot_console.run_command('abootimg get ver v')
- response = u_boot_console.run_command('env print v')
- assert response == 'v=4'
- u_boot_console.log.action('Testing 'abootimg get recovery_dtbo'...')
- response = u_boot_console.run_command('abootimg get recovery_dtbo a')
- assert response == 'Error: header version must be >= 1 and <= 2 to get dtbo'
- u_boot_console.log.action('Testing 'abootimg get dtb_load_addr'...')
- u_boot_console.run_command('abootimg get dtb_load_addr a')
- response = u_boot_console.run_command('env print a')
- assert response == 'a=11f00000'
- u_boot_console.log.action('Testing 'abootimg get dtb --index'...')
- u_boot_console.run_command('abootimg get dtb --index=1 dtb2_start')
- response = u_boot_console.run_command('env print dtb2_start')
- correct_str = "dtb2_start=%x" % (dtb2_addr)
- assert response == correct_str
- u_boot_console.run_command('fdt addr $dtb2_start')
- u_boot_console.run_command('fdt get value v / model')
- response = u_boot_console.run_command('env print v')
- assert response == 'v=x2'
-- 2.34.1
Regards, Simon

On Fri, Jan 27, 2023 at 04:51:41PM +0100, Safae Ouajih wrote:
On 27/01/2023 01:55, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
test_abootimg is extended to include the testing of boot images version 4. For this, boot.img and vendor_boot.img have been generated using mkbootimg tool with setting the header version to 4.
This tests:
- Getting the header version using abootimg
- Extracting the load address of the dtb
- Extracting the dtb start address in RAM
Running test: $ ./test/py/test.py --bd sandbox --build -k test_abootimg
Signed-off-by: Safae Ouajih souajih@baylibre.com
test/py/tests/test_android/test_abootimg.py | 135 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Question below
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py index 43a7099c46..a5c734b9c5 100644 --- a/test/py/tests/test_android/test_abootimg.py +++ b/test/py/tests/test_android/test_abootimg.py @@ -32,6 +32,23 @@ Now one can obtain original boot.img from this hex dump like this:
$ xxd -r -p boot.img.gz.hex boot.img.gz $ gunzip -9 boot.img.gz
+For boot image header version 4, these tests rely on two images that are generated +using the same steps above :
+1- boot.img :
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--header_version 4 --output ./boot.img
+2- vendor_boot.img
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--pagesize 4096 --vendor_ramdisk ./ramdisk.img \
--header_version 4 --vendor_boot ./vboot.img \
Is it possible for us to run these commands in the test, to avoid hassle when we want to change the disk image? See test_ut.py
Hi Simon,
I think that it is possible to run these commands in the test. However,
this requires adding "mkbootimg" android tool with the last updates
Please update tools/docker/Dockerfile to include this tool then, so we can run it in CI (or locally using the images).

On 27/01/2023 21:37, Tom Rini wrote:
On Fri, Jan 27, 2023 at 04:51:41PM +0100, Safae Ouajih wrote:
On 27/01/2023 01:55, Simon Glass wrote:
Hi Safae,
On Thu, 26 Jan 2023 at 09:05, Safae Ouajih souajih@baylibre.com wrote:
test_abootimg is extended to include the testing of boot images version 4. For this, boot.img and vendor_boot.img have been generated using mkbootimg tool with setting the header version to 4.
This tests:
- Getting the header version using abootimg
- Extracting the load address of the dtb
- Extracting the dtb start address in RAM
Running test: $ ./test/py/test.py --bd sandbox --build -k test_abootimg
Signed-off-by: Safae Ouajih souajih@baylibre.com
test/py/tests/test_android/test_abootimg.py | 135 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Question below
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py index 43a7099c46..a5c734b9c5 100644 --- a/test/py/tests/test_android/test_abootimg.py +++ b/test/py/tests/test_android/test_abootimg.py @@ -32,6 +32,23 @@ Now one can obtain original boot.img from this hex dump like this:
$ xxd -r -p boot.img.gz.hex boot.img.gz $ gunzip -9 boot.img.gz
+For boot image header version 4, these tests rely on two images that are generated +using the same steps above :
+1- boot.img :
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--header_version 4 --output ./boot.img
+2- vendor_boot.img
- $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
--cmdline "cmdline test" --dtb ./dtb.img \
--os_version R --os_patch_level 2019-06-05 \
--pagesize 4096 --vendor_ramdisk ./ramdisk.img \
--header_version 4 --vendor_boot ./vboot.img \
Is it possible for us to run these commands in the test, to avoid hassle when we want to change the disk image? See test_ut.py
Hi Simon,
I think that it is possible to run these commands in the test. However,
this requires adding "mkbootimg" android tool with the last updates
Please update tools/docker/Dockerfile to include this tool then, so we can run it in CI (or locally using the images).
Hello Tom,
I will add a patch to add that tool in a v3.
Thank you,
Best regards,
Safae

чт, 26 янв. 2023 г. в 18:05, Safae Ouajih souajih@baylibre.com:
Hello everyone,
This is based on Roman Stratiienko's work to support boot image header version 3 and 4.
This supports the new boot image headers v3, v4 and bootconfig feature.
https://source.android.com/docs/core/architecture/bootloader/boot-image-head... https://source.android.com/docs/core/architecture/bootloader/implementing-bo...
Tested on Amlogic Khadas vim3l, a reference board for Android Open Source Project https://www.khadas.com/vim3l
And on AM625 Texas Instruments board with 5.10 linux kernel
Main changes :
- New partition : vendor boot, with a specific vendor ramdisk
- DTB is stored in the vendor boot partition
- The generic ramdisk is placed after the vendor ramdisk
- Bootconfig feature support
Here is a link to see the related android boot flow changes on KHADAS vim3l as an example: https://gitlab.baylibre.com/baylibre/amlogic/atv/u-boot/-/commits/souajih/Bo...
Changes in v2:
- Rework parts of the code to fix the abootimg test: test_abootimg
- Update test_abootimg to support boot image header v4
- Remove LIBXBC library, import and adapt the functions to support bootconfig feature
- Rename the used structures : andr_boot_img_hdr_v0_v1_v2 -> andr_boot_img_hdr_v0 andr_boot_img_hdr_v3_v4 -> andr_boot_img_hdr_v3 andr_vendor_boot_img_hdr_v3_v4 -> andr_vendor_img_hdr
Hello,
Thanks for these patches.
Please note that Android has both vendor.img and boot_vendor.img I would suggest adding some prefix, e.g. andr_bootvnd_img_hdr or something similar.
Safae Ouajih (17): android: boot: rename andr_img_hdr -> andr_boot_img_hdr_v0 android: boot: support vendor boot image in abootimg android: boot: replace android_image_check_header android: boot: add boot image header v3 and v4 structures android: boot: kcomp: support andr_image_data android: boot: move to andr_image_data structure android: boot: content print is not supported for v3,v4 header version android: boot: boot image header v3,v4 do not support recovery DTBO android: boot: add vendor boot image to prepare for v3,v4 support android: boot: update android_image_get_data to support v3,v4 android: boot: ramdisk: support vendor ramdisk android: boot: support extra command line android: boot: update android_image_get_dtb_img_addr to support v3,v4 drivers: fastboot: zImage flashing is not supported for v3,v4 android: boot: support boot image header version 3 and 4 android: boot: support bootconfig test/py: android: extend abootimg test
boot/bootm.c | 29 +- boot/image-android.c | 467 ++++++++++++++++---- boot/image-board.c | 15 +- boot/image-fdt.c | 5 +- cmd/abootimg.c | 75 +++- drivers/fastboot/fb_mmc.c | 19 +- include/android_image.h | 228 +++++++++- include/image.h | 37 +- test/py/tests/test_android/test_abootimg.py | 135 +++++- 9 files changed, 850 insertions(+), 160 deletions(-)
-- 2.34.1

On 26/01/2023 19:17, Roman Stratiienko wrote:
чт, 26 янв. 2023 г. в 18:05, Safae Ouajih souajih@baylibre.com:
Hello everyone,
This is based on Roman Stratiienko's work to support boot image header version 3 and 4.
This supports the new boot image headers v3, v4 and bootconfig feature.
https://source.android.com/docs/core/architecture/bootloader/boot-image-head... https://source.android.com/docs/core/architecture/bootloader/implementing-bo...
Tested on Amlogic Khadas vim3l, a reference board for Android Open Source Project https://www.khadas.com/vim3l
And on AM625 Texas Instruments board with 5.10 linux kernel
Main changes :
- New partition : vendor boot, with a specific vendor ramdisk
- DTB is stored in the vendor boot partition
- The generic ramdisk is placed after the vendor ramdisk
- Bootconfig feature support
Here is a link to see the related android boot flow changes on KHADAS vim3l as an example: https://gitlab.baylibre.com/baylibre/amlogic/atv/u-boot/-/commits/souajih/Bo...
Changes in v2:
- Rework parts of the code to fix the abootimg test: test_abootimg
- Update test_abootimg to support boot image header v4
- Remove LIBXBC library, import and adapt the functions to support bootconfig feature
- Rename the used structures : andr_boot_img_hdr_v0_v1_v2 -> andr_boot_img_hdr_v0 andr_boot_img_hdr_v3_v4 -> andr_boot_img_hdr_v3 andr_vendor_boot_img_hdr_v3_v4 -> andr_vendor_img_hdr
Hello,
Thanks for these patches.
Please note that Android has both vendor.img and boot_vendor.img I would suggest adding some prefix, e.g. andr_bootvnd_img_hdr or something similar.
Hello,
Thank you for your remark.
Indeed " struct andr_vendor_img_hdr " can be confusing.
To differentiate vendor.img and vendor_boot.img I will make the following changed in a v3:
struct andr_vendor_img_hdr -> struct andr_vnd_boot_img_hdr
Best regards,
--safae
Safae Ouajih (17): android: boot: rename andr_img_hdr -> andr_boot_img_hdr_v0 android: boot: support vendor boot image in abootimg android: boot: replace android_image_check_header android: boot: add boot image header v3 and v4 structures android: boot: kcomp: support andr_image_data android: boot: move to andr_image_data structure android: boot: content print is not supported for v3,v4 header version android: boot: boot image header v3,v4 do not support recovery DTBO android: boot: add vendor boot image to prepare for v3,v4 support android: boot: update android_image_get_data to support v3,v4 android: boot: ramdisk: support vendor ramdisk android: boot: support extra command line android: boot: update android_image_get_dtb_img_addr to support v3,v4 drivers: fastboot: zImage flashing is not supported for v3,v4 android: boot: support boot image header version 3 and 4 android: boot: support bootconfig test/py: android: extend abootimg test
boot/bootm.c | 29 +- boot/image-android.c | 467 ++++++++++++++++---- boot/image-board.c | 15 +- boot/image-fdt.c | 5 +- cmd/abootimg.c | 75 +++- drivers/fastboot/fb_mmc.c | 19 +- include/android_image.h | 228 +++++++++- include/image.h | 37 +- test/py/tests/test_android/test_abootimg.py | 135 +++++- 9 files changed, 850 insertions(+), 160 deletions(-)
-- 2.34.1

On Thu, Jan 26, 2023 at 17:04, Safae Ouajih souajih@baylibre.com wrote:
Hello everyone,
This is based on Roman Stratiienko's work to support boot image header version 3 and 4.
This supports the new boot image headers v3, v4 and bootconfig feature.
https://source.android.com/docs/core/architecture/bootloader/boot-image-head... https://source.android.com/docs/core/architecture/bootloader/implementing-bo...
Tested on Amlogic Khadas vim3l, a reference board for Android Open Source Project https://www.khadas.com/vim3l
And on AM625 Texas Instruments board with 5.10 linux kernel
Main changes :
- New partition : vendor boot, with a specific vendor ramdisk
- DTB is stored in the vendor boot partition
- The generic ramdisk is placed after the vendor ramdisk
- Bootconfig feature support
Here is a link to see the related android boot flow changes on KHADAS vim3l as an example: https://gitlab.baylibre.com/baylibre/amlogic/atv/u-boot/-/commits/souajih/Bo...
Changes in v2:
- Rework parts of the code to fix the abootimg test: test_abootimg
- Update test_abootimg to support boot image header v4
- Remove LIBXBC library, import and adapt the functions to support bootconfig feature
- Rename the used structures : andr_boot_img_hdr_v0_v1_v2 -> andr_boot_img_hdr_v0 andr_boot_img_hdr_v3_v4 -> andr_boot_img_hdr_v3 andr_vendor_boot_img_hdr_v3_v4 -> andr_vendor_img_hdr
Re-tested the whole series on Khadas vim3l board with boot header v2.
Tested-by: Mattijs Korpershoek mkorpershoek@baylibre.com
Safae Ouajih (17): android: boot: rename andr_img_hdr -> andr_boot_img_hdr_v0 android: boot: support vendor boot image in abootimg android: boot: replace android_image_check_header android: boot: add boot image header v3 and v4 structures android: boot: kcomp: support andr_image_data android: boot: move to andr_image_data structure android: boot: content print is not supported for v3,v4 header version android: boot: boot image header v3,v4 do not support recovery DTBO android: boot: add vendor boot image to prepare for v3,v4 support android: boot: update android_image_get_data to support v3,v4 android: boot: ramdisk: support vendor ramdisk android: boot: support extra command line android: boot: update android_image_get_dtb_img_addr to support v3,v4 drivers: fastboot: zImage flashing is not supported for v3,v4 android: boot: support boot image header version 3 and 4 android: boot: support bootconfig test/py: android: extend abootimg test
boot/bootm.c | 29 +- boot/image-android.c | 467 ++++++++++++++++---- boot/image-board.c | 15 +- boot/image-fdt.c | 5 +- cmd/abootimg.c | 75 +++- drivers/fastboot/fb_mmc.c | 19 +- include/android_image.h | 228 +++++++++- include/image.h | 37 +- test/py/tests/test_android/test_abootimg.py | 135 +++++- 9 files changed, 850 insertions(+), 160 deletions(-)
-- 2.34.1
participants (5)
-
Mattijs Korpershoek
-
Roman Stratiienko
-
Safae Ouajih
-
Simon Glass
-
Tom Rini