mkimage regression: legacy images with Image Type IH_TYPE_FLATDT

Hello!
ld;dr: I want to create legacy images with Image Type IH_TYPE_FLATDT.
Details:
During the migration of an older system to recent yocto, we noticed that the u-boot's mkimage doesn't work anymore as expected.
The system runs an older version of u-boot and requires the kernel's dtb wrapped in a legacy u-boot image.
With the old u-boot (v2009.08) the following command was used to create the uimage containing the dtb:
| mkimage -A arm -O linux -T flat_dt -C none -d <infile> <outfile>
e.g.:
| $ mkimage-v2009.08-144-g449609f5b11c -A arm -O linux -T flat_dt -C none -d ./vivavis-skalar-pro.dtb out-v2009.08-144-g449609f5b11c | Image Name: | Created: Wed Feb 2 22:22:22 2022 | Image Type: ARM Linux Flat Device Tree (uncompressed) | Data Size: 21726 Bytes = 21.22 kB = 0.02 MB | Load Address: 00000000 | Entry Point: 00000000 | | $ file out-v2009.08-144-g449609f5b11c | out-v2009.08-144-g449609f5b11c: u-boot legacy uImage, , Linux/ARM, | Binary Flat Device Tree BLOB (Not compressed), 21726 bytes, Wed Feb 2 | 21:22:22 2022, Load Address: 00000000, Entry Point: 00000000, Header | CRC: 0X945F44C9, Data CRC: 0XDCA9BDD
With the new u-boot:
| $ mkimage -A arm -O linux -T flat_dt -C none -d ./vivavis-skalar-pro.dtb out-upstream | mkimage: Can't set header for FIT Image support: Success | | echo $? | 1
The command fails. (...and prints the error message "Success". I'll send a patch to fix that).
An image is (partially) generated, but it's neither a valid legacy image nor a FIT image:
| $ file out-upstream | out-upstream: data | | $ hexdump -C out-upstream | head -10 | 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | * | 00000040 d0 0d fe ed 00 00 54 de 00 00 00 38 00 00 50 9c |......T....8..P.| | 00000050 00 00 00 28 00 00 00 11 00 00 00 10 00 00 00 00 |...(............| | 00000060 00 00 04 42 00 00 50 64 00 00 00 00 00 00 00 00 |...B..Pd........| | 00000070 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 |................| | 00000080 00 00 00 03 00 00 00 04 00 00 00 00 00 00 00 01 |................| | 00000090 00 00 00 03 00 00 00 04 00 00 00 0f 00 00 00 01 |................| | 000000a0 00 00 00 03 00 00 00 13 00 00 00 1b 56 49 56 41 |............VIVA| | 000000b0 56 49 53 20 53 6b 61 6c 61 72 2e 70 72 6f 00 00 |VIS Skalar.pro..|
The main difference between the old u-boot and recent u-boot, is that the old u-boot (obviously) always creates legacy images, with the struct legacy_img_hdr::ih_type in the header set to the type given with the '-T' command line argument.
With new mkimage, it's a bit different. The type of the -T command line parameter is used to select the actual image type. This is done by iterating over all image types and calling the check_image_type callback to find a matching image provider.
The FIT image ("fit_common.c") matches on types IH_TYPE_FLATDT (which corresponds to "-T flat_dt") while the legacy image ("tools/default_image.c") matches on the following image types:
IH_TYPE_STANDALONE, /* Standalone Program */ IH_TYPE_KERNEL, /* OS Kernel Image */ IH_TYPE_RAMDISK, /* RAMDisk Image */ IH_TYPE_MULTI, /* Multi-File Image */ IH_TYPE_FIRMWARE, /* Firmware Image */ IH_TYPE_SCRIPT, /* Script file */ IH_TYPE_FILESYSTEM, /* Filesystem Image (any type) */
For work around the problem, I disabled FIT image support entirely and let the legacy image pick up IH_TYPE_FLATDT, too:
diff --git a/tools/default_image.c b/tools/default_image.c index 4a067e65862e..ab145001e49d 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -26,7 +26,7 @@ static struct legacy_img_hdr header;
static int image_check_image_types(uint8_t type) { - if (((type > IH_TYPE_INVALID) && (type < IH_TYPE_FLATDT)) || + if (((type > IH_TYPE_INVALID) && (type <= IH_TYPE_FLATDT)) || (type == IH_TYPE_KERNEL_NOLOAD) || (type == IH_TYPE_FIRMWARE_IVT)) return EXIT_SUCCESS; else diff --git a/tools/fit_common.c b/tools/fit_common.c index 01649760ac00..a967449103f0 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -43,9 +43,11 @@ int fit_verify_header(unsigned char *ptr, int image_size,
int fit_check_image_types(uint8_t type) { +#if 0 if (type == IH_TYPE_FLATDT) return EXIT_SUCCESS; else +#endif return EXIT_FAILURE; }
I though of adding a command line parameter to force legacy images, regardless of the -T value (which means passing the parsed command line parameters down into the check_image_type callback). Are the better options or am I using mkimage wrong?
regards, Marc

Hi Marc,
On Fri, 28 Oct 2022 at 11:53, Marc Kleine-Budde mkl@pengutronix.de wrote:
Hello!
ld;dr: I want to create legacy images with Image Type IH_TYPE_FLATDT.
Details:
During the migration of an older system to recent yocto, we noticed that the u-boot's mkimage doesn't work anymore as expected.
The system runs an older version of u-boot and requires the kernel's dtb wrapped in a legacy u-boot image.
With the old u-boot (v2009.08) the following command was used to create the uimage containing the dtb:
| mkimage -A arm -O linux -T flat_dt -C none -d <infile> <outfile>
e.g.:
| $ mkimage-v2009.08-144-g449609f5b11c -A arm -O linux -T flat_dt -C none -d ./vivavis-skalar-pro.dtb out-v2009.08-144-g449609f5b11c | Image Name: | Created: Wed Feb 2 22:22:22 2022 | Image Type: ARM Linux Flat Device Tree (uncompressed) | Data Size: 21726 Bytes = 21.22 kB = 0.02 MB | Load Address: 00000000 | Entry Point: 00000000 | | $ file out-v2009.08-144-g449609f5b11c | out-v2009.08-144-g449609f5b11c: u-boot legacy uImage, , Linux/ARM, | Binary Flat Device Tree BLOB (Not compressed), 21726 bytes, Wed Feb 2 | 21:22:22 2022, Load Address: 00000000, Entry Point: 00000000, Header | CRC: 0X945F44C9, Data CRC: 0XDCA9BDD
With the new u-boot:
| $ mkimage -A arm -O linux -T flat_dt -C none -d ./vivavis-skalar-pro.dtb out-upstream | mkimage: Can't set header for FIT Image support: Success | | echo $? | 1
The command fails. (...and prints the error message "Success". I'll send a patch to fix that).
An image is (partially) generated, but it's neither a valid legacy image nor a FIT image:
| $ file out-upstream | out-upstream: data | | $ hexdump -C out-upstream | head -10 | 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | * | 00000040 d0 0d fe ed 00 00 54 de 00 00 00 38 00 00 50 9c |......T....8..P.| | 00000050 00 00 00 28 00 00 00 11 00 00 00 10 00 00 00 00 |...(............| | 00000060 00 00 04 42 00 00 50 64 00 00 00 00 00 00 00 00 |...B..Pd........| | 00000070 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 |................| | 00000080 00 00 00 03 00 00 00 04 00 00 00 00 00 00 00 01 |................| | 00000090 00 00 00 03 00 00 00 04 00 00 00 0f 00 00 00 01 |................| | 000000a0 00 00 00 03 00 00 00 13 00 00 00 1b 56 49 56 41 |............VIVA| | 000000b0 56 49 53 20 53 6b 61 6c 61 72 2e 70 72 6f 00 00 |VIS Skalar.pro..|
The main difference between the old u-boot and recent u-boot, is that the old u-boot (obviously) always creates legacy images, with the struct legacy_img_hdr::ih_type in the header set to the type given with the '-T' command line argument.
With new mkimage, it's a bit different. The type of the -T command line parameter is used to select the actual image type. This is done by iterating over all image types and calling the check_image_type callback to find a matching image provider.
The FIT image ("fit_common.c") matches on types IH_TYPE_FLATDT (which corresponds to "-T flat_dt") while the legacy image ("tools/default_image.c") matches on the following image types:
IH_TYPE_STANDALONE, /* Standalone Program */ IH_TYPE_KERNEL, /* OS Kernel Image */ IH_TYPE_RAMDISK, /* RAMDisk Image */ IH_TYPE_MULTI, /* Multi-File Image */ IH_TYPE_FIRMWARE, /* Firmware Image */ IH_TYPE_SCRIPT, /* Script file */ IH_TYPE_FILESYSTEM, /* Filesystem Image (any type) */
For work around the problem, I disabled FIT image support entirely and let the legacy image pick up IH_TYPE_FLATDT, too:
diff --git a/tools/default_image.c b/tools/default_image.c index 4a067e65862e..ab145001e49d 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -26,7 +26,7 @@ static struct legacy_img_hdr header;
static int image_check_image_types(uint8_t type) {
if (((type > IH_TYPE_INVALID) && (type < IH_TYPE_FLATDT)) ||
if (((type > IH_TYPE_INVALID) && (type <= IH_TYPE_FLATDT)) || (type == IH_TYPE_KERNEL_NOLOAD) || (type == IH_TYPE_FIRMWARE_IVT)) return EXIT_SUCCESS; else
diff --git a/tools/fit_common.c b/tools/fit_common.c index 01649760ac00..a967449103f0 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -43,9 +43,11 @@ int fit_verify_header(unsigned char *ptr, int image_size,
int fit_check_image_types(uint8_t type) { +#if 0 if (type == IH_TYPE_FLATDT) return EXIT_SUCCESS; else +#endif return EXIT_FAILURE; }
I though of adding a command line parameter to force legacy images, regardless of the -T value (which means passing the parsed command line parameters down into the check_image_type callback). Are the better options or am I using mkimage wrong?
Firstly, do you need to use the new mkimage with a 2009 U-Boot? Can you update the whole thing to 2022 and use FIT instead?
Yes I think a command-line flag to disable FIT would be best.
Regards, Simon
participants (2)
-
Marc Kleine-Budde
-
Simon Glass