Bjørn Mork <bj...@mork.no> writes: > Robert Marko <robima...@gmail.com> writes: > >> What should be done is to expand mkimage with an option to align to an >> 8-byte boundary. > > Definitely. > > However, this implies that mkimage must mangle the output of libfdt to > align one specific property. AFAICS, there are no such possibilities in > device tree.
Well, you made me take a closer look. And I found one possibility: libfdt supports overwriting properties with FDT_NOP. So we can add an empty property in front of the image data and overwrite it with nops. This result is 3 x 4 byte FDT_NOP values What do you think about something like the attached hack? Is it OK to make this unconditional? My reasoning is that it's pretty hard to know when the alignment is required, the failures are arbitrary and hard to debug, and it doesn't seem to harm. This adds 12 bytes to every unaligned fdt node and that's it. I'll try to run it by u-boot too if you think it's acceptable. I tested this briefly, with a kernel I knew would cause an unaligned fdt from previous failures. The result looks like this and it booted fine on my Unifi 6 Lite: $ fdtdump bin/r21167+1-1673b7dca384/targets/ramips/mt7621/openwrt-snapshot-ramips-mt7621-ubnt_unifi-6-lite-squashfs-sysupgrade.bin | sed -e 's/\(data = \[.. .. .. .. .. .. .. .. .. .. .. .. .. \).*\(.....\].*\)/\1 ... \2/' |less **** fdtdump is a low-level debugging tool, not meant for general use. **** If you want to decompile a dtb, you probably want **** dtc -I dtb -O dts <filename> /dts-v1/; // magic: 0xd00dfeed // totalsize: 0x2d4e50 (2969168) // off_dt_struct: 0x38 // off_dt_strings: 0x2d4a70 // off_mem_rsvmap: 0x28 // version: 17 // last_comp_version: 16 // boot_cpuid_phys: 0x0 // size_dt_strings: 0x72 // size_dt_struct: 0x2d4a38 / { timestamp = <0x6366d7d8>; description = "MIPS OpenWrt FIT (Flattened Image Tree)"; #address-cells = <0x00000001>; images { kernel-1 { description = "MIPS OpenWrt Linux-5.15.76"; data = [6d 00 00 80 00 20 cd 96 00 00 00 00 00 ... a5 3e]; type = "kernel"; arch = "mips"; os = "linux"; compression = "lzma"; load = <0x80001000>; entry = <0x80001000>; hash@1 { value = <0xbd771d3e>; algo = "crc32"; }; hash@2 { value = <0x7c11c808 0x508aada9 0x2f14f1b1 0x6b6d7e89 0x652dd798>; algo = "sha1"; }; }; fdt-1 { // [NOP] // [NOP] // [NOP] description = "MIPS OpenWrt ubnt_unifi-6-lite device tree blob"; data = [d0 0d fe ed 00 00 2c 7b 00 00 00 38 00 ... 65 00]; type = "flat_dt"; arch = "mips"; compression = "none"; hash@1 { value = <0x16bb5a14>; algo = "crc32"; }; hash@2 { value = <0x40f26bf2 0x8e33bbe6 0x61fec716 0x929f2003 0x301f5e4d>; algo = "sha1"; }; }; }; configurations { default = "config@1"; config@1 { description = "OpenWrt ubnt_unifi-6-lite"; kernel = "kernel-1"; fdt = "fdt-1"; }; }; }; $ binwalk bin/r21167+1-1673b7dca384/targets/ramips/mt7621/openwrt-snapshot-ramips-mt7621-ubnt_unifi-6-lite-squashfs-sysupgrade.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 Flattened device tree, size: 2969168 bytes, version: 17 228 0xE4 LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 9882912 bytes 2956440 0x2D1C98 Flattened device tree, size: 11387 bytes, version: 17 2969168 0x2D4E50 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 5224258 bytes, 1061 inodes, blocksize: 262144 bytes, created: 2022-11-05 21:38:32 Bjørn
>From 2a81e80aed1e0f8f4cd947f77ce45c9f4358e2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bj...@mork.no> Date: Sat, 5 Nov 2022 22:33:31 +0100 Subject: [PATCH] mkimage: Align fdt images in FIT to 8 bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork <bj...@mork.no> --- tools/fit_image.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tools/fit_image.c b/tools/fit_image.c index 923a9755b709..f0ef3333aa7d 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -24,6 +24,50 @@ static struct legacy_img_hdr header; +#define FIT_NOP_PROP "x-nop" + +/** + * fit_align_fdt_images() - Align all fdt images in the FIT to 8 bytes + * + * An fdt image must be 8 byte aligned to be used "in place". Verify + * that all images are properly aligned, and insert 3 FDT_NOP tags in + * front of the imaga "data" property if necessary. + */ +static int fit_align_fdt_images(void *fit) +{ + int images_noffset; + int noffset; + uint8_t type; + size_t size; + const void *ptr; + + images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror(images_noffset)); + return images_noffset; + } + + for (noffset = fdt_first_subnode(fit, images_noffset); + noffset >= 0; + noffset = fdt_next_subnode(fit, noffset)) { + fit_image_get_type(fit, noffset, &type); + if (type != IH_TYPE_FLATDT) + continue; + + fit_image_get_data(fit, noffset, &ptr, &size); + debug("%s: Found fdt with size %zu at offset %zu\n", size, ptr - fit); + if ((ptr - fit) % 8 == 0) + continue; + + /* Insert an empty dummy property and overwrite it with FDT_NOP */ + debug("Aligning 8 byte boundary by adding 3 FDT_NOP tags\n"); + fdt_setprop_empty(fit, noffset, FIT_NOP_PROP); + fdt_nop_property(fit, noffset, FIT_NOP_PROP); + } + return 0; +} + static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) { @@ -81,6 +125,10 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, ¶ms->summary); } + if (!ret) { + ret = fit_align_fdt_images(ptr); + } + if (dest_blob) { munmap(dest_blob, destfd_size); close(destfd); -- 2.30.2
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel