Hi all, On Mon, Apr 28, 2025 at 12:41 PM Alice Guo (OSS) <alice....@oss.nxp.com> wrote: > > From: Alice Guo <alice....@nxp.com> > > i.MX95 uses binman to invoke mkimage to create image container. 2 image > containers are needed currently. The first one is composed of > ahab-container.img, LPDDR firmware images, OEI images, System Manager > image and u-boot-spl.bin. The second one is consisted of ARM Trusted > firmware and u-boot.bin. > > Because DDR OEI image and LPDDR firmware images have to be packaged > together and named as m33-oei-ddrfw.bin by binman, so imx9_image.sh does > not check if m33-oei-ddrfw.bin exists. > > When using "make imx95_19x19_evk_defconfig; make", imx9_image.sh will > delete the line for u-boot.bin in container.cfg. In fact, binman is > always called after the u-boot.bin is built, so imx9_image.sh does not > check if u-boot.bin exists. > > Signed-off-by: Alice Guo <alice....@nxp.com>
I bisected a problem with the current mainline with the imx8qxp_mek board and seems to point to that patch. After this patch, I'm getting the following errors when u-boot creates the flash.bin binary. error writing image hdr 400 MKIMAGE flash.bin The resulting binary seems to not work. Reverting that patch helps to make bootable the board again. The u-boot log is: .... MKIMAGE u-boot.cnt 1+0 records in 1+0 records out 33792 bytes (34 kB, 33 KiB) copied, 6.5088e-05 s, 519 MB/s 64+1 records in 64+1 records out 32909 bytes (33 kB, 32 KiB) copied, 0.000142272 s, 231 MB/s 1+0 records in 1+0 records out 676864 bytes (677 kB, 661 KiB) copied, 0.000610144 s, 1.1 GB/s 1320+1 records in 1320+1 records out 676272 bytes (676 kB, 660 KiB) copied, 0.00326546 s, 207 MB/s build_container: 0 0 error writing image hdr 400 MKIMAGE flash.bin 1+0 records in 1+0 records out 164864 bytes (165 kB, 161 KiB) copied, 0.00016016 s, 1.0 GB/s 321+1 records in 321+1 records out 164608 bytes (165 kB, 161 KiB) copied, 0.000612231 s, 269 MB/s 1+0 records in 1+0 records out 79872 bytes (80 kB, 78 KiB) copied, 7.304e-05 s, 1.1 GB/s 155+1 records in 155+1 records out 79799 bytes (80 kB, 78 KiB) copied, 0.000962302 s, 82.9 MB/s build_container: 400 0 error writing image hdr 400 append u-boot.cnt at 316 KB 702+0 records in 702+0 records out 718848 bytes (719 kB, 702 KiB) copied, 0.00186017 s, 386 MB/s Best regards, Enric > --- > include/imx8image.h | 19 +++++-- > tools/imx8image.c | 147 > ++++++++++++++++++++++++++++++++++++++++++++++------ > tools/imx9_image.sh | 8 +++ > 3 files changed, 155 insertions(+), 19 deletions(-) > > diff --git a/include/imx8image.h b/include/imx8image.h > index 6b95e93fb50..e0d25c5b6c9 100644 > --- a/include/imx8image.h > +++ b/include/imx8image.h > @@ -157,7 +157,9 @@ enum imx8image_cmd { > CMD_SOC_TYPE, > CMD_CONTAINER, > CMD_IMAGE, > - CMD_DATA > + CMD_DATA, > + CMD_DUMMY_V2X, > + CMD_HOLD, > }; > > enum imx8image_core_type { > @@ -169,7 +171,9 @@ enum imx8image_core_type { > CFG_A35, > CFG_A55, > CFG_A53, > - CFG_A72 > + CFG_A72, > + CFG_M33, > + CFG_OEI, > }; > > enum imx8image_fld_types { > @@ -208,7 +212,10 @@ typedef enum option_type { > FILEOFF, > MSG_BLOCK, > SENTINEL, > - UPOWER > + UPOWER, > + OEI, > + DUMMY_V2X, > + HOLD, > } option_type_t; > > typedef struct { > @@ -227,12 +234,16 @@ typedef struct { > #define CORE_CA35 4 > #define CORE_CA72 5 > #define CORE_SECO 6 > +#define CORE_M33 7 > > #define CORE_ULP_CM33 0x1 > #define CORE_ULP_CA35 0x2 > #define CORE_ULP_UPOWER 0x4 > #define CORE_ULP_SENTINEL 0x6 > > +#define CORE_IMX95_M33P 0 > +#define CORE_IMX95_A55C0 2 > + > #define SC_R_OTP 357U > #define SC_R_DEBUG 354U > #define SC_R_ROM_0 236U > @@ -246,10 +257,12 @@ typedef struct { > #define IMG_TYPE_EXEC 0x03 /* Executable image type */ > #define IMG_TYPE_DATA 0x04 /* Data image type */ > #define IMG_TYPE_DCD_DDR 0x05 /* DCD/DDR image type */ > +#define IMG_TYPE_OEI 0x05 /* Optional Executable image type */ > #define IMG_TYPE_SECO 0x06 /* SECO image type */ > #define IMG_TYPE_SENTINEL 0x06 /* SENTINEL image type */ > #define IMG_TYPE_PROV 0x07 /* Provisioning image type */ > #define IMG_TYPE_DEK 0x08 /* DEK validation type */ > +#define IMG_TYPE_V2X_DUMMY 0x0E /* V2X Dummy image */ > > #define IMG_TYPE_SHIFT 0 > #define IMG_TYPE_MASK 0x1f > diff --git a/tools/imx8image.c b/tools/imx8image.c > index 0135b190951..a333ded46e2 100644 > --- a/tools/imx8image.c > +++ b/tools/imx8image.c > @@ -7,6 +7,7 @@ > > #include "imx8image.h" > #include <image.h> > +#include <linux/sizes.h> > > static int p_idx; > static int sector_size; > @@ -54,7 +55,9 @@ static table_entry_t imx8image_cmds[] = { > {CMD_CONTAINER, "CONTAINER", "new container", > }, > {CMD_IMAGE, "IMAGE", "new image", > }, > {CMD_DATA, "DATA", "new data", > }, > - {-1, "", "", > }, > + {CMD_DUMMY_V2X, "DUMMY_V2X", "v2x", > }, > + {CMD_HOLD, "HOLD", "hold", > }, > + {-1, "", "", > } > }; > > static table_entry_t imx8image_core_entries[] = { > @@ -66,7 +69,9 @@ static table_entry_t imx8image_core_entries[] = { > {CFG_A55, "A55", "A55 core", }, > {CFG_A53, "A53", "A53 core", }, > {CFG_A72, "A72", "A72 core", }, > - {-1, "", "", }, > + {CFG_OEI, "OEI", "OEI", }, > + {CFG_M33, "M33", "M33 core", }, > + {-1, "", "", } > }; > > static table_entry_t imx8image_sector_size[] = { > @@ -144,6 +149,14 @@ static void parse_cfg_cmd(image_t *param_stack, int32_t > cmd, char *token, > exit(EXIT_FAILURE); > } > break; > + case CMD_DUMMY_V2X: > + param_stack[p_idx].option = DUMMY_V2X; > + param_stack[p_idx++].entry = (uint32_t)strtoll(token, NULL, > 0); > + break; > + case CMD_HOLD: > + param_stack[p_idx].option = HOLD; > + param_stack[p_idx].entry = (uint32_t)strtoll(token, NULL, 0); > + param_stack[p_idx++].filename = NULL; > default: > break; > } > @@ -221,6 +234,16 @@ static void parse_cfg_fld(image_t *param_stack, int32_t > *cmd, char *token, > (*cmd == CMD_DATA) ? DATA : AP; > param_stack[p_idx].filename = token; > break; > + case CFG_OEI: > + param_stack[p_idx].option = OEI; > + param_stack[p_idx].filename = token; > + param_stack[p_idx].ext = CORE_CM4_0; > + break; > + case CFG_M33: > + param_stack[p_idx].option = M40; > + param_stack[p_idx].ext = 0; > + param_stack[p_idx].filename = token; > + break; > } > break; > case CFG_LOAD_ADDR: > @@ -238,9 +261,15 @@ static void parse_cfg_fld(image_t *param_stack, int32_t > *cmd, char *token, > case CFG_A53: > case CFG_A55: > case CFG_A72: > + case CFG_M33: > param_stack[p_idx++].entry = > (uint32_t)strtoll(token, NULL, 0); > break; > + case CFG_OEI: > + param_stack[p_idx].dst = (uint32_t)strtoll(token, > NULL, 0); > + param_stack[p_idx].entry = param_stack[p_idx].dst + 1; > + p_idx++; > + break; > } > default: > break; > @@ -549,6 +578,7 @@ static void set_image_array_entry(flash_header_v3_t > *container, > char *tmp_filename, bool dcd_skip) > { > uint64_t entry = image_stack->entry; > + uint64_t dst = image_stack->dst; > uint64_t core = image_stack->ext; > uint32_t meta; > char *tmp_name = ""; > @@ -558,7 +588,9 @@ static void set_image_array_entry(flash_header_v3_t > *container, > img->offset = offset; /* Is re-adjusted later */ > img->size = size; > > - set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT); > + if (type != DUMMY_V2X) { > + set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT); > + } > > switch (type) { > case SECO: > @@ -580,6 +612,27 @@ static void set_image_array_entry(flash_header_v3_t > *container, > img->dst = 0xe4000000; /* S400 IRAM base */ > img->entry = 0xe4000000; > break; > + case OEI: > + if (soc != IMX9) { > + fprintf(stderr, "Error: invalid core id: %" PRIi64 > "\n", core); > + exit(EXIT_FAILURE); > + } > + > + img->hab_flags |= IMG_TYPE_OEI; > + if (core == CORE_CM4_0) { > + img->hab_flags |= CORE_ULP_CM33 << > BOOT_IMG_FLAGS_CORE_SHIFT; > + meta = CORE_IMX95_M33P; > + > + } else { > + img->hab_flags |= CORE_ULP_CA35 << > BOOT_IMG_FLAGS_CORE_SHIFT; > + meta = CORE_IMX95_A55C0; > + } > + tmp_name = "OEI"; > + img->dst = (dst ? dst : entry); > + img->entry = entry; > + img->meta = meta; > + custom_partition = 0; > + break; > case AP: > if (soc == QX && core == CORE_CA35) { > meta = IMAGE_A35_DEFAULT_META(custom_partition); > @@ -587,8 +640,10 @@ static void set_image_array_entry(flash_header_v3_t > *container, > meta = IMAGE_A53_DEFAULT_META(custom_partition); > } else if (soc == QM && core == CORE_CA72) { > meta = IMAGE_A72_DEFAULT_META(custom_partition); > - } else if (((soc == ULP) || (soc == IMX9)) && core == > CORE_CA35) { > + } else if ((soc == ULP) && core == CORE_CA35) { > meta = 0; > + } else if ((soc == IMX9) && core == CORE_CA35) { > + meta = CORE_IMX95_A55C0; > } else { > fprintf(stderr, > "Error: invalid AP core id: %" PRIu64 "\n", > @@ -687,6 +742,15 @@ static void set_image_array_entry(flash_header_v3_t > *container, > img->entry = 0x28300200; > } > break; > + case DUMMY_V2X: > + img->hab_flags |= IMG_TYPE_V2X_DUMMY; > + img->hab_flags |= CORE_SC << BOOT_IMG_FLAGS_CORE_SHIFT; > + tmp_name = "V2X Dummy"; > + set_image_hash(img, "/dev/null", IMAGE_HASH_ALGO_DEFAULT); > + img->dst = entry; > + img->entry = entry; > + img->size = 0; /* dummy image has no size */ > + break; > default: > fprintf(stderr, "unrecognized image type (%d)\n", type); > exit(EXIT_FAILURE); > @@ -709,15 +773,26 @@ void set_container(flash_header_v3_t *container, > uint16_t sw_version, > fprintf(stdout, "container flags: 0x%x\n", container->flags); > } > > -static int get_container_image_start_pos(image_t *image_stack, uint32_t > align) > +static int get_container_image_start_pos(image_t *image_stack, uint32_t > align, uint32_t *v2x) > { > image_t *img_sp = image_stack; > /*8K total container header*/ > int file_off = CONTAINER_IMAGE_ARRAY_START_OFFSET; > FILE *fd = NULL; > - flash_header_v3_t header; > + flash_header_v3_t *header; > + flash_header_v3_t *header2; > + void *p; > int ret; > > + p = calloc(1, SZ_4K); > + if (!p) { > + fprintf(stderr, "Fail to alloc 4K memory\n"); > + exit(EXIT_FAILURE); > + } > + > + header = p; > + header2 = p + FIRST_CONTAINER_HEADER_LENGTH; > + > while (img_sp->option != NO_IMG) { > if (img_sp->option == APPEND) { > fd = fopen(img_sp->filename, "r"); > @@ -726,7 +801,7 @@ static int get_container_image_start_pos(image_t > *image_stack, uint32_t align) > exit(EXIT_FAILURE); > } > > - ret = fread(&header, sizeof(header), 1, fd); > + ret = fread(header, SZ_4K, 1, fd); > if (ret != 1) { > printf("Failure Read header %d\n", ret); > exit(EXIT_FAILURE); > @@ -734,19 +809,27 @@ static int get_container_image_start_pos(image_t > *image_stack, uint32_t align) > > fclose(fd); > > - if (header.tag != IVT_HEADER_TAG_B0) { > - fprintf(stderr, "header tag mismatched file > %s\n", img_sp->filename); > + if (header->tag != IVT_HEADER_TAG_B0) { > + fprintf(stderr, "header tag mismatched \n"); > exit(EXIT_FAILURE); > } else { > - file_off += > - header.img[header.num_images - > 1].size; > - file_off = ALIGN(file_off, align); > + if (header2->tag != IVT_HEADER_TAG_B0) { > + file_off += > header->img[header->num_images - 1].size; > + file_off = ALIGN(file_off, align); > + } else { > + file_off = > header2->img[header2->num_images - 1].offset + FIRST_CONTAINER_HEADER_LENGTH; > + file_off += > header2->img[header2->num_images - 1].size; > + file_off = ALIGN(file_off, align); > + fprintf(stderr, "Has 2nd container > %x\n", file_off); > + *v2x = true; > + } > } > } > > img_sp++; > } > > + free(p); > return file_off; > } > > @@ -838,6 +921,7 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > char *tmp_filename = NULL; > uint32_t size = 0; > uint32_t file_padding = 0; > + uint32_t v2x = false; > int ret; > > int container = -1; > @@ -861,7 +945,7 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > set_imx_hdr_v3(&imx_header, 0); > set_imx_hdr_v3(&imx_header, 1); > > - file_off = get_container_image_start_pos(image_stack, sector_size); > + file_off = get_container_image_start_pos(image_stack, sector_size, > &v2x); > fprintf(stdout, "container image offset (aligned):%x\n", file_off); > > /* step through image stack and generate the header */ > @@ -870,6 +954,7 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > /* stop once we reach null terminator */ > while (img_sp->option != NO_IMG) { > switch (img_sp->option) { > + case OEI: > case AP: > case M40: > case M41: > @@ -892,6 +977,30 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > file_off += ALIGN(sbuf.st_size, sector_size); > break; > > + case DUMMY_V2X: > + if (container < 0) { > + fprintf(stderr, "No container found\n"); > + exit(EXIT_FAILURE); > + } > + tmp_filename = "dummy"; > + set_image_array_entry(&imx_header.fhdr[container], > + soc, > + img_sp, > + file_off, > + 0, > + tmp_filename, > + dcd_skip); > + img_sp->src = file_off; > + break; > + > + case HOLD: > + if (container < 0) { > + fprintf(stderr, "No container found\n"); > + exit(EXIT_FAILURE); > + } > + file_off += ALIGN(img_sp->entry, sector_size); > + break; > + > case SECO: > case SENTINEL: > if (container < 0) { > @@ -963,11 +1072,15 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > do { > if (img_sp->option == APPEND) { > copy_file(ofd, img_sp->filename, 0, 0); > - file_padding += FIRST_CONTAINER_HEADER_LENGTH; > + if (v2x) > + file_padding += FIRST_CONTAINER_HEADER_LENGTH > * 2; > + else > + file_padding += FIRST_CONTAINER_HEADER_LENGTH; > } > img_sp++; > } while (img_sp->option != NO_IMG); > > + fprintf(stderr, "%s: %x %d\n", __func__, file_padding, v2x); > /* Add padding or skip appended container */ > ret = lseek(ofd, file_padding, SEEK_SET); > if (ret < 0) { > @@ -980,6 +1093,7 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > /* Note: Image offset are not contained in the image */ > tmp = flatten_container_header(&imx_header, container + 1, > &size, file_padding); > + fprintf(stderr, "error writing image hdr %x\n", size); > /* Write image header */ > if (write(ofd, tmp, size) != size) { > fprintf(stderr, "error writing image hdr\n"); > @@ -1000,7 +1114,8 @@ static int build_container(soc_type_t soc, uint32_t > sector_size, > img_sp->option == AP || img_sp->option == DATA || > img_sp->option == SCD || img_sp->option == SCFW || > img_sp->option == SECO || img_sp->option == MSG_BLOCK || > - img_sp->option == UPOWER || img_sp->option == SENTINEL) { > + img_sp->option == UPOWER || img_sp->option == SENTINEL || > + img_sp->option == OEI) { > copy_file_aligned(ofd, img_sp->filename, img_sp->src, > sector_size); > } > @@ -1031,7 +1146,7 @@ int imx8image_copy_image(int outfd, struct > image_tool_params *mparams) > fprintf(stdout, "CONTAINER SW VERSION:\t0x%04x\n", sw_version); > > build_container(soc, sector_size, emmc_fastboot, > - img_sp, dcd_skip, fuse_version, sw_version, outfd); > + img_sp, false, fuse_version, sw_version, outfd); > > return 0; > } > diff --git a/tools/imx9_image.sh b/tools/imx9_image.sh > index ca78a57a19a..6523d1a0ad1 100755 > --- a/tools/imx9_image.sh > +++ b/tools/imx9_image.sh > @@ -18,6 +18,14 @@ for f in $blobs; do > continue > fi > > + if [ $f = "m33-oei-ddrfw.bin" ]; then > + continue > + fi > + > + if [ $f = "u-boot.bin" ]; then > + continue > + fi > + > if [ ! -f $tmp ]; then > echo "WARNING '$tmp' not found, resulting binary may be > not-functional" >&2 > > > -- > 2.43.0 >