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
>

Reply via email to