From: Simon Glass <simon.glass@canonical.com> The code for printing information about FITs is fairly old and not that easy to maintain. It also lacks tests. This series adds some tests, moves the code into its own file and then adds a series of helpers to deal with the intricacies of printing each item. This provides a binary-size reduction of about 320 bytes on aarch64. Simon Glass (30): docs: Merge .claude/README.md into CLAUDE.md tools: Fix debug() to avoid unused-variable warnings test: Increase expect_str/actual_str buffer size fit: Remove unused len parameter from fit_get_name() test: Add a test for FIT image printing test: Add signature-testing to the FIT-printing test test: fit: Test printing a FIT with multiple FDTs test: fit: Test the remaining features and edge cases test: fit: Add test for missing FIT description test: fit: Add pytest for mkimage output fit: Refactor fit_print_contents() to use new fit_print() fit: Move printing code to its own file fit: Drop showing an unused 'required' property fit: Add a context struct for FIT-printing fit: Put the indent string into print context fit: Create some helpers for printing fit: Use emit_label() helper in fit_image_print() fit: Use emit_label() helper in fit_conf_print() fit: Add a a function to print labels with values fit: Change indent from string to int fit: Move values one column to the right fit: Use emit_label_val() where possible fit: Add a helper to output optional properties fit: Add a helper for timestamp printing fit: Add a helper for stringlist properties fit: Add a helper for printing descriptions fit: Add a helper for address printing fit: Use a boolean to simplify type checks fit: Add a helper to iterate through hash/signature nodes fit: Use the libfdt subnode iterator .claude/README.md => CLAUDE.md | 3 + boot/Makefile | 1 + boot/fit_print.c | 494 ++++++++++++++++++++++++++++++++ boot/image-cipher.c | 2 +- boot/image-fit-sig.c | 24 +- boot/image-fit.c | 442 +--------------------------- common/spl/spl_fit.c | 12 +- common/update.c | 4 +- drivers/fpga/socfpga_arria10.c | 2 +- include/image.h | 84 +++++- include/test/test.h | 4 +- test/boot/Makefile | 1 + test/boot/fit_print.c | 192 +++++++++++++ test/py/tests/test_fit_print.py | 431 ++++++++++++++++++++++++++++ tools/Makefile | 1 + tools/fit_image.c | 15 +- tools/fit_info.c | 2 +- tools/image-host.c | 30 +- tools/mkimage.h | 8 +- 19 files changed, 1272 insertions(+), 480 deletions(-) rename .claude/README.md => CLAUDE.md (93%) create mode 100644 boot/fit_print.c create mode 100644 test/boot/fit_print.c create mode 100644 test/py/tests/test_fit_print.py -- 2.43.0 base-commit: adf71f6928469e3854448b7a58f26235852bd6d7 branch: fita
From: Simon Glass <simon.glass@canonical.com> Consolidate build and coding documentation into CLAUDE.md and remove the redundant .claude/README.md file. Mention the use of the Co-developed-by tag and how to run tests. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- .claude/README.md => CLAUDE.md | 3 +++ 1 file changed, 3 insertions(+) rename .claude/README.md => CLAUDE.md (93%) diff --git a/.claude/README.md b/CLAUDE.md similarity index 93% rename from .claude/README.md rename to CLAUDE.md index b84be8d2445..374f24ba1f9 100644 --- a/.claude/README.md +++ b/CLAUDE.md @@ -32,6 +32,7 @@ make sandbox_defconfig O=/tmp/<build_dir> # Build make -j$(nproc) O=/tmp/<build_dir> ``` + ## Testing There are aliases in ~/bin/git-alias which you can use. @@ -67,3 +68,5 @@ pyt <test_name> - This follows U-Boot's established naming convention for output parameters - Keep commit messages concise - focus on the key change and essential details only - Code should be formatted to 80 columns and not have trailing spaces +- Remember to use Co-developed-by in commits +- Remember not to cd into the build directory; run U-Boot directly in the source dir -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The debug() macro in mkimage.h expands to nothing when MKIMAGE_DEBUG is not defined. This causes the compiler to warn about unused variables that are only referenced in debug() statements. Fix this using the same approach as the debug_cond() macro. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/mkimage.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/mkimage.h b/tools/mkimage.h index 5d6bcc9301a..a356d20c3b1 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -25,9 +25,13 @@ #undef MKIMAGE_DEBUG #ifdef MKIMAGE_DEBUG -#define debug(fmt,args...) printf (fmt ,##args) +#define debug(fmt, args...) printf(fmt, ##args) #else -#define debug(fmt,args...) +#define debug(fmt, args...) \ + do { \ + if (0) \ + printf(fmt, ##args); \ + } while (0) #endif /* MKIMAGE_DEBUG */ #define log_debug(fmt, args...) debug(fmt, ##args) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> These buffers can be exceeded when checking the FIT output with an RSA key. Increase the limit to 1K. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- include/test/test.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/test/test.h b/include/test/test.h index 51609e799b7..f2d956e913c 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -78,8 +78,8 @@ struct unit_test_state { bool force_run; void *old_bloblist; bool soft_fail; - char expect_str[512]; - char actual_str[512]; + char expect_str[1024]; + char actual_str[1024]; }; /* Test flags for each test */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Remove the unused third parameter (len) from fit_get_name(). All uses of this function pass NULL for this parameter. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/image-cipher.c | 2 +- boot/image-fit-sig.c | 24 ++++++++++++------------ boot/image-fit.c | 29 ++++++++++++++--------------- common/spl/spl_fit.c | 12 ++++++------ common/update.c | 4 ++-- drivers/fpga/socfpga_arria10.c | 2 +- include/image.h | 6 +++--- tools/fit_image.c | 2 +- tools/fit_info.c | 2 +- tools/image-host.c | 30 +++++++++++++++--------------- 10 files changed, 56 insertions(+), 57 deletions(-) diff --git a/boot/image-cipher.c b/boot/image-cipher.c index 9d389f26cea..66fae2153cd 100644 --- a/boot/image-cipher.c +++ b/boot/image-cipher.c @@ -76,7 +76,7 @@ static int fit_image_setup_decrypt(struct image_cipher_info *info, char *algo_name; int ret; - node_name = fit_get_name(fit, image_noffset, NULL); + node_name = fit_get_name(fit, image_noffset); if (!node_name) { printf("Can't get node name\n"); return -1; diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index a121de60ae2..8dee5698236 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -145,7 +145,7 @@ static int fit_image_verify_sig(const void *fit, int image_noffset, /* Process all hash subnodes of the component image node */ fdt_for_each_subnode(noffset, fit, image_noffset) { - const char *name = fit_get_name(fit, noffset, NULL); + const char *name = fit_get_name(fit, noffset); /* * We don't support this since libfdt considers names with the @@ -178,8 +178,8 @@ static int fit_image_verify_sig(const void *fit, int image_noffset, error: printf(" error!\n%s for '%s' hash node in '%s' image node\n", - err_msg, fit_get_name(fit, noffset, NULL), - fit_get_name(fit, image_noffset, NULL)); + err_msg, fit_get_name(fit, noffset), + fit_get_name(fit, image_noffset)); return -1; } @@ -212,7 +212,7 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, key_blob, noffset); if (ret) { printf("Failed to verify required signature '%s'\n", - fit_get_name(key_blob, noffset, NULL)); + fit_get_name(key_blob, noffset)); return ret; } verify_count++; @@ -277,10 +277,10 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, char path[200]; int count; - config_name = fit_get_name(fit, conf_noffset, NULL); + config_name = fit_get_name(fit, conf_noffset); debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, key_blob, - fit_get_name(fit, noffset, NULL), - fit_get_name(key_blob, required_keynode, NULL)); + fit_get_name(fit, noffset), + fit_get_name(key_blob, required_keynode)); *err_msgp = NULL; if (fit_image_setup_verify(&info, fit, noffset, key_blob, required_keynode, err_msgp)) @@ -421,7 +421,7 @@ static int fit_config_verify_key(const void *fit, int conf_noffset, /* Process all hash subnodes of the component conf node */ fdt_for_each_subnode(noffset, fit, conf_noffset) { - const char *name = fit_get_name(fit, noffset, NULL); + const char *name = fit_get_name(fit, noffset); if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { @@ -448,8 +448,8 @@ static int fit_config_verify_key(const void *fit, int conf_noffset, error: printf(" error!\n%s for '%s' hash node in '%s' config node\n", - err_msg, fit_get_name(fit, noffset, NULL), - fit_get_name(fit, conf_noffset, NULL)); + err_msg, fit_get_name(fit, noffset), + fit_get_name(fit, conf_noffset)); return -EPERM; } @@ -469,7 +469,7 @@ error: static int fit_config_verify_required_keys(const void *fit, int conf_noffset, const void *key_blob) { - const char *name = fit_get_name(fit, conf_noffset, NULL); + const char *name = fit_get_name(fit, conf_noffset); int noffset; int key_node; int verified = 0; @@ -525,7 +525,7 @@ static int fit_config_verify_required_keys(const void *fit, int conf_noffset, if (ret) { if (reqd_policy_all) { printf("Failed to verify required signature '%s'\n", - fit_get_name(key_blob, noffset, NULL)); + fit_get_name(key_blob, noffset)); return ret; } } else { diff --git a/boot/image-fit.c b/boot/image-fit.c index 7bcdb97985a..eb47c00cc01 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -148,7 +148,7 @@ static void fit_get_debug(const void *fit, int noffset, char *prop_name, int err) { debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n", - prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL), + prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset), fdt_strerror(err)); } @@ -205,8 +205,7 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p, bool required; int ret, i; - debug("%s %s node: '%s'\n", p, type, - fit_get_name(fit, noffset, NULL)); + debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); printf("%s %s algo: ", p, type); if (fit_image_hash_get_algo(fit, noffset, &algo)) { printf("invalid/unsupported\n"); @@ -271,7 +270,7 @@ static void fit_image_print_verification_data(const void *fit, int noffset, * Multiple hash/signature nodes require unique unit node * names, e.g. hash-1, hash-2, signature-1, signature-2, etc. */ - name = fit_get_name(fit, noffset, NULL); + name = fit_get_name(fit, noffset); if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { fit_image_print_data(fit, noffset, p, "Hash"); } else if (!strncmp(name, FIT_SIG_NODENAME, @@ -436,7 +435,7 @@ void fit_print_contents(const void *fit) * i.e. component image node. */ printf("%s Image %u (%s)\n", p, count++, - fit_get_name(fit, noffset, NULL)); + fit_get_name(fit, noffset)); fit_image_print(fit, noffset, p); } @@ -466,7 +465,7 @@ void fit_print_contents(const void *fit) * i.e. configuration node. */ printf("%s Configuration %u (%s)\n", p, count++, - fit_get_name(fit, noffset, NULL)); + fit_get_name(fit, noffset)); fit_conf_print(fit, noffset, p); } @@ -1215,7 +1214,7 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp) sizeof(uint32_t)); if (ret) { debug("Can't set '%s' property for '%s' node (%s)\n", - FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL), + FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset), fdt_strerror(ret)); return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1; } @@ -1352,7 +1351,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, /* Process all hash subnodes of the component image node */ fdt_for_each_subnode(noffset, fit, image_noffset) { - const char *name = fit_get_name(fit, noffset, NULL); + const char *name = fit_get_name(fit, noffset); /* * Check subnode name, must be equal to "hash". @@ -1393,8 +1392,8 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, error: printf(" error!\n%s for '%s' hash node in '%s' image node\n", - err_msg, fit_get_name(fit, noffset, NULL), - fit_get_name(fit, image_noffset, NULL)); + err_msg, fit_get_name(fit, noffset), + fit_get_name(fit, image_noffset)); return 0; } @@ -1413,7 +1412,7 @@ error: */ int fit_image_verify(const void *fit, int image_noffset) { - const char *name = fit_get_name(fit, image_noffset, NULL); + const char *name = fit_get_name(fit, image_noffset); const void *data; size_t size; char *err_msg = ""; @@ -1437,7 +1436,7 @@ int fit_image_verify(const void *fit, int image_noffset) err: printf("error!\n%s in '%s' image node\n", err_msg, - fit_get_name(fit, image_noffset, NULL)); + fit_get_name(fit, image_noffset)); return 0; } @@ -1480,7 +1479,7 @@ int fit_all_image_verify(const void *fit) * i.e. component image node. */ printf(" Hash(es) for Image %u (%s): ", count, - fit_get_name(fit, noffset, NULL)); + fit_get_name(fit, noffset)); count++; if (!fit_image_verify(fit, noffset)) @@ -2127,7 +2126,7 @@ static int select_from_config(const void *fit, struct bootm_headers *images, return -ENOPKG; } - *fit_unamep = fit_get_name(fit, noffset, NULL); + *fit_unamep = fit_get_name(fit, noffset); return noffset; } @@ -2639,7 +2638,7 @@ int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, if (i < count) { noffset = fit_conf_get_prop_node_index(fit, cfg_noffset, FIT_FDT_PROP, i); - uname = fit_get_name(fit, noffset, NULL); + uname = fit_get_name(fit, noffset); uconfig = NULL; } else { if (!next_config) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 49b4df60560..b4049e41c2c 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -255,7 +255,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, if (fit_image_get_load(fit, node, &load_addr)) { if (!image_info->load_addr) { printf("Can't load %s: No load address and no buffer\n", - fit_get_name(fit, node, NULL)); + fit_get_name(fit, node)); return -ENOBUFS; } load_addr = image_info->load_addr; @@ -281,7 +281,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, /* Dont bother to copy 0 byte data, but warn, though */ if (!len) { log_warning("%s: Skip load '%s': image size is 0!\n", - __func__, fit_get_name(fit, node, NULL)); + __func__, fit_get_name(fit, node)); return 0; } @@ -318,7 +318,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) { printf("## Checking hash(es) for Image %s ... ", - fit_get_name(fit, node, NULL)); + fit_get_name(fit, node)); if (!fit_image_verify_with_data(fit, node, gd_fdt_blob(), src, length)) return -EPERM; @@ -489,12 +489,12 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, (void *)image_info.load_addr); if (ret) { pr_err("failed to apply DT overlay %s\n", - fit_get_name(ctx->fit, node, NULL)); + fit_get_name(ctx->fit, node)); break; } debug("%s: DT overlay %s applied\n", __func__, - fit_get_name(ctx->fit, node, NULL)); + fit_get_name(ctx->fit, node)); } free(tmpbuffer); if (ret) @@ -720,7 +720,7 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx) if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) { printf("## Checking hash(es) for config %s ... ", - fit_get_name(ctx->fit, ctx->conf_node, NULL)); + fit_get_name(ctx->fit, ctx->conf_node)); if (fit_config_verify(ctx->fit, ctx->conf_node)) return -EPERM; puts("OK\n"); diff --git a/common/update.c b/common/update.c index 6801b49479d..8f44a64592a 100644 --- a/common/update.c +++ b/common/update.c @@ -278,7 +278,7 @@ got_update_file: if (ndepth != 1) goto next_node; - fit_image_name = (char *)fit_get_name(fit, noffset, NULL); + fit_image_name = (char *)fit_get_name(fit, noffset); printf("Processing update '%s' :", fit_image_name); if (!fit_image_verify(fit, noffset)) { @@ -354,7 +354,7 @@ int fit_update(const void *fit) if (ndepth != 1) goto next_node; - fit_image_name = (char *)fit_get_name(fit, noffset, NULL); + fit_image_name = (char *)fit_get_name(fit, noffset); printf("Processing update '%s' :", fit_image_name); if (!fit_image_verify(fit, noffset)) { diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index e9822b2bb0e..317bb261bc8 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -613,7 +613,7 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, images_noffset = fit_conf_get_prop_node_index(buffer_p, confs_noffset, FIT_FPGA_PROP, i); - uname = fit_get_name(buffer_p, images_noffset, NULL); + uname = fit_get_name(buffer_p, images_noffset); if (uname) { debug("FPGA: %s\n", uname); diff --git a/include/image.h b/include/image.h index a972e3f6921..33eb5d71e79 100644 --- a/include/image.h +++ b/include/image.h @@ -1225,15 +1225,15 @@ ulong fit_get_end(const void *fit); /** * fit_get_name - get FIT node name * @fit: pointer to the FIT format image header + * @noffset: node offset * * returns: * NULL, on error * pointer to node name, on success */ -static inline const char *fit_get_name(const void *fit_hdr, - int noffset, int *len) +static inline const char *fit_get_name(const void *fit_hdr, int noffset) { - return fdt_get_name(fit_hdr, noffset, len); + return fdt_get_name(fit_hdr, noffset, NULL); } /** diff --git a/tools/fit_image.c b/tools/fit_image.c index 013242cd204..80f9020d29d 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -972,7 +972,7 @@ static int fit_extract_contents(void *ptr, struct imgtool *itl) */ if (itl->pflag == count) { printf("Extracted:\n%s Image %u (%s)\n", p, - count, fit_get_name(fit, noffset, NULL)); + count, fit_get_name(fit, noffset)); fit_image_print(fit, noffset, p); diff --git a/tools/fit_info.c b/tools/fit_info.c index b2642ec5b76..3c049a7f7e1 100644 --- a/tools/fit_info.c +++ b/tools/fit_info.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - printf("NAME: %s\n", fit_get_name(fit_blob, nodeoffset, NULL)); + printf("NAME: %s\n", fit_get_name(fit_blob, nodeoffset)); printf("LEN: %d\n", len); printf("OFF: %d\n", (int)(nodep - fit_blob)); (void) munmap((void *)fit_blob, fsbuf.st_size); diff --git a/tools/image-host.c b/tools/image-host.c index a9b86902763..99594f89de0 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -46,7 +46,7 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value, ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); if (ret) { fprintf(stderr, "Can't set hash '%s' property for '%s' node(%s)\n", - FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL), + FIT_VALUE_PROP, fit_get_name(fit, noffset), fdt_strerror(ret)); return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO; } @@ -76,7 +76,7 @@ static int fit_image_process_hash(void *fit, const char *image_name, const char *algo; int ret; - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); if (fit_image_hash_get_algo(fit, noffset, &algo)) { fprintf(stderr, @@ -176,7 +176,7 @@ static int fit_image_setup_sig(struct image_sign_info *info, const char *node_name; const char *padding_name; - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); if (!algo_name) { if (fit_image_hash_get_algo(fit, noffset, &algo_name)) { fprintf(stderr, @@ -247,7 +247,7 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile, engine_id, algo_name)) return -1; - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); region.data = data; region.size = size; ret = info.crypto->sign(&info, ®ion, 1, &value, &value_len); @@ -585,7 +585,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest, int cipher_node_offset, len; /* Get image name */ - image_name = fit_get_name(fit, image_noffset, NULL); + image_name = fit_get_name(fit, image_noffset); if (!image_name) { fprintf(stderr, "Can't get image name\n"); return -1; @@ -677,7 +677,7 @@ int fit_image_add_verification_data(const char *keydir, const char *keyfile, return -1; } - image_name = fit_get_name(fit, image_noffset, NULL); + image_name = fit_get_name(fit, image_noffset); /* Process all hash subnodes of the component image node */ for (noffset = fdt_first_subnode(fit, image_noffset); @@ -691,7 +691,7 @@ int fit_image_add_verification_data(const char *keydir, const char *keyfile, * Multiple hash nodes require unique unit node * names, e.g. hash-1, hash-2, signature-1, etc. */ - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); if (!strncmp(node_name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { ret = fit_image_process_hash(fit, image_name, noffset, @@ -809,7 +809,7 @@ static int fit_config_add_hash(const void *fit, int image_noffset, for (noffset = fdt_first_subnode(fit, image_noffset); noffset >= 0; noffset = fdt_next_subnode(fit, noffset)) { - const char *name = fit_get_name(fit, noffset, NULL); + const char *name = fit_get_name(fit, noffset); if (strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) @@ -884,8 +884,8 @@ static int fit_config_get_hash_list(const void *fit, int conf_noffset, int image_count; int ret, len; - conf_name = fit_get_name(fit, conf_noffset, NULL); - sig_name = fit_get_name(fit, sig_offset, NULL); + conf_name = fit_get_name(fit, conf_noffset); + sig_name = fit_get_name(fit, sig_offset); /* * Build a list of nodes we need to hash. We always need the root @@ -991,8 +991,8 @@ static int fit_config_get_regions(const void *fit, int conf_noffset, char *region_prop; int ret, len; - conf_name = fit_get_name(fit, conf_noffset, NULL); - sig_name = fit_get_name(fit, sig_offset, NULL); + conf_name = fit_get_name(fit, conf_noffset); + sig_name = fit_get_name(fit, sig_offset); debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name); /* Get a list of nodes we want to hash */ @@ -1084,7 +1084,7 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile, uint value_len; int ret; - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); if (fit_config_get_regions(fit, conf_noffset, noffset, ®ion, ®ion_count, ®ion_prop, ®ion_proplen)) @@ -1148,7 +1148,7 @@ static int fit_config_add_verification_data(const char *keydir, const char *conf_name; int noffset; - conf_name = fit_get_name(fit, conf_noffset, NULL); + conf_name = fit_get_name(fit, conf_noffset); /* Process all hash subnodes of the configuration node */ for (noffset = fdt_first_subnode(fit, conf_noffset); @@ -1157,7 +1157,7 @@ static int fit_config_add_verification_data(const char *keydir, const char *node_name; int ret = 0; - node_name = fit_get_name(fit, noffset, NULL); + node_name = fit_get_name(fit, noffset); if (!strncmp(node_name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { ret = fit_config_process_sig(keydir, keyfile, keydest, -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The code for printing FITs is quite messy, with lots of separate printf() calls, an indentation string, etc. It also has no tests. In preparation for refactoring this code, add a test. Use Python code to create the test image and C code to test it. The test covers FIT description, image details (type, architecture, OS, addresses), and configuration details. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/boot/Makefile | 1 + test/boot/fit_print.c | 93 +++++++++++++++++++++++++ test/py/tests/test_fit_print.py | 120 ++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 test/boot/fit_print.c create mode 100644 test/py/tests/test_fit_print.py diff --git a/test/boot/Makefile b/test/boot/Makefile index 71c482f8d24..70e15bf63fa 100644 --- a/test/boot/Makefile +++ b/test/boot/Makefile @@ -5,6 +5,7 @@ ifdef CONFIG_UT_BOOTSTD obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o obj-$(CONFIG_FIT) += image.o +obj-$(CONFIG_$(PHASE_)FIT_PRINT) += fit_print.o obj-$(CONFIG_BLK_LUKS) += luks.o obj-$(CONFIG_EXPO) += expo.o expo_common.o diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c new file mode 100644 index 00000000000..ef1e86800ee --- /dev/null +++ b/test/boot/fit_print.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for FIT image printing + * + * Copyright 2025 Canonical Ltd + * Written by Simon Glass <simon.glass@canonical.com> + */ + +#include <image.h> +#include <mapmem.h> +#include <os.h> +#include <test/ut.h> +#include <linux/libfdt.h> +#include "bootstd_common.h" + +/* Test fit_print_contents() output */ +static int test_fit_print_norun(struct unit_test_state *uts) +{ + char fname[256]; + void *fit; + void *buf; + ulong addr; + int size; + + /* Load the FIT created by the Python test */ + ut_assertok(os_persistent_file(fname, sizeof(fname), "test-fit.fit")); + ut_assertok(os_read_file(fname, &buf, &size)); + + /* Copy to address 0x10000 and print from there */ + addr = 0x10000; + fit = map_sysmem(addr, size); + memcpy(fit, buf, size); + + /* Print it and check output line by line */ + console_record_reset_enable(); + fit_print_contents(fit); + + /* Check every line of output */ + ut_assert_nextline(" FIT description: Test FIT image for printing"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Image 0 (kernel)"); + ut_assert_nextline(" Description: Test kernel"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Kernel Image"); + ut_assert_nextline(" Compression: gzip compressed"); + ut_assert_nextline(" Data Start: 0x000100c4"); + ut_assert_nextline(" Data Size: 327 Bytes = 327 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x01000000"); + ut_assert_nextline(" Entry Point: 0x01000000"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee"); + ut_assert_nextline(" Image 1 (ramdisk)"); + ut_assert_nextline(" Description: Test ramdisk"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: RAMDisk Image"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010304"); + ut_assert_nextline(" Data Size: 301 Bytes = 301 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x02000000"); + ut_assert_nextline(" Entry Point: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655"); + ut_assert_nextline(" Image 2 (fdt)"); + ut_assert_nextline(" Description: Test FDT"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Flat Device Tree"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010514"); + ut_assert_nextline(" Data Size: 157 Bytes = 157 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 51918524b06745cae06331047c7e566909431bf71338e5f703dffba1823274f4"); + ut_assert_nextline(" Default Configuration: 'conf-1'"); + ut_assert_nextline(" Configuration 0 (conf-1)"); + ut_assert_nextline(" Description: Test configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" Init Ramdisk: ramdisk"); + ut_assert_nextline(" FDT: fdt"); + ut_assert_nextline(" Configuration 1 (conf-2)"); + ut_assert_nextline(" Description: Alternate configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" FDT: fdt"); + ut_assert_console_end(); + + os_free(buf); + + return 0; +} +BOOTSTD_TEST(test_fit_print_norun, UTF_CONSOLE | UTF_MANUAL); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py new file mode 100644 index 00000000000..4960ce503b4 --- /dev/null +++ b/test/py/tests/test_fit_print.py @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Canonical Ltd +# Written by Simon Glass <simon.glass@canonical.com> + +"""Test for FIT image printing""" + +import os + +import pytest + +import fit_util +import utils + +# ITS for testing FIT printing with hashes, ramdisk, and multiple configs +PRINT_ITS = ''' +/dts-v1/; + +/ { + description = "Test FIT image for printing"; + #address-cells = <1>; + + images { + kernel { + description = "Test kernel"; + data = /incbin/("%(kernel)s"); + type = "kernel"; + arch = "sandbox"; + os = "linux"; + compression = "gzip"; + load = <0x1000000>; + entry = <0x1000000>; + hash-1 { + algo = "sha256"; + }; + }; + ramdisk { + description = "Test ramdisk"; + data = /incbin/("%(ramdisk)s"); + type = "ramdisk"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x2000000>; + hash-1 { + algo = "sha256"; + }; + }; + fdt { + description = "Test FDT"; + data = /incbin/("%(fdt)s"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + }; + configurations { + default = "conf-1"; + conf-1 { + description = "Test configuration"; + kernel = "kernel"; + fdt = "fdt"; + ramdisk = "ramdisk"; + }; + conf-2 { + description = "Alternate configuration"; + kernel = "kernel"; + fdt = "fdt"; + }; + }; +}; +''' + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_print') +@pytest.mark.requiredtool('dtc') +def test_fit_print(ubman): + """Test fit_print_contents() via C unit test""" + mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') + + # Create test files (make kernel ~6.3K) + kernel = fit_util.make_kernel(ubman, 'test-kernel.bin', + 'kernel with some extra test data') + + # Compress the kernel (with -n to avoid timestamps for reproducibility) + kernel_gz = kernel + '.gz' + utils.run_and_log(ubman, ['gzip', '-f', '-n', '-k', kernel]) + + fdt = fit_util.make_dtb(ubman, ''' +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <0>; + model = "Test"; +}; +''', 'test-fdt') + ramdisk = fit_util.make_kernel(ubman, 'test-ramdisk.bin', 'ramdisk') + + # Compress the ramdisk (with -n to avoid timestamps for reproducibility) + ramdisk_gz = ramdisk + '.gz' + utils.run_and_log(ubman, ['gzip', '-f', '-n', '-k', ramdisk]) + + # Create FIT image with fixed timestamp for reproducible output + params = { + 'kernel': kernel_gz, + 'fdt': fdt, + 'ramdisk': ramdisk_gz, + } + env = os.environ.copy() + env['SOURCE_DATE_EPOCH'] = '1234567890' # 2009-02-13 23:31:30 UTC + fit = os.path.join(ubman.config.persistent_data_dir, 'test-fit.fit') + its = fit_util.make_its(ubman, PRINT_ITS, params) + utils.run_and_log(ubman, [mkimage, '-f', its, fit], env=env) + + # Run the C test which will load and verify this FIT + ubman.run_command('ut -f bootstd test_fit_print_norun') + result = ubman.run_command('echo $?') + assert '0' == result -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a signature node to the FIT configuration in the ITS template, using a fixed RSA-2048 private key for reproducible signatures. Use the default 'pkcs-1.5' padding. Use mkimage to sign it. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/boot/fit_print.c | 4 +++ test/py/tests/test_fit_print.py | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c index ef1e86800ee..8aa1de3a6c4 100644 --- a/test/boot/fit_print.c +++ b/test/boot/fit_print.c @@ -80,6 +80,10 @@ static int test_fit_print_norun(struct unit_test_state *uts) ut_assert_nextline(" Kernel: kernel"); ut_assert_nextline(" Init Ramdisk: ramdisk"); ut_assert_nextline(" FDT: fdt"); + ut_assert_nextline(" Sign algo: sha256,rsa2048:test-key"); + ut_assert_nextline(" Sign padding: pkcs-1.5"); + ut_assert_nextlinen(" Sign value: 9ed5738204714c0ecf46"); + ut_assert_nextline(" Timestamp: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Configuration 1 (conf-2)"); ut_assert_nextline(" Description: Alternate configuration"); ut_assert_nextline(" Kernel: kernel"); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index 4960ce503b4..de52bbb61a4 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -63,6 +63,12 @@ PRINT_ITS = ''' kernel = "kernel"; fdt = "fdt"; ramdisk = "ramdisk"; + signature { + algo = "sha256,rsa2048"; + padding = "pkcs-1.5"; + key-name-hint = "test-key"; + sign-images = "fdt", "kernel", "ramdisk"; + }; }; conf-2 { description = "Alternate configuration"; @@ -76,6 +82,7 @@ PRINT_ITS = ''' @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('fit_print') @pytest.mark.requiredtool('dtc') +@pytest.mark.requiredtool('openssl') def test_fit_print(ubman): """Test fit_print_contents() via C unit test""" mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') @@ -114,6 +121,56 @@ def test_fit_print(ubman): its = fit_util.make_its(ubman, PRINT_ITS, params) utils.run_and_log(ubman, [mkimage, '-f', its, fit], env=env) + # Use a fixed RSA key pair for reproducible signatures + tmpdir = ubman.config.result_dir + '/' + + # Fixed 2048-bit RSA private key for testing (for reproducible signatures) + key_pem = '''-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDU18AB+xpQw+GX +mywzH4nsEIECgLVnBTNaAnE4XSIqbiviZetumBP6Ib2W+0OIOn8/hIh3UnzzyWIP +aRus94CVfFQPqwhi6/M9ptL7N7lCXq9DwQ0EY55GquwoO9jZnnDsCSU76jgKg+Nc +dsbvprfFDxBjkrLBfdEgzJtNUaJnUCd58RG8sII7EOP4JTGnXn2wVTsKYcTmr8y6 +bOZTUQfsYj9BGFTbskkLYj1RJ6Dpzk4yBqyUn4fUYhfqsAHwlJs/64Byx2m7J7Ia +rfp49NkqgOFlTvDzKnecxGt4pmgEA+4MtRxUFDliZ/bG3TvG/xNlXvWaHp9DG05u +4h9jy2NPAgMBAAECggEAAMZKOheeWGXmF8WmSwdV2qiSt54dSuMvdSfmHpTkL3BY +M4o4aZ4fEH138ak3bTL9TI9gacLAlqiIdVLmGWKLMsARlD8EmEuQhoxpXyWsRGwQ +yjfVIst0A4DSvDC/kMctVQaRfp7TFmK1fJwoDC44o/xyjFI32VFqZeqotAbUhvi3 +gIYvP5Q4Kvbaq9aZNURqazJHuEVD9LpwbnroUd4cBrcorstJzaDmTIyb5swLX+IX +FjMOVtHtBDKOG9Ce1wlEOXZtSsoZtAEgkd1IQYBCTBUDkxPdx+ZKPdfT4aKWX3S4 +WQ65lDEGAnplMmetFRV+k9NNJvEia9JoX/SJqhUWGQKBgQD1/rffQZnFWqGM2dD1 +CEkXpCN23xAEaZjQtuIhPMBWEWufAPZhyZSbq3eLjcqSS5mzU8B+n1c9Zxw6r0qM +BXlcUftreFPKvEXeyp1YWh7loxHiVVuasp2lEDx4arwUrI61XtAaixUb9Opxxj/x +UDrY5cj7BIRhrkDZtnor/EbRaQKBgQDdf9pymbbxRmHHFGERSzo6/gbr1GRK9fUA +ZNrzfBM5Sdvmm2aKgYd7hIKhOgeKIkS858gEOsRw75x6nvlrjZvFZGIfetXXxaN9 +c6Uqq/f6rTRUTB9/SqvMgKZMuJ2SFms8I1nbxSE/PMD0T6TRbhjaFoZwZP42HVsM +wAN2Oiq/9wKBgQC7sQHyYkdFgYVJxtfcXdoHI8G7bS73buqeNSwMWCIYiWooA7/5 +lKjCre2kmSc6wFwhq4FwG3ug6g9r51tlwrd6bUL8GO81/LkC6G1tgDWa2PVIUAB4 +5FfMHbtF1Ypz68VnNVRrLDuK/S/0Z2NaZ/C+lXTnseaf8Sih9Mz6yp3uIQKBgBc4 +61cuhH6hSWkM2uxsPaunrGQXPXiadthWupnifUV5V+PCkSqeT+0ERInQwq+Zzikc +B91hp+zLQlWcyzuaeiVk0+DHCRp5Lx3c/QkPRI10kVLxNDAtTPvA1S6gAG0rioyg +jDA9Z7Hwla5Hl1kZuONMj0XDYN+djkk07Gf9yzObAoGAbiS3mRID0pLFhWR1L64h +NlRJpZjsHNRPd0WFVxXnJRzZxkStoTwL2BhPtG3Xx1ReIkNVCxlu1Dk0rLLKl1nj +4B/X9Qu6aejXnOsbqp1/JBXYxD8l5B2yg5//wz18um/SOSagpAPeH4i/V3NxOup5 +S0n8gbs0Ht/ZckLk8mPclbk= +-----END PRIVATE KEY-----''' + + with open(tmpdir + 'test-key.key', 'w', encoding='utf-8') as f: + f.write(key_pem) + + utils.run_and_log(ubman, + f'openssl req -batch -new -x509 -key {tmpdir}test-key.key ' + f'-out {tmpdir}test-key.crt') + + # Create a dummy DTB for the public key + dtb = fit_util.make_fname(ubman, 'test-key.dtb') + utils.run_and_log(ubman, ['dtc', '-I', 'dts', '-O', 'dtb', '-o', dtb], + stdin=b'/dts-v1/; / { };') + + # Sign the FIT configuration (use env for reproducible timestamp) + utils.run_and_log(ubman, [mkimage, '-F', '-k', tmpdir, '-K', dtb, + '-r', fit, '-c', 'Configuration signing'], + env=env) + # Run the C test which will load and verify this FIT ubman.run_command('ut -f bootstd test_fit_print_norun') result = ubman.run_command('echo $?') -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update the FDT fdt to include two separate FDT images, referenced by the two configurations. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/boot/fit_print.c | 27 ++++++++++++++++------- test/py/tests/test_fit_print.py | 39 ++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c index 8aa1de3a6c4..69ab2ecf081 100644 --- a/test/boot/fit_print.c +++ b/test/boot/fit_print.c @@ -64,30 +64,41 @@ static int test_fit_print_norun(struct unit_test_state *uts) ut_assert_nextline(" Entry Point: unavailable"); ut_assert_nextline(" Hash algo: sha256"); ut_assert_nextline(" Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655"); - ut_assert_nextline(" Image 2 (fdt)"); - ut_assert_nextline(" Description: Test FDT"); + ut_assert_nextline(" Image 2 (fdt-1)"); + ut_assert_nextline(" Description: Test FDT 1"); ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Type: Flat Device Tree"); ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x00010514"); - ut_assert_nextline(" Data Size: 157 Bytes = 157 Bytes"); + ut_assert_nextline(" Data Start: 0x00010518"); + ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); ut_assert_nextline(" Architecture: Sandbox"); ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 51918524b06745cae06331047c7e566909431bf71338e5f703dffba1823274f4"); + ut_assert_nextline(" Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb"); + ut_assert_nextline(" Image 3 (fdt-2)"); + ut_assert_nextline(" Description: Test FDT 2"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Flat Device Tree"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x0001067c"); + ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4"); ut_assert_nextline(" Default Configuration: 'conf-1'"); ut_assert_nextline(" Configuration 0 (conf-1)"); ut_assert_nextline(" Description: Test configuration"); ut_assert_nextline(" Kernel: kernel"); ut_assert_nextline(" Init Ramdisk: ramdisk"); - ut_assert_nextline(" FDT: fdt"); + ut_assert_nextline(" FDT: fdt-1"); ut_assert_nextline(" Sign algo: sha256,rsa2048:test-key"); ut_assert_nextline(" Sign padding: pkcs-1.5"); - ut_assert_nextlinen(" Sign value: 9ed5738204714c0ecf46"); + ut_assert_nextlinen(" Sign value: 6b1cc88f8b3b7f2f148d"); ut_assert_nextline(" Timestamp: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Configuration 1 (conf-2)"); ut_assert_nextline(" Description: Alternate configuration"); ut_assert_nextline(" Kernel: kernel"); - ut_assert_nextline(" FDT: fdt"); + ut_assert_nextline(" FDT: fdt-1"); + ut_assert_nextline(" fdt-2"); ut_assert_console_end(); os_free(buf); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index de52bbb61a4..5127fc6f8f0 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -45,9 +45,19 @@ PRINT_ITS = ''' algo = "sha256"; }; }; - fdt { - description = "Test FDT"; - data = /incbin/("%(fdt)s"); + fdt-1 { + description = "Test FDT 1"; + data = /incbin/("%(fdt1)s"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + fdt-2 { + description = "Test FDT 2"; + data = /incbin/("%(fdt2)s"); type = "flat_dt"; arch = "sandbox"; compression = "none"; @@ -61,19 +71,19 @@ PRINT_ITS = ''' conf-1 { description = "Test configuration"; kernel = "kernel"; - fdt = "fdt"; + fdt = "fdt-1"; ramdisk = "ramdisk"; signature { algo = "sha256,rsa2048"; padding = "pkcs-1.5"; key-name-hint = "test-key"; - sign-images = "fdt", "kernel", "ramdisk"; + sign-images = "fdt-1", "kernel", "ramdisk"; }; }; conf-2 { description = "Alternate configuration"; kernel = "kernel"; - fdt = "fdt"; + fdt = "fdt-1", "fdt-2"; }; }; }; @@ -95,14 +105,22 @@ def test_fit_print(ubman): kernel_gz = kernel + '.gz' utils.run_and_log(ubman, ['gzip', '-f', '-n', '-k', kernel]) - fdt = fit_util.make_dtb(ubman, ''' + fdt1 = fit_util.make_dtb(ubman, ''' +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <0>; + model = "Test FDT 1"; +}; +''', 'test-fdt-1') + fdt2 = fit_util.make_dtb(ubman, ''' /dts-v1/; / { #address-cells = <1>; #size-cells = <0>; - model = "Test"; + model = "Test FDT 2"; }; -''', 'test-fdt') +''', 'test-fdt-2') ramdisk = fit_util.make_kernel(ubman, 'test-ramdisk.bin', 'ramdisk') # Compress the ramdisk (with -n to avoid timestamps for reproducibility) @@ -112,7 +130,8 @@ def test_fit_print(ubman): # Create FIT image with fixed timestamp for reproducible output params = { 'kernel': kernel_gz, - 'fdt': fdt, + 'fdt1': fdt1, + 'fdt2': fdt2, 'ramdisk': ramdisk_gz, } env = os.environ.copy() -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add support for testing the loadables, fpga, compatible properties and unavailable/error conditions in FIT configurations. With this, most of the FIT-printing code is covered by tests. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/boot/fit_print.c | 54 ++++++++++++++++++++++++++++++- test/py/tests/test_fit_print.py | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c index 69ab2ecf081..856cbfc6613 100644 --- a/test/boot/fit_print.c +++ b/test/boot/fit_print.c @@ -84,21 +84,73 @@ static int test_fit_print_norun(struct unit_test_state *uts) ut_assert_nextline(" Architecture: Sandbox"); ut_assert_nextline(" Hash algo: sha256"); ut_assert_nextline(" Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4"); + ut_assert_nextline(" Image 4 (firmware-1)"); + ut_assert_nextline(" Description: Test Firmware 1"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Firmware"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000107e8"); + ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Unknown OS"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414"); + ut_assert_nextline(" Image 5 (firmware-2)"); + ut_assert_nextline(" Description: Test Firmware 2"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Firmware"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000117e8"); + ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Unknown OS"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1"); + ut_assert_nextline(" Image 6 (fpga)"); + ut_assert_nextline(" Description: Test FPGA"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: FPGA Image"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000127e0"); + ut_assert_nextline(" Data Size: 4291 Bytes = 4.2 KiB"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622"); + ut_assert_nextline(" Image 7 (script)"); + ut_assert_nextline(" Description: unavailable"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Script"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x0001394c"); + ut_assert_nextline(" Data Size: 3791 Bytes = 3.7 KiB"); + ut_assert_nextline(" Hash algo: invalid/unsupported"); ut_assert_nextline(" Default Configuration: 'conf-1'"); ut_assert_nextline(" Configuration 0 (conf-1)"); ut_assert_nextline(" Description: Test configuration"); ut_assert_nextline(" Kernel: kernel"); ut_assert_nextline(" Init Ramdisk: ramdisk"); ut_assert_nextline(" FDT: fdt-1"); + ut_assert_nextline(" Compatible: vendor,board-1.0"); + ut_assert_nextline(" vendor,board"); ut_assert_nextline(" Sign algo: sha256,rsa2048:test-key"); ut_assert_nextline(" Sign padding: pkcs-1.5"); - ut_assert_nextlinen(" Sign value: 6b1cc88f8b3b7f2f148d"); + ut_assert_nextlinen(" Sign value: c20f64d9bf79ddb0b1a6"); ut_assert_nextline(" Timestamp: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Configuration 1 (conf-2)"); ut_assert_nextline(" Description: Alternate configuration"); ut_assert_nextline(" Kernel: kernel"); ut_assert_nextline(" FDT: fdt-1"); ut_assert_nextline(" fdt-2"); + ut_assert_nextline(" FPGA: fpga"); + ut_assert_nextline(" Loadables: firmware-1"); + ut_assert_nextline(" firmware-2"); + ut_assert_nextline(" Compatible: vendor,board-2.0"); + ut_assert_nextline(" Configuration 2 (conf-3)"); + ut_assert_nextline(" Description: unavailable"); + ut_assert_nextline(" Kernel: unavailable"); + ut_assert_nextline(" Loadables: script"); ut_assert_console_end(); os_free(buf); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index 5127fc6f8f0..25fada7d468 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -65,6 +65,44 @@ PRINT_ITS = ''' algo = "sha256"; }; }; + firmware-1 { + description = "Test Firmware 1"; + data = /incbin/("%(firmware1)s"); + type = "firmware"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + firmware-2 { + description = "Test Firmware 2"; + data = /incbin/("%(firmware2)s"); + type = "firmware"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + fpga { + description = "Test FPGA"; + data = /incbin/("%(fpga)s"); + type = "fpga"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + script { + data = /incbin/("%(script)s"); + type = "script"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; }; configurations { default = "conf-1"; @@ -73,6 +111,7 @@ PRINT_ITS = ''' kernel = "kernel"; fdt = "fdt-1"; ramdisk = "ramdisk"; + compatible = "vendor,board-1.0", "vendor,board"; signature { algo = "sha256,rsa2048"; padding = "pkcs-1.5"; @@ -84,6 +123,12 @@ PRINT_ITS = ''' description = "Alternate configuration"; kernel = "kernel"; fdt = "fdt-1", "fdt-2"; + fpga = "fpga"; + loadables = "firmware-1", "firmware-2"; + compatible = "vendor,board-2.0"; + }; + conf-3 { + loadables = "script"; }; }; }; @@ -121,7 +166,11 @@ def test_fit_print(ubman): model = "Test FDT 2"; }; ''', 'test-fdt-2') + firmware1 = fit_util.make_kernel(ubman, 'test-firmware-1.bin', 'firmware 1') + firmware2 = fit_util.make_kernel(ubman, 'test-firmware-2.bin', 'firmware 2') + fpga = fit_util.make_kernel(ubman, 'test-fpga.bin', 'fpga bitstream') ramdisk = fit_util.make_kernel(ubman, 'test-ramdisk.bin', 'ramdisk') + script = fit_util.make_kernel(ubman, 'test-script.bin', 'echo test') # Compress the ramdisk (with -n to avoid timestamps for reproducibility) ramdisk_gz = ramdisk + '.gz' @@ -132,7 +181,11 @@ def test_fit_print(ubman): 'kernel': kernel_gz, 'fdt1': fdt1, 'fdt2': fdt2, + 'firmware1': firmware1, + 'firmware2': firmware2, + 'fpga': fpga, 'ramdisk': ramdisk_gz, + 'script': script, } env = os.environ.copy() env['SOURCE_DATE_EPOCH'] = '1234567890' # 2009-02-13 23:31:30 UTC @@ -190,6 +243,10 @@ S0n8gbs0Ht/ZckLk8mPclbk= '-r', fit, '-c', 'Configuration signing'], env=env) + # Delete the algo property from the hash-1 node to test invalid/unsupported + utils.run_and_log(ubman, ['fdtput', '-d', fit, '/images/script/hash-1', + 'algo']) + # Run the C test which will load and verify this FIT ubman.run_command('ut -f bootstd test_fit_print_norun') result = ubman.run_command('echo $?') -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a test to verify that fit_print_contents() correctly handles a FIT image with a missing description property. To handle this a new FIT created with the description removed after mkimage has processed it, since mkimage will fail if the description is missing. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/boot/fit_print.c | 32 ++++++++++++++++++++++++ test/py/tests/test_fit_print.py | 43 +++++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c index 856cbfc6613..8e8d81e7f6b 100644 --- a/test/boot/fit_print.c +++ b/test/boot/fit_print.c @@ -158,3 +158,35 @@ static int test_fit_print_norun(struct unit_test_state *uts) return 0; } BOOTSTD_TEST(test_fit_print_norun, UTF_CONSOLE | UTF_MANUAL); + +/* Test fit_print_contents() with missing FIT description */ +static int test_fit_print_no_desc_norun(struct unit_test_state *uts) +{ + char fname[256]; + void *fit; + void *buf; + ulong addr; + int size; + + /* Load the FIT created by the Python test (with deleted description) */ + ut_assertok(os_persistent_file(fname, sizeof(fname), + "test-fit-nodesc.fit")); + ut_assertok(os_read_file(fname, &buf, &size)); + + /* Copy to address 0x10000 and print from there */ + addr = 0x10000; + fit = map_sysmem(addr, size); + memcpy(fit, buf, size); + + /* Print it and check just the first line */ + console_record_reset_enable(); + fit_print_contents(fit); + + /* Check the first line shows unavailable */ + ut_assert_nextline(" FIT description: unavailable"); + + os_free(buf); + + return 0; +} +BOOTSTD_TEST(test_fit_print_no_desc_norun, UTF_CONSOLE | UTF_MANUAL); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index 25fada7d468..0ab8c0d4769 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -134,12 +134,14 @@ PRINT_ITS = ''' }; ''' -@pytest.mark.boardspec('sandbox') -@pytest.mark.buildconfigspec('fit_print') -@pytest.mark.requiredtool('dtc') -@pytest.mark.requiredtool('openssl') -def test_fit_print(ubman): - """Test fit_print_contents() via C unit test""" +def build_test_fit(ubman, fit): + """Build a test FIT image with all components + + Args: + ubman (ConsoleBase): U-Boot manager object + fit (str): Path where the FIT file should be created + """ + # pylint: disable=too-many-locals mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') # Create test files (make kernel ~6.3K) @@ -189,7 +191,6 @@ def test_fit_print(ubman): } env = os.environ.copy() env['SOURCE_DATE_EPOCH'] = '1234567890' # 2009-02-13 23:31:30 UTC - fit = os.path.join(ubman.config.persistent_data_dir, 'test-fit.fit') its = fit_util.make_its(ubman, PRINT_ITS, params) utils.run_and_log(ubman, [mkimage, '-f', its, fit], env=env) @@ -247,7 +248,35 @@ S0n8gbs0Ht/ZckLk8mPclbk= utils.run_and_log(ubman, ['fdtput', '-d', fit, '/images/script/hash-1', 'algo']) + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_print') +@pytest.mark.requiredtool('dtc') +@pytest.mark.requiredtool('openssl') +def test_fit_print(ubman): + """Test fit_print_contents() via C unit test""" + fit = os.path.join(ubman.config.persistent_data_dir, 'test-fit.fit') + build_test_fit(ubman, fit) + # Run the C test which will load and verify this FIT ubman.run_command('ut -f bootstd test_fit_print_norun') result = ubman.run_command('echo $?') assert '0' == result + + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_print') +@pytest.mark.requiredtool('dtc') +@pytest.mark.requiredtool('openssl') +def test_fit_print_no_desc(ubman): + """Test fit_print_contents() with missing FIT description""" + fit = os.path.join(ubman.config.persistent_data_dir, 'test-fit-nodesc.fit') + build_test_fit(ubman, fit) + + # Delete the description property + utils.run_and_log(ubman, ['fdtput', '-d', fit, '/', 'description']) + + # Run the C test to check the missing description + ubman.run_command('ut -f bootstd test_fit_print_no_desc_norun') + result = ubman.run_command('echo $?') + assert '0' == result -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a new pytest to check the output of 'mkimage -l' on the test FIT. Only check the first 80 chars as the signature lines can be very long. The timestamps are quite annoying, since we need the test to pass on whatever CI machine is used. Obtain the first timestamp and use that to check the rest, after some sanity checks. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/py/tests/test_fit_print.py | 149 ++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index 0ab8c0d4769..180467fba72 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -5,6 +5,8 @@ """Test for FIT image printing""" import os +import re +import time import pytest @@ -280,3 +282,150 @@ def test_fit_print_no_desc(ubman): ubman.run_command('ut -f bootstd test_fit_print_no_desc_norun') result = ubman.run_command('echo $?') assert '0' == result + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_print') +@pytest.mark.requiredtool('dtc') +@pytest.mark.requiredtool('openssl') +def test_fit_print_mkimage(ubman): + """Test 'mkimage -l' output on FIT image""" + mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') + fit = fit_util.make_fname(ubman, 'test-fit-mkimage.fit') + build_test_fit(ubman, fit) + + # Run mkimage -l and capture output + output = utils.run_and_log(ubman, [mkimage, '-l', fit]) + + # Extract the actual timestamp from mkimage output to avoid timezone issues + # mkimage uses localtime() which can vary based on system timezone + match = re.search(r'Created:\s+(.+)', output) + if not match: + raise ValueError("Could not find Created: line in mkimage output") + timestamp_str = match.group(1).strip() + + expected_timestamp = 1234567890 + # Validate timestamp is reasonable (SOURCE_DATE_EPOCH) + parsed_time = time.strptime(timestamp_str, '%a %b %d %H:%M:%S %Y') + parsed_timestamp = time.mktime(parsed_time) + time_diff = abs(parsed_timestamp - expected_timestamp) + + # Check it is within 24 hours (86400 seconds) + assert time_diff < 86400, \ + f"Timestamp {timestamp_str} is more than 24 hours from expected" + + # Expected output (complete output from mkimage -l) + expected = f''' +FIT description: Test FIT image for printing +Created: {timestamp_str} + Image 0 (kernel) + Description: Test kernel + Created: {timestamp_str} + Type: Kernel Image + Compression: gzip compressed + Data Size: 327 Bytes = 0.32 KiB = 0.00 MiB + Architecture: Sandbox + OS: Linux + Load Address: 0x01000000 + Entry Point: 0x01000000 + Hash algo: sha256 + Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee + Image 1 (ramdisk) + Description: Test ramdisk + Created: {timestamp_str} + Type: RAMDisk Image + Compression: uncompressed + Data Size: 301 Bytes = 0.29 KiB = 0.00 MiB + Architecture: Sandbox + OS: Linux + Load Address: 0x02000000 + Entry Point: unavailable + Hash algo: sha256 + Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655 + Image 2 (fdt-1) + Description: Test FDT 1 + Created: {timestamp_str} + Type: Flat Device Tree + Compression: uncompressed + Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB + Architecture: Sandbox + Hash algo: sha256 + Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb + Image 3 (fdt-2) + Description: Test FDT 2 + Created: {timestamp_str} + Type: Flat Device Tree + Compression: uncompressed + Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB + Architecture: Sandbox + Hash algo: sha256 + Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4 + Image 4 (firmware-1) + Description: Test Firmware 1 + Created: {timestamp_str} + Type: Firmware + Compression: uncompressed + Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB + Architecture: Sandbox + OS: Unknown OS + Load Address: unavailable + Hash algo: sha256 + Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414 + Image 5 (firmware-2) + Description: Test Firmware 2 + Created: {timestamp_str} + Type: Firmware + Compression: uncompressed + Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB + Architecture: Sandbox + OS: Unknown OS + Load Address: unavailable + Hash algo: sha256 + Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1 + Image 6 (fpga) + Description: Test FPGA + Created: {timestamp_str} + Type: FPGA Image + Compression: uncompressed + Data Size: 4291 Bytes = 4.19 KiB = 0.00 MiB + Load Address: unavailable + Hash algo: sha256 + Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622 + Image 7 (script) + Description: unavailable + Created: {timestamp_str} + Type: Script + Compression: uncompressed + Data Size: 3791 Bytes = 3.70 KiB = 0.00 MiB + Hash algo: invalid/unsupported + Default Configuration: 'conf-1' + Configuration 0 (conf-1) + Description: Test configuration + Kernel: kernel + Init Ramdisk: ramdisk + FDT: fdt-1 + Compatible: vendor,board-1.0 + vendor,board + Sign algo: sha256,rsa2048:test-key + Sign padding: pkcs-1.5 + Sign value: c20f64d9bf79ddb0b1a69293b2375ad88e70536684705a9577f2156e6da4df6d + Timestamp: {timestamp_str} + Configuration 1 (conf-2) + Description: Alternate configuration + Kernel: kernel + FDT: fdt-1 + fdt-2 + FPGA: fpga + Loadables: firmware-1 + firmware-2 + Compatible: vendor,board-2.0 + Configuration 2 (conf-3) + Description: unavailable + Kernel: unavailable + Loadables: script +'''.strip().split('\n') + + lines = output.split('\n') + for seq, (expected, line) in enumerate(zip(expected, lines)): + exp = expected[:80] + act = line[:80] + assert exp == act, f"line {seq + 1}: expect '{exp}' got '{act}'" -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Create a new fit_print() function containing the logic from fit_print_contents(), and make fit_print_contents() call it. This allows future callers to use fit_print() directly as we add more features. Tidy up the function comments so that they are in the header. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/image-fit.c | 34 ++++++---------------------------- include/image.h | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/boot/image-fit.c b/boot/image-fit.c index eb47c00cc01..9103016bd08 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -368,19 +368,7 @@ static void fit_conf_print(const void *fit, int noffset, const char *p) } } -/** - * fit_print_contents - prints out the contents of the FIT format image - * @fit: pointer to the FIT format image header - * @p: pointer to prefix string - * - * fit_print_contents() formats a multi line FIT image contents description. - * The routine prints out FIT image properties (root node level) followed by - * the details of each component image. - * - * returns: - * no returned results - */ -void fit_print_contents(const void *fit) +void fit_print(const void *fit) { const char *desc; char *uname; @@ -472,21 +460,11 @@ void fit_print_contents(const void *fit) } } -/** - * fit_image_print - prints out the FIT component image details - * @fit: pointer to the FIT format image header - * @image_noffset: offset of the component image node - * @p: pointer to prefix string - * - * fit_image_print() lists all mandatory properties for the processed component - * image. If present, hash nodes are printed out as well. Load - * address for images of type firmware is also printed out. Since the load - * address is not mandatory for firmware images, it will be output as - * "unavailable" when not present. - * - * returns: - * no returned results - */ +void fit_print_contents(const void *fit) +{ + fit_print(fit); +} + void fit_image_print(const void *fit, int image_noffset, const char *p) { uint8_t type, arch, os, comp = IH_COMP_NONE; diff --git a/include/image.h b/include/image.h index 33eb5d71e79..2f9469e2709 100644 --- a/include/image.h +++ b/include/image.h @@ -1198,9 +1198,52 @@ int fit_parse_subimage(const char *spec, ulong addr_curr, ulong *addr, const char **image_name); int fit_get_subimage_count(const void *fit, int images_noffset); -void fit_print_contents(const void *fit); + +/** + * fit_print() - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * This formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) followed by + * the details of each component image. + * + * returns: + * no returned results + */ +void fit_print(const void *fit); + +/** + * fit_image_print - prints out the FIT component image details + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properties for the processed component + * image. If present, hash nodes are printed out as well. Load + * address for images of type firmware is also printed out. Since the load + * address is not mandatory for firmware images, it will be output as + * "unavailable" when not present. + * + * returns: + * no returned results + */ void fit_image_print(const void *fit, int noffset, const char *p); +/** + * fit_print_contents() - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * This formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) followed by + * the details of each component image. + * + * returns: + * no returned results + */ +void fit_print_contents(const void *fit); + /** * fit_get_end - get FIT image size * @fit: pointer to the FIT format image header -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> There is enough code here that it makes sense to put it in its own file. Create a new fit_print.c file, before undertaking future refactoring. Printing is only included in the main build if CONFIG_FIT_PRINT is enabled, although it is always included in the tools build. Add static inlines for existing callers. Make a few small code-style adjustments, including fixing checkpatch warnings about over-use of brackets. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/Makefile | 1 + boot/fit_print.c | 411 +++++++++++++++++++++++++++++++++++++++++++++++ boot/image-fit.c | 394 --------------------------------------------- include/image.h | 12 ++ tools/Makefile | 1 + 5 files changed, 425 insertions(+), 394 deletions(-) create mode 100644 boot/fit_print.c diff --git a/boot/Makefile b/boot/Makefile index cfa5a0a98e9..725af083e66 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_$(PHASE_)UPL_WRITE) += upl_write.o obj-$(CONFIG_$(PHASE_)OF_LIBFDT) += image-fdt.o obj-$(CONFIG_$(PHASE_)FIT_SIGNATURE) += fdt_region.o obj-$(CONFIG_$(PHASE_)FIT) += image-fit.o +obj-$(CONFIG_$(PHASE_)FIT_PRINT) += fit_print.o obj-$(CONFIG_$(PHASE_)MULTI_DTB_FIT) += boot_fit.o common_fit.o obj-$(CONFIG_$(PHASE_)IMAGE_PRE_LOAD) += image-pre-load.o obj-$(CONFIG_$(PHASE_)IMAGE_SIGN_INFO) += image-sig.o diff --git a/boot/fit_print.c b/boot/fit_print.c new file mode 100644 index 00000000000..134625396bd --- /dev/null +++ b/boot/fit_print.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2013, Google Inc. + * + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#define LOG_CATEGORY LOGC_BOOT + +#ifdef USE_HOSTCC +#include "mkimage.h" +#include <time.h> +#include <linux/libfdt.h> +#else +#include <log.h> +#include <malloc.h> +#include <mapmem.h> +#include <linux/compiler.h> +#endif + +#include <image.h> +#include <u-boot/crc.h> + +/** + * fit_image_print_data() - prints out the hash node details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash node + * @p: pointer to prefix string + * @type: Type of information to print ("hash" or "sign") + * + * fit_image_print_data() lists properties for the processed hash node + * + * This function avoid using puts() since it prints a newline on the host + * but does not in U-Boot. + * + * returns: + * no returned results + */ +static void fit_image_print_data(const void *fit, int noffset, const char *p, + const char *type) +{ + const char *keyname, *padding, *algo; + int value_len, ret, i; + uint8_t *value; + bool required; + + debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); + printf("%s %s algo: ", p, type); + if (fit_image_hash_get_algo(fit, noffset, &algo)) { + printf("invalid/unsupported\n"); + return; + } + printf("%s", algo); + keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); + required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL); + if (keyname) + printf(":%s", keyname); + if (required) + printf(" (required)"); + printf("\n"); + + padding = fdt_getprop(fit, noffset, "padding", NULL); + if (padding) + printf("%s %s padding: %s\n", p, type, padding); + + ret = fit_image_hash_get_value(fit, noffset, &value, &value_len); + printf("%s %s value: ", p, type); + if (ret) { + printf("unavailable\n"); + } else { + for (i = 0; i < value_len; i++) + printf("%02x", value[i]); + printf("\n"); + } + + debug("%s %s len: %d\n", p, type, value_len); + + /* Signatures have a time stamp */ + if (IMAGE_ENABLE_TIMESTAMP && keyname) { + time_t timestamp; + + printf("%s Timestamp: ", p); + if (fit_get_timestamp(fit, noffset, ×tamp)) + printf("unavailable\n"); + else + genimg_print_time(timestamp); + } +} + +/** + * fit_image_print_verification_data() - prints out the hash/signature details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash or signature node + * @p: pointer to prefix string + * + * This lists properties for the processed hash node + * + * returns: + * no returned results + */ +static void fit_image_print_verification_data(const void *fit, int noffset, + const char *p) +{ + const char *name; + + /* + * Check subnode name, must be equal to "hash" or "signature". + * Multiple hash/signature nodes require unique unit node + * names, e.g. hash-1, hash-2, signature-1, signature-2, etc. + */ + name = fit_get_name(fit, noffset); + if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) + fit_image_print_data(fit, noffset, p, "Hash"); + else if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) + fit_image_print_data(fit, noffset, p, "Sign"); +} + +void fit_image_print(const void *fit, int image_noffset, const char *p) +{ + uint8_t type, arch, os, comp = IH_COMP_NONE; + const char *desc; + size_t size; + ulong load, entry; + const void *data; + int noffset; + int ndepth; + int ret; + + if (!CONFIG_IS_ENABLED(FIT_PRINT)) + return; + + /* Mandatory properties */ + ret = fit_get_desc(fit, image_noffset, &desc); + printf("%s Description: ", p); + if (ret) + printf("unavailable\n"); + else + printf("%s\n", desc); + + if (IMAGE_ENABLE_TIMESTAMP) { + time_t timestamp; + + ret = fit_get_timestamp(fit, 0, ×tamp); + printf("%s Created: ", p); + if (ret) + printf("unavailable\n"); + else + genimg_print_time(timestamp); + } + + fit_image_get_type(fit, image_noffset, &type); + printf("%s Type: %s\n", p, genimg_get_type_name(type)); + + fit_image_get_comp(fit, image_noffset, &comp); + printf("%s Compression: %s\n", p, genimg_get_comp_name(comp)); + + ret = fit_image_get_data(fit, image_noffset, &data, &size); + + if (!tools_build()) { + printf("%s Data Start: ", p); + if (ret) { + printf("unavailable\n"); + } else { + void *vdata = (void *)data; + + printf("0x%08lx\n", (ulong)map_to_sysmem(vdata)); + } + } + + printf("%s Data Size: ", p); + if (ret) + printf("unavailable\n"); + else + genimg_print_size(size); + + /* Remaining, type dependent properties */ + if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || + type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE || + type == IH_TYPE_FLATDT) { + fit_image_get_arch(fit, image_noffset, &arch); + printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); + } + + if (type == IH_TYPE_KERNEL || type == IH_TYPE_RAMDISK || + type == IH_TYPE_FIRMWARE) { + fit_image_get_os(fit, image_noffset, &os); + printf("%s OS: %s\n", p, genimg_get_os_name(os)); + } + + if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || + type == IH_TYPE_FIRMWARE || type == IH_TYPE_RAMDISK || + type == IH_TYPE_FPGA) { + ret = fit_image_get_load(fit, image_noffset, &load); + printf("%s Load Address: ", p); + if (ret) + printf("unavailable\n"); + else + printf("0x%08lx\n", load); + } + + /* optional load address for FDT */ + if (type == IH_TYPE_FLATDT && + !fit_image_get_load(fit, image_noffset, &load)) + printf("%s Load Address: 0x%08lx\n", p, load); + + if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || + type == IH_TYPE_RAMDISK) { + ret = fit_image_get_entry(fit, image_noffset, &entry); + printf("%s Entry Point: ", p); + if (ret) + printf("unavailable\n"); + else + printf("0x%08lx\n", entry); + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + fit_image_print_verification_data(fit, noffset, p); + } + } +} + +/** + * fit_conf_print - prints out the FIT configuration details + * @fit: pointer to the FIT format image header + * @noffset: offset of the configuration node + * @p: pointer to prefix string + * + * fit_conf_print() lists all mandatory properties for the processed + * configuration node. + * + * returns: + * no returned results + */ +static void fit_conf_print(const void *fit, int noffset, const char *p) +{ + const char *uname, *desc; + int ret, ndepth, i; + + /* Mandatory properties */ + ret = fit_get_desc(fit, noffset, &desc); + printf("%s Description: ", p); + if (ret) + printf("unavailable\n"); + else + printf("%s\n", desc); + + uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); + printf("%s Kernel: ", p); + if (!uname) + printf("unavailable\n"); + else + printf("%s\n", uname); + + /* Optional properties */ + uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); + if (uname) + printf("%s Init Ramdisk: %s\n", p, uname); + + uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL); + if (uname) + printf("%s Firmware: %s\n", p, uname); + + for (i = 0; + uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, + i, NULL), uname; + i++) { + if (!i) + printf("%s FDT: ", p); + else + printf("%s ", p); + printf("%s\n", uname); + } + + uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); + if (uname) + printf("%s FPGA: %s\n", p, uname); + + /* Print out all of the specified loadables */ + for (i = 0; + uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP, + i, NULL), uname; + i++) { + if (!i) + printf("%s Loadables: ", p); + else + printf("%s ", p); + printf("%s\n", uname); + } + + /* Show the list of compatible strings */ + for (i = 0; uname = fdt_stringlist_get(fit, noffset, + FIT_COMPATIBLE_PROP, i, NULL), uname; i++) { + if (!i) + printf("%s Compatible: ", p); + else + printf("%s ", p); + printf("%s\n", uname); + } + + /* Process all hash subnodes of the component configuration node */ + for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component config node */ + fit_image_print_verification_data(fit, noffset, p); + } + } +} + +void fit_print(const void *fit) +{ + const char *desc; + char *uname; + int images_noffset; + int confs_noffset; + int noffset; + int ndepth; + int count = 0; + int ret; + const char *p; + time_t timestamp; + + /* Indent string is defined in header image.h */ + p = IMAGE_INDENT_STRING; + + /* Root node properties */ + ret = fit_get_desc(fit, 0, &desc); + printf("%sFIT description: ", p); + if (ret) + printf("unavailable\n"); + else + printf("%s\n", desc); + + if (IMAGE_ENABLE_TIMESTAMP) { + ret = fit_get_timestamp(fit, 0, ×tamp); + printf("%sCreated: ", p); + if (ret) + printf("unavailable\n"); + else + genimg_print_time(timestamp); + } + + /* Find images parent node offset */ + 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; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf("%s Image %u (%s)\n", p, count++, + fit_get_name(fit, noffset)); + + fit_image_print(fit, noffset, p); + } + } + + /* Find configurations parent node offset */ + confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug("Can't get configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror(confs_noffset)); + return; + } + + /* get default configuration unit name from default property */ + uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); + if (uname) + printf("%s Default Configuration: '%s'\n", p, uname); + + /* Process its subnodes, print out configurations details */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, confs_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the configurations parent node, + * i.e. configuration node. + */ + printf("%s Configuration %u (%s)\n", p, count++, + fit_get_name(fit, noffset)); + + fit_conf_print(fit, noffset, p); + } + } +} + +void fit_print_contents(const void *fit) +{ + fit_print(fit); +} diff --git a/boot/image-fit.c b/boot/image-fit.c index 9103016bd08..5eef9479781 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -179,400 +179,6 @@ int fit_get_subimage_count(const void *fit, int images_noffset) return count; } -/** - * fit_image_print_data() - prints out the hash node details - * @fit: pointer to the FIT format image header - * @noffset: offset of the hash node - * @p: pointer to prefix string - * @type: Type of information to print ("hash" or "sign") - * - * fit_image_print_data() lists properties for the processed hash node - * - * This function avoid using puts() since it prints a newline on the host - * but does not in U-Boot. - * - * returns: - * no returned results - */ -static void fit_image_print_data(const void *fit, int noffset, const char *p, - const char *type) -{ - const char *keyname; - uint8_t *value; - int value_len; - const char *algo; - const char *padding; - bool required; - int ret, i; - - debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); - printf("%s %s algo: ", p, type); - if (fit_image_hash_get_algo(fit, noffset, &algo)) { - printf("invalid/unsupported\n"); - return; - } - printf("%s", algo); - keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); - required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL; - if (keyname) - printf(":%s", keyname); - if (required) - printf(" (required)"); - printf("\n"); - - padding = fdt_getprop(fit, noffset, "padding", NULL); - if (padding) - printf("%s %s padding: %s\n", p, type, padding); - - ret = fit_image_hash_get_value(fit, noffset, &value, - &value_len); - printf("%s %s value: ", p, type); - if (ret) { - printf("unavailable\n"); - } else { - for (i = 0; i < value_len; i++) - printf("%02x", value[i]); - printf("\n"); - } - - debug("%s %s len: %d\n", p, type, value_len); - - /* Signatures have a time stamp */ - if (IMAGE_ENABLE_TIMESTAMP && keyname) { - time_t timestamp; - - printf("%s Timestamp: ", p); - if (fit_get_timestamp(fit, noffset, ×tamp)) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } -} - -/** - * fit_image_print_verification_data() - prints out the hash/signature details - * @fit: pointer to the FIT format image header - * @noffset: offset of the hash or signature node - * @p: pointer to prefix string - * - * This lists properties for the processed hash node - * - * returns: - * no returned results - */ -static void fit_image_print_verification_data(const void *fit, int noffset, - const char *p) -{ - const char *name; - - /* - * Check subnode name, must be equal to "hash" or "signature". - * Multiple hash/signature nodes require unique unit node - * names, e.g. hash-1, hash-2, signature-1, signature-2, etc. - */ - name = fit_get_name(fit, noffset); - if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) { - fit_image_print_data(fit, noffset, p, "Hash"); - } else if (!strncmp(name, FIT_SIG_NODENAME, - strlen(FIT_SIG_NODENAME))) { - fit_image_print_data(fit, noffset, p, "Sign"); - } -} - -/** - * fit_conf_print - prints out the FIT configuration details - * @fit: pointer to the FIT format image header - * @noffset: offset of the configuration node - * @p: pointer to prefix string - * - * fit_conf_print() lists all mandatory properties for the processed - * configuration node. - * - * returns: - * no returned results - */ -static void fit_conf_print(const void *fit, int noffset, const char *p) -{ - const char *uname, *desc; - int ret, ndepth, i; - - /* Mandatory properties */ - ret = fit_get_desc(fit, noffset, &desc); - printf("%s Description: ", p); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); - - uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); - printf("%s Kernel: ", p); - if (!uname) - printf("unavailable\n"); - else - printf("%s\n", uname); - - /* Optional properties */ - uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); - if (uname) - printf("%s Init Ramdisk: %s\n", p, uname); - - uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL); - if (uname) - printf("%s Firmware: %s\n", p, uname); - - for (i = 0; - uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, - i, NULL), uname; - i++) { - if (!i) - printf("%s FDT: ", p); - else - printf("%s ", p); - printf("%s\n", uname); - } - - uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); - if (uname) - printf("%s FPGA: %s\n", p, uname); - - /* Print out all of the specified loadables */ - for (i = 0; - uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP, - i, NULL), uname; - i++) { - if (!i) - printf("%s Loadables: ", p); - else - printf("%s ", p); - printf("%s\n", uname); - } - - /* Show the list of compatible strings */ - for (i = 0; uname = fdt_stringlist_get(fit, noffset, - FIT_COMPATIBLE_PROP, i, NULL), uname; i++) { - if (!i) - printf("%s Compatible: ", p); - else - printf("%s ", p); - printf("%s\n", uname); - } - - /* Process all hash subnodes of the component configuration node */ - for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* Direct child node of the component configuration node */ - fit_image_print_verification_data(fit, noffset, p); - } - } -} - -void fit_print(const void *fit) -{ - const char *desc; - char *uname; - int images_noffset; - int confs_noffset; - int noffset; - int ndepth; - int count = 0; - int ret; - const char *p; - time_t timestamp; - - if (!CONFIG_IS_ENABLED(FIT_PRINT)) - return; - - /* Indent string is defined in header image.h */ - p = IMAGE_INDENT_STRING; - - /* Root node properties */ - ret = fit_get_desc(fit, 0, &desc); - printf("%sFIT description: ", p); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); - - if (IMAGE_ENABLE_TIMESTAMP) { - ret = fit_get_timestamp(fit, 0, ×tamp); - printf("%sCreated: ", p); - if (ret) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } - - /* Find images parent node offset */ - 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; - } - - /* Process its subnodes, print out component images details */ - for (ndepth = 0, count = 0, - noffset = fdt_next_node(fit, images_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* - * Direct child node of the images parent node, - * i.e. component image node. - */ - printf("%s Image %u (%s)\n", p, count++, - fit_get_name(fit, noffset)); - - fit_image_print(fit, noffset, p); - } - } - - /* Find configurations parent node offset */ - confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); - if (confs_noffset < 0) { - debug("Can't get configurations parent node '%s' (%s)\n", - FIT_CONFS_PATH, fdt_strerror(confs_noffset)); - return; - } - - /* get default configuration unit name from default property */ - uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); - if (uname) - printf("%s Default Configuration: '%s'\n", p, uname); - - /* Process its subnodes, print out configurations details */ - for (ndepth = 0, count = 0, - noffset = fdt_next_node(fit, confs_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* - * Direct child node of the configurations parent node, - * i.e. configuration node. - */ - printf("%s Configuration %u (%s)\n", p, count++, - fit_get_name(fit, noffset)); - - fit_conf_print(fit, noffset, p); - } - } -} - -void fit_print_contents(const void *fit) -{ - fit_print(fit); -} - -void fit_image_print(const void *fit, int image_noffset, const char *p) -{ - uint8_t type, arch, os, comp = IH_COMP_NONE; - const char *desc; - size_t size; - ulong load, entry; - const void *data; - int noffset; - int ndepth; - int ret; - - if (!CONFIG_IS_ENABLED(FIT_PRINT)) - return; - - /* Mandatory properties */ - ret = fit_get_desc(fit, image_noffset, &desc); - printf("%s Description: ", p); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); - - if (IMAGE_ENABLE_TIMESTAMP) { - time_t timestamp; - - ret = fit_get_timestamp(fit, 0, ×tamp); - printf("%s Created: ", p); - if (ret) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } - - fit_image_get_type(fit, image_noffset, &type); - printf("%s Type: %s\n", p, genimg_get_type_name(type)); - - fit_image_get_comp(fit, image_noffset, &comp); - printf("%s Compression: %s\n", p, genimg_get_comp_name(comp)); - - ret = fit_image_get_data(fit, image_noffset, &data, &size); - - if (!tools_build()) { - printf("%s Data Start: ", p); - if (ret) { - printf("unavailable\n"); - } else { - void *vdata = (void *)data; - - printf("0x%08lx\n", (ulong)map_to_sysmem(vdata)); - } - } - - printf("%s Data Size: ", p); - if (ret) - printf("unavailable\n"); - else - genimg_print_size(size); - - /* Remaining, type dependent properties */ - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || - (type == IH_TYPE_FLATDT)) { - fit_image_get_arch(fit, image_noffset, &arch); - printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); - } - - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) || - (type == IH_TYPE_FIRMWARE)) { - fit_image_get_os(fit, image_noffset, &os); - printf("%s OS: %s\n", p, genimg_get_os_name(os)); - } - - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) || - (type == IH_TYPE_FPGA)) { - ret = fit_image_get_load(fit, image_noffset, &load); - printf("%s Load Address: ", p); - if (ret) - printf("unavailable\n"); - else - printf("0x%08lx\n", load); - } - - /* optional load address for FDT */ - if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load)) - printf("%s Load Address: 0x%08lx\n", p, load); - - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_RAMDISK)) { - ret = fit_image_get_entry(fit, image_noffset, &entry); - printf("%s Entry Point: ", p); - if (ret) - printf("unavailable\n"); - else - printf("0x%08lx\n", entry); - } - - /* Process all hash subnodes of the component image node */ - for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* Direct child node of the component image node */ - fit_image_print_verification_data(fit, noffset, p); - } - } -} - int fit_get_desc(const void *fit, int noffset, const char **descp) { const char *desc; diff --git a/include/image.h b/include/image.h index 2f9469e2709..17dd68e7048 100644 --- a/include/image.h +++ b/include/image.h @@ -1199,6 +1199,8 @@ int fit_parse_subimage(const char *spec, ulong addr_curr, int fit_get_subimage_count(const void *fit, int images_noffset); +#if CONFIG_IS_ENABLED(FIT_PRINT) + /** * fit_print() - prints out the contents of the FIT format image * @fit: pointer to the FIT format image header @@ -1244,6 +1246,16 @@ void fit_image_print(const void *fit, int noffset, const char *p); */ void fit_print_contents(const void *fit); +#else /* !FIT_PRINT */ + +static inline void fit_print(const void *fit) {} +static inline void fit_image_print(const void *fit, int noffset, const char *p) +{ +} +static inline void fit_print_contents(const void *fit) {} + +#endif + /** * fit_get_end - get FIT image size * @fit: pointer to the FIT format image header diff --git a/tools/Makefile b/tools/Makefile index 97ce1dbb17e..995350b5f5f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -72,6 +72,7 @@ hostprogs-y += file2include endif FIT_OBJS-y := fit_common.o fit_image.o image-host.o generated/boot/image-fit.o +FIT_OBJS-y += generated/boot/fit_print.o FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o generated/boot/image-fit-sig.o FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := generated/boot/image-cipher.o -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> This is actually not defined by the spec. The 'required' property is for use by the verifying code. Having it in the FIT does not help size an attacker could potentially remove it. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 134625396bd..bea2e176f17 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -45,7 +45,6 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p, const char *keyname, *padding, *algo; int value_len, ret, i; uint8_t *value; - bool required; debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); printf("%s %s algo: ", p, type); @@ -55,11 +54,8 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p, } printf("%s", algo); keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); - required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL); if (keyname) printf(":%s", keyname); - if (required) - printf(" (required)"); printf("\n"); padding = fdt_getprop(fit, noffset, "padding", NULL); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Create a struct fit_print_ctx to hold the FIT pointer and pass it to all printing functions instead of passing the FIT pointer directly. This provides a foundation for adding additional context in the future. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 58 +++++++++++++++++++++++++++++++---------------- boot/image-fit.c | 5 +++- include/image.h | 30 ++++++++++++++++++------ tools/fit_image.c | 5 +++- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index bea2e176f17..bb6dc140e34 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -25,8 +25,20 @@ #include <u-boot/crc.h> /** - * fit_image_print_data() - prints out the hash node details + * fit_print_init() - initialize FIT print context + * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header + * + * This initializes a fit_print_ctx structure with the given FIT image. + */ +void fit_print_init(struct fit_print_ctx *ctx, const void *fit) +{ + ctx->fit = fit; +} + +/** + * fit_image_print_data() - prints out the hash node details + * @ctx: pointer to FIT print context * @noffset: offset of the hash node * @p: pointer to prefix string * @type: Type of information to print ("hash" or "sign") @@ -39,10 +51,11 @@ * returns: * no returned results */ -static void fit_image_print_data(const void *fit, int noffset, const char *p, - const char *type) +static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, + const char *p, const char *type) { const char *keyname, *padding, *algo; + const void *fit = ctx->fit; int value_len, ret, i; uint8_t *value; @@ -88,7 +101,7 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p, /** * fit_image_print_verification_data() - prints out the hash/signature details - * @fit: pointer to the FIT format image header + * @ctx: pointer to FIT print context * @noffset: offset of the hash or signature node * @p: pointer to prefix string * @@ -97,9 +110,10 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p, * returns: * no returned results */ -static void fit_image_print_verification_data(const void *fit, int noffset, - const char *p) +static void fit_image_print_verification_data(struct fit_print_ctx *ctx, + int noffset, const char *p) { + const void *fit = ctx->fit; const char *name; /* @@ -109,13 +123,14 @@ static void fit_image_print_verification_data(const void *fit, int noffset, */ name = fit_get_name(fit, noffset); if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) - fit_image_print_data(fit, noffset, p, "Hash"); + fit_image_print_data(ctx, noffset, p, "Hash"); else if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) - fit_image_print_data(fit, noffset, p, "Sign"); + fit_image_print_data(ctx, noffset, p, "Sign"); } -void fit_image_print(const void *fit, int image_noffset, const char *p) +void fit_image_print(struct fit_print_ctx *ctx, int image_noffset, const char *p) { + const void *fit = ctx->fit; uint8_t type, arch, os, comp = IH_COMP_NONE; const char *desc; size_t size; @@ -125,9 +140,6 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) int ndepth; int ret; - if (!CONFIG_IS_ENABLED(FIT_PRINT)) - return; - /* Mandatory properties */ ret = fit_get_desc(fit, image_noffset, &desc); printf("%s Description: ", p); @@ -218,14 +230,14 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* Direct child node of the component image node */ - fit_image_print_verification_data(fit, noffset, p); + fit_image_print_verification_data(ctx, noffset, p); } } } /** * fit_conf_print - prints out the FIT configuration details - * @fit: pointer to the FIT format image header + * @ctx: pointer to FIT print context * @noffset: offset of the configuration node * @p: pointer to prefix string * @@ -235,8 +247,10 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) * returns: * no returned results */ -static void fit_conf_print(const void *fit, int noffset, const char *p) +static void fit_conf_print(struct fit_print_ctx *ctx, int noffset, + const char *p) { + const void *fit = ctx->fit; const char *uname, *desc; int ret, ndepth, i; @@ -307,13 +321,14 @@ static void fit_conf_print(const void *fit, int noffset, const char *p) noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* Direct child node of the component config node */ - fit_image_print_verification_data(fit, noffset, p); + fit_image_print_verification_data(ctx, noffset, p); } } } -void fit_print(const void *fit) +void fit_print(struct fit_print_ctx *ctx) { + const void *fit = ctx->fit; const char *desc; char *uname; int images_noffset; @@ -366,7 +381,7 @@ void fit_print(const void *fit) printf("%s Image %u (%s)\n", p, count++, fit_get_name(fit, noffset)); - fit_image_print(fit, noffset, p); + fit_image_print(ctx, noffset, p); } } @@ -396,12 +411,15 @@ void fit_print(const void *fit) printf("%s Configuration %u (%s)\n", p, count++, fit_get_name(fit, noffset)); - fit_conf_print(fit, noffset, p); + fit_conf_print(ctx, noffset, p); } } } void fit_print_contents(const void *fit) { - fit_print(fit); + struct fit_print_ctx ctx; + + fit_print_init(&ctx, fit); + fit_print(&ctx); } diff --git a/boot/image-fit.c b/boot/image-fit.c index 5eef9479781..ed77a5e09c5 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1555,7 +1555,10 @@ int fit_get_data_conf_prop(const void *fit, const char *prop_name, static int print_and_verify(const void *fit, int rd_noffset, int verify) { - fit_image_print(fit, rd_noffset, " "); + struct fit_print_ctx ctx; + + fit_print_init(&ctx, fit); + fit_image_print(&ctx, rd_noffset, " "); if (verify) { puts(" Verifying Hash Integrity ... "); diff --git a/include/image.h b/include/image.h index 17dd68e7048..9b5a1815df9 100644 --- a/include/image.h +++ b/include/image.h @@ -1199,26 +1199,41 @@ int fit_parse_subimage(const char *spec, ulong addr_curr, int fit_get_subimage_count(const void *fit, int images_noffset); +/** + * struct fit_print_ctx - context for FIT printing + * @fit: pointer to the FIT format image header + */ +struct fit_print_ctx { + const void *fit; +}; + #if CONFIG_IS_ENABLED(FIT_PRINT) /** - * fit_print() - prints out the contents of the FIT format image + * fit_print_init() - initialize FIT print context + * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header - * @p: pointer to prefix string * - * This formats a multi line FIT image contents description. + * This inits a fit_print_ctx structure with the given FIT image. + */ +void fit_print_init(struct fit_print_ctx *ctx, const void *fit); + +/** + * fit_print() - prints out the contents of the FIT format image + * @ctx: pointer to FIT print context + * * The routine prints out FIT image properties (root node level) followed by * the details of each component image. * * returns: * no returned results */ -void fit_print(const void *fit); +void fit_print(struct fit_print_ctx *ctx); /** * fit_image_print - prints out the FIT component image details - * @fit: pointer to the FIT format image header - * @image_noffset: offset of the component image node + * @ctx: pointer to FIT print context + * @noffset: offset of the component image node * @p: pointer to prefix string * * fit_image_print() lists all mandatory properties for the processed component @@ -1230,7 +1245,7 @@ void fit_print(const void *fit); * returns: * no returned results */ -void fit_image_print(const void *fit, int noffset, const char *p); +void fit_image_print(struct fit_print_ctx *ctx, int noffset, const char *p); /** * fit_print_contents() - prints out the contents of the FIT format image @@ -1248,6 +1263,7 @@ void fit_print_contents(const void *fit); #else /* !FIT_PRINT */ +static inline void fit_print_init(struct fit_print_ctx *ctx, const void *fit) {} static inline void fit_print(const void *fit) {} static inline void fit_image_print(const void *fit, int noffset, const char *p) { diff --git a/tools/fit_image.c b/tools/fit_image.c index 80f9020d29d..017a2d212e9 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -971,10 +971,13 @@ static int fit_extract_contents(void *ptr, struct imgtool *itl) * i.e. component image node. */ if (itl->pflag == count) { + struct fit_print_ctx ctx; + printf("Extracted:\n%s Image %u (%s)\n", p, count, fit_get_name(fit, noffset)); - fit_image_print(fit, noffset, p); + fit_print_init(&ctx, fit); + fit_image_print(&ctx, noffset, p); return fit_image_extract(fit, noffset, itl->outfile); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the indent string into struct fit_print_ctx so it is available to the printing functions. This avoids having to pass it as a separate parameter. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 54 +++++++++++++++++++++++++++++------------------ boot/image-fit.c | 4 ++-- include/image.h | 18 ++++++++++------ tools/fit_image.c | 4 ++-- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index bb6dc140e34..07454dcf5cf 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -28,19 +28,21 @@ * fit_print_init() - initialize FIT print context * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header + * @indent: indentation string for printing * * This initializes a fit_print_ctx structure with the given FIT image. */ -void fit_print_init(struct fit_print_ctx *ctx, const void *fit) +void fit_print_init(struct fit_print_ctx *ctx, const void *fit, + const char *indent) { ctx->fit = fit; + ctx->indent = indent; } /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context * @noffset: offset of the hash node - * @p: pointer to prefix string * @type: Type of information to print ("hash" or "sign") * * fit_image_print_data() lists properties for the processed hash node @@ -52,9 +54,10 @@ void fit_print_init(struct fit_print_ctx *ctx, const void *fit) * no returned results */ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, - const char *p, const char *type) + const char *type) { const char *keyname, *padding, *algo; + const char *p = ctx->indent; const void *fit = ctx->fit; int value_len, ret, i; uint8_t *value; @@ -103,7 +106,6 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, * fit_image_print_verification_data() - prints out the hash/signature details * @ctx: pointer to FIT print context * @noffset: offset of the hash or signature node - * @p: pointer to prefix string * * This lists properties for the processed hash node * @@ -111,7 +113,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, * no returned results */ static void fit_image_print_verification_data(struct fit_print_ctx *ctx, - int noffset, const char *p) + int noffset) { const void *fit = ctx->fit; const char *name; @@ -123,14 +125,30 @@ static void fit_image_print_verification_data(struct fit_print_ctx *ctx, */ name = fit_get_name(fit, noffset); if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) - fit_image_print_data(ctx, noffset, p, "Hash"); + fit_image_print_data(ctx, noffset, "Hash"); else if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) - fit_image_print_data(ctx, noffset, p, "Sign"); + fit_image_print_data(ctx, noffset, "Sign"); } -void fit_image_print(struct fit_print_ctx *ctx, int image_noffset, const char *p) +/** + * fit_image_print - prints out the FIT component image details + * @ctx: pointer to FIT print context + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properties for the processed component + * image. If present, hash nodes are printed out as well. Load + * address for images of type firmware is also printed out. Since the load + * address is not mandatory for firmware images, it will be output as + * "unavailable" when not present. + * + * returns: + * no returned results + */ +void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) { const void *fit = ctx->fit; + const char *p = ctx->indent; uint8_t type, arch, os, comp = IH_COMP_NONE; const char *desc; size_t size; @@ -230,7 +248,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset, const char *p noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* Direct child node of the component image node */ - fit_image_print_verification_data(ctx, noffset, p); + fit_image_print_verification_data(ctx, noffset); } } } @@ -239,7 +257,6 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset, const char *p * fit_conf_print - prints out the FIT configuration details * @ctx: pointer to FIT print context * @noffset: offset of the configuration node - * @p: pointer to prefix string * * fit_conf_print() lists all mandatory properties for the processed * configuration node. @@ -247,10 +264,10 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset, const char *p * returns: * no returned results */ -static void fit_conf_print(struct fit_print_ctx *ctx, int noffset, - const char *p) +static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; + const char *p = ctx->indent; const char *uname, *desc; int ret, ndepth, i; @@ -321,7 +338,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset, noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* Direct child node of the component config node */ - fit_image_print_verification_data(ctx, noffset, p); + fit_image_print_verification_data(ctx, noffset); } } } @@ -329,6 +346,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset, void fit_print(struct fit_print_ctx *ctx) { const void *fit = ctx->fit; + const char *p = ctx->indent; const char *desc; char *uname; int images_noffset; @@ -337,12 +355,8 @@ void fit_print(struct fit_print_ctx *ctx) int ndepth; int count = 0; int ret; - const char *p; time_t timestamp; - /* Indent string is defined in header image.h */ - p = IMAGE_INDENT_STRING; - /* Root node properties */ ret = fit_get_desc(fit, 0, &desc); printf("%sFIT description: ", p); @@ -381,7 +395,7 @@ void fit_print(struct fit_print_ctx *ctx) printf("%s Image %u (%s)\n", p, count++, fit_get_name(fit, noffset)); - fit_image_print(ctx, noffset, p); + fit_image_print(ctx, noffset); } } @@ -411,7 +425,7 @@ void fit_print(struct fit_print_ctx *ctx) printf("%s Configuration %u (%s)\n", p, count++, fit_get_name(fit, noffset)); - fit_conf_print(ctx, noffset, p); + fit_conf_print(ctx, noffset); } } } @@ -420,6 +434,6 @@ void fit_print_contents(const void *fit) { struct fit_print_ctx ctx; - fit_print_init(&ctx, fit); + fit_print_init(&ctx, fit, IMAGE_INDENT_STRING); fit_print(&ctx); } diff --git a/boot/image-fit.c b/boot/image-fit.c index ed77a5e09c5..bb8a96fe39e 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1557,8 +1557,8 @@ static int print_and_verify(const void *fit, int rd_noffset, int verify) { struct fit_print_ctx ctx; - fit_print_init(&ctx, fit); - fit_image_print(&ctx, rd_noffset, " "); + fit_print_init(&ctx, fit, " "); + fit_image_print(&ctx, rd_noffset); if (verify) { puts(" Verifying Hash Integrity ... "); diff --git a/include/image.h b/include/image.h index 9b5a1815df9..7a5ad29a3ec 100644 --- a/include/image.h +++ b/include/image.h @@ -1202,9 +1202,11 @@ int fit_get_subimage_count(const void *fit, int images_noffset); /** * struct fit_print_ctx - context for FIT printing * @fit: pointer to the FIT format image header + * @indent: indentation string for printing */ struct fit_print_ctx { const void *fit; + const char *indent; }; #if CONFIG_IS_ENABLED(FIT_PRINT) @@ -1213,10 +1215,12 @@ struct fit_print_ctx { * fit_print_init() - initialize FIT print context * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header + * @indent: indentation string for printing * * This inits a fit_print_ctx structure with the given FIT image. */ -void fit_print_init(struct fit_print_ctx *ctx, const void *fit); +void fit_print_init(struct fit_print_ctx *ctx, const void *fit, + const char *indent); /** * fit_print() - prints out the contents of the FIT format image @@ -1231,10 +1235,9 @@ void fit_print_init(struct fit_print_ctx *ctx, const void *fit); void fit_print(struct fit_print_ctx *ctx); /** - * fit_image_print - prints out the FIT component image details + * fit_image_print() - prints out the FIT component image details * @ctx: pointer to FIT print context * @noffset: offset of the component image node - * @p: pointer to prefix string * * fit_image_print() lists all mandatory properties for the processed component * image. If present, hash nodes are printed out as well. Load @@ -1245,7 +1248,7 @@ void fit_print(struct fit_print_ctx *ctx); * returns: * no returned results */ -void fit_image_print(struct fit_print_ctx *ctx, int noffset, const char *p); +void fit_image_print(struct fit_print_ctx *ctx, int noffset); /** * fit_print_contents() - prints out the contents of the FIT format image @@ -1263,11 +1266,12 @@ void fit_print_contents(const void *fit); #else /* !FIT_PRINT */ -static inline void fit_print_init(struct fit_print_ctx *ctx, const void *fit) {} -static inline void fit_print(const void *fit) {} -static inline void fit_image_print(const void *fit, int noffset, const char *p) +static inline void fit_print_init(struct fit_print_ctx *ctx, const void *fit, + const char *indent) { } +static inline void fit_print(const void *fit) {} +static inline void fit_image_print(const void *fit, int noffset) {} static inline void fit_print_contents(const void *fit) {} #endif diff --git a/tools/fit_image.c b/tools/fit_image.c index 017a2d212e9..10815e8f4d3 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -976,8 +976,8 @@ static int fit_extract_contents(void *ptr, struct imgtool *itl) printf("Extracted:\n%s Image %u (%s)\n", p, count, fit_get_name(fit, noffset)); - fit_print_init(&ctx, fit); - fit_image_print(&ctx, noffset, p); + fit_print_init(&ctx, fit, p); + fit_image_print(&ctx, noffset); return fit_image_extract(fit, noffset, itl->outfile); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The current code is quite fiddly with manually spaced labels. Add helper functions for printing labels (with or without a type prefix) with a cofigurable tab width for the value that folows. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 42 +++++++++++++++++++++++++++++++++++++++--- include/image.h | 2 ++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 07454dcf5cf..b87526023b4 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -37,6 +37,42 @@ void fit_print_init(struct fit_print_ctx *ctx, const void *fit, { ctx->fit = fit; ctx->indent = indent; + ctx->tab = 16 + strlen(indent); +} + +/** + * emit_type() - print a label with indentation and padding + * @ctx: pointer to FIT print context + * @type: type prefix (e.g., "Hash" or "Sign") + * @label: label suffix (e.g., "algo" or "value") + * + * Prints the indentation from the context, followed by two spaces, the type, + * a space, the label, a colon, and padding to align values to ctx->tab. + */ +static void emit_type(struct fit_print_ctx *ctx, const char *type, + const char *label) +{ + int len; + + len = printf("%s %s %s:", ctx->indent, type, label); + printf("%*s", ctx->tab - len, ""); +} + +/** + * emit_label() - print a label with indentation and padding + * @ctx: pointer to FIT print context + * @type: type prefix (e.g., "Hash" or "Sign") + * @label: label suffix (e.g., "algo" or "value") + * + * Prints the indentation from the context, followed by two spaces, a space, + * the label, a colon, and padding to align values to ctx->tab. + */ +static void emit_label(struct fit_print_ctx *ctx, const char *label) +{ + int len; + + len = printf("%s %s:", ctx->indent, label); + printf("%*s", ctx->tab - len, ""); } /** @@ -63,7 +99,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, uint8_t *value; debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); - printf("%s %s algo: ", p, type); + emit_type(ctx, type, "algo"); if (fit_image_hash_get_algo(fit, noffset, &algo)) { printf("invalid/unsupported\n"); return; @@ -79,7 +115,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, printf("%s %s padding: %s\n", p, type, padding); ret = fit_image_hash_get_value(fit, noffset, &value, &value_len); - printf("%s %s value: ", p, type); + emit_type(ctx, type, "value"); if (ret) { printf("unavailable\n"); } else { @@ -94,7 +130,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, if (IMAGE_ENABLE_TIMESTAMP && keyname) { time_t timestamp; - printf("%s Timestamp: ", p); + emit_label(ctx, "Timestamp"); if (fit_get_timestamp(fit, noffset, ×tamp)) printf("unavailable\n"); else diff --git a/include/image.h b/include/image.h index 7a5ad29a3ec..d5c3cc03de5 100644 --- a/include/image.h +++ b/include/image.h @@ -1203,10 +1203,12 @@ int fit_get_subimage_count(const void *fit, int images_noffset); * struct fit_print_ctx - context for FIT printing * @fit: pointer to the FIT format image header * @indent: indentation string for printing + * @tab: amount of space to tab out for the label */ struct fit_print_ctx { const void *fit; const char *indent; + int tab; }; #if CONFIG_IS_ENABLED(FIT_PRINT) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update fit_image_print() to use the emit_label() helper function for printing labels. This avoids various manual printf() calls and spacing logic. Set ctx->tab to 19 to align values at the correct column position. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index b87526023b4..69139c46931 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -184,7 +184,6 @@ static void fit_image_print_verification_data(struct fit_print_ctx *ctx, void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) { const void *fit = ctx->fit; - const char *p = ctx->indent; uint8_t type, arch, os, comp = IH_COMP_NONE; const char *desc; size_t size; @@ -196,7 +195,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) /* Mandatory properties */ ret = fit_get_desc(fit, image_noffset, &desc); - printf("%s Description: ", p); + emit_label(ctx, "Description"); if (ret) printf("unavailable\n"); else @@ -206,7 +205,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) time_t timestamp; ret = fit_get_timestamp(fit, 0, ×tamp); - printf("%s Created: ", p); + emit_label(ctx, "Created"); if (ret) printf("unavailable\n"); else @@ -214,15 +213,17 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) } fit_image_get_type(fit, image_noffset, &type); - printf("%s Type: %s\n", p, genimg_get_type_name(type)); + emit_label(ctx, "Type"); + printf("%s\n", genimg_get_type_name(type)); fit_image_get_comp(fit, image_noffset, &comp); - printf("%s Compression: %s\n", p, genimg_get_comp_name(comp)); + emit_label(ctx, "Compression"); + printf("%s\n", genimg_get_comp_name(comp)); ret = fit_image_get_data(fit, image_noffset, &data, &size); if (!tools_build()) { - printf("%s Data Start: ", p); + emit_label(ctx, "Data Start"); if (ret) { printf("unavailable\n"); } else { @@ -232,7 +233,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) } } - printf("%s Data Size: ", p); + emit_label(ctx, "Data Size"); if (ret) printf("unavailable\n"); else @@ -243,20 +244,22 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE || type == IH_TYPE_FLATDT) { fit_image_get_arch(fit, image_noffset, &arch); - printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); + emit_label(ctx, "Architecture"); + printf("%s\n", genimg_get_arch_name(arch)); } if (type == IH_TYPE_KERNEL || type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE) { fit_image_get_os(fit, image_noffset, &os); - printf("%s OS: %s\n", p, genimg_get_os_name(os)); + emit_label(ctx, "OS"); + printf("%s\n", genimg_get_os_name(os)); } if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || type == IH_TYPE_FIRMWARE || type == IH_TYPE_RAMDISK || type == IH_TYPE_FPGA) { ret = fit_image_get_load(fit, image_noffset, &load); - printf("%s Load Address: ", p); + emit_label(ctx, "Load Address"); if (ret) printf("unavailable\n"); else @@ -265,13 +268,15 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) /* optional load address for FDT */ if (type == IH_TYPE_FLATDT && - !fit_image_get_load(fit, image_noffset, &load)) - printf("%s Load Address: 0x%08lx\n", p, load); + !fit_image_get_load(fit, image_noffset, &load)) { + emit_label(ctx, "Load Address"); + printf("0x%08lx\n", load); + } if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || type == IH_TYPE_RAMDISK) { ret = fit_image_get_entry(fit, image_noffset, &entry); - printf("%s Entry Point: ", p); + emit_label(ctx, "Entry Point"); if (ret) printf("unavailable\n"); else -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update fit_conf_print() to use the emit_label() helper function for printing labels. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 69139c46931..97dab4b2490 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -312,16 +312,18 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) const char *uname, *desc; int ret, ndepth, i; + ctx->tab = 19; + /* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc); - printf("%s Description: ", p); + emit_label(ctx, "Description"); if (ret) printf("unavailable\n"); else printf("%s\n", desc); uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); - printf("%s Kernel: ", p); + emit_label(ctx, "Kernel"); if (!uname) printf("unavailable\n"); else @@ -329,27 +331,33 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) /* Optional properties */ uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); - if (uname) - printf("%s Init Ramdisk: %s\n", p, uname); + if (uname) { + emit_label(ctx, "Init Ramdisk"); + printf("%s\n", uname); + } uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL); - if (uname) - printf("%s Firmware: %s\n", p, uname); + if (uname) { + emit_label(ctx, "Firmware"); + printf("%s\n", uname); + } for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, i, NULL), uname; i++) { if (!i) - printf("%s FDT: ", p); + emit_label(ctx, "FDT"); else printf("%s ", p); printf("%s\n", uname); } uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); - if (uname) - printf("%s FPGA: %s\n", p, uname); + if (uname) { + emit_label(ctx, "FPGA"); + printf("%s\n", uname); + } /* Print out all of the specified loadables */ for (i = 0; @@ -357,7 +365,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) i, NULL), uname; i++) { if (!i) - printf("%s Loadables: ", p); + emit_label(ctx, "Loadables"); else printf("%s ", p); printf("%s\n", uname); @@ -367,7 +375,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_COMPATIBLE_PROP, i, NULL), uname; i++) { if (!i) - printf("%s Compatible: ", p); + emit_label(ctx, "Compatible"); else printf("%s ", p); printf("%s\n", uname); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a new emit_label_val() helper function that combines emit_label() and printf() for simple label-value pairs. Make use of it where appropriate. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 65 ++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 97dab4b2490..3ff53fceded 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -75,6 +75,23 @@ static void emit_label(struct fit_print_ctx *ctx, const char *label) printf("%*s", ctx->tab - len, ""); } +/** + * emit_label_val() - print a label with value + * @ctx: pointer to FIT print context + * @label: label string (e.g., "Type" or "OS") + * @val: value string to print after the label + * + * Prints the indentation, label with padding to ctx->tab, and the value + * followed by a newline. This is a convenience function that combines + * emit_label() and printf() for simple label-value pairs. + */ +static void emit_label_val(struct fit_print_ctx *ctx, const char *label, + const char *val) +{ + emit_label(ctx, label); + printf("%s\n", val); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -195,11 +212,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) /* Mandatory properties */ ret = fit_get_desc(fit, image_noffset, &desc); - emit_label(ctx, "Description"); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); + emit_label_val(ctx, "Description", ret ? "unavailable" : desc); if (IMAGE_ENABLE_TIMESTAMP) { time_t timestamp; @@ -213,12 +226,10 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) } fit_image_get_type(fit, image_noffset, &type); - emit_label(ctx, "Type"); - printf("%s\n", genimg_get_type_name(type)); + emit_label_val(ctx, "Type", genimg_get_type_name(type)); fit_image_get_comp(fit, image_noffset, &comp); - emit_label(ctx, "Compression"); - printf("%s\n", genimg_get_comp_name(comp)); + emit_label_val(ctx, "Compression", genimg_get_comp_name(comp)); ret = fit_image_get_data(fit, image_noffset, &data, &size); @@ -244,15 +255,13 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE || type == IH_TYPE_FLATDT) { fit_image_get_arch(fit, image_noffset, &arch); - emit_label(ctx, "Architecture"); - printf("%s\n", genimg_get_arch_name(arch)); + emit_label_val(ctx, "Architecture", genimg_get_arch_name(arch)); } if (type == IH_TYPE_KERNEL || type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE) { fit_image_get_os(fit, image_noffset, &os); - emit_label(ctx, "OS"); - printf("%s\n", genimg_get_os_name(os)); + emit_label_val(ctx, "OS", genimg_get_os_name(os)); } if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || @@ -316,31 +325,19 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) /* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc); - emit_label(ctx, "Description"); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); + emit_label_val(ctx, "Description", ret ? "unavailable" : desc); uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); - emit_label(ctx, "Kernel"); - if (!uname) - printf("unavailable\n"); - else - printf("%s\n", uname); + emit_label_val(ctx, "Kernel", uname ?: "unavailable"); /* Optional properties */ uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); - if (uname) { - emit_label(ctx, "Init Ramdisk"); - printf("%s\n", uname); - } + if (uname) + emit_label_val(ctx, "Init Ramdisk", uname); uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL); - if (uname) { - emit_label(ctx, "Firmware"); - printf("%s\n", uname); - } + if (uname) + emit_label_val(ctx, "Firmware", uname); for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, @@ -354,10 +351,8 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) } uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); - if (uname) { - emit_label(ctx, "FPGA"); - printf("%s\n", uname); - } + if (uname) + emit_label_val(ctx, "FPGA", uname); /* Print out all of the specified loadables */ for (i = 0; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Change the indent field in fit_print_ctx from a string pointer to an int number of spaces to indent. Set the initial indent value to 3 to match IMAGE_INDENT_STRING Drop indentation from the debug() calls since these are not visible to users. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 47 +++++++++++++++++++++++------------------------ boot/image-fit.c | 2 +- include/image.h | 13 ++++++------- tools/fit_image.c | 10 +++++----- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 3ff53fceded..a361ec21b5e 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -28,16 +28,14 @@ * fit_print_init() - initialize FIT print context * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header - * @indent: indentation string for printing * * This initializes a fit_print_ctx structure with the given FIT image. */ -void fit_print_init(struct fit_print_ctx *ctx, const void *fit, - const char *indent) +void fit_print_init(struct fit_print_ctx *ctx, const void *fit) { ctx->fit = fit; - ctx->indent = indent; - ctx->tab = 16 + strlen(indent); + ctx->indent = IMAGE_INDENT; + ctx->tab = 16 + IMAGE_INDENT; } /** @@ -54,7 +52,7 @@ static void emit_type(struct fit_print_ctx *ctx, const char *type, { int len; - len = printf("%s %s %s:", ctx->indent, type, label); + len = printf("%*s%s %s:", ctx->indent, "", type, label); printf("%*s", ctx->tab - len, ""); } @@ -71,7 +69,7 @@ static void emit_label(struct fit_print_ctx *ctx, const char *label) { int len; - len = printf("%s %s:", ctx->indent, label); + len = printf("%*s%s:", ctx->indent, "", label); printf("%*s", ctx->tab - len, ""); } @@ -110,12 +108,11 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, const char *type) { const char *keyname, *padding, *algo; - const char *p = ctx->indent; + int p = ctx->indent; const void *fit = ctx->fit; int value_len, ret, i; uint8_t *value; - debug("%s %s node: '%s'\n", p, type, fit_get_name(fit, noffset)); emit_type(ctx, type, "algo"); if (fit_image_hash_get_algo(fit, noffset, &algo)) { printf("invalid/unsupported\n"); @@ -129,7 +126,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, padding = fdt_getprop(fit, noffset, "padding", NULL); if (padding) - printf("%s %s padding: %s\n", p, type, padding); + printf("%*s%s padding: %s\n", p, "", type, padding); ret = fit_image_hash_get_value(fit, noffset, &value, &value_len); emit_type(ctx, type, "value"); @@ -141,7 +138,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, printf("\n"); } - debug("%s %s len: %d\n", p, type, value_len); + debug("%s len: %d\n", type, value_len); /* Signatures have a time stamp */ if (IMAGE_ENABLE_TIMESTAMP && keyname) { @@ -317,12 +314,10 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; - const char *p = ctx->indent; + int p = ctx->indent; const char *uname, *desc; int ret, ndepth, i; - ctx->tab = 19; - /* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc); emit_label_val(ctx, "Description", ret ? "unavailable" : desc); @@ -346,7 +341,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "FDT"); else - printf("%s ", p); + printf("%*s ", p, ""); printf("%s\n", uname); } @@ -362,7 +357,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "Loadables"); else - printf("%s ", p); + printf("%*s ", p, ""); printf("%s\n", uname); } @@ -372,7 +367,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "Compatible"); else - printf("%s ", p); + printf("%*s ", p, ""); printf("%s\n", uname); } @@ -390,7 +385,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) void fit_print(struct fit_print_ctx *ctx) { const void *fit = ctx->fit; - const char *p = ctx->indent; + int p = ctx->indent; const char *desc; char *uname; int images_noffset; @@ -403,7 +398,7 @@ void fit_print(struct fit_print_ctx *ctx) /* Root node properties */ ret = fit_get_desc(fit, 0, &desc); - printf("%sFIT description: ", p); + printf("%*sFIT description: ", p, ""); if (ret) printf("unavailable\n"); else @@ -411,7 +406,7 @@ void fit_print(struct fit_print_ctx *ctx) if (IMAGE_ENABLE_TIMESTAMP) { ret = fit_get_timestamp(fit, 0, ×tamp); - printf("%sCreated: ", p); + printf("%*sCreated: ", p, ""); if (ret) printf("unavailable\n"); else @@ -436,10 +431,12 @@ void fit_print(struct fit_print_ctx *ctx) * Direct child node of the images parent node, * i.e. component image node. */ - printf("%s Image %u (%s)\n", p, count++, + printf("%*s Image %u (%s)\n", p, "", count++, fit_get_name(fit, noffset)); + ctx->indent += 2; fit_image_print(ctx, noffset); + ctx->indent -= 2; } } @@ -454,7 +451,7 @@ void fit_print(struct fit_print_ctx *ctx) /* get default configuration unit name from default property */ uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); if (uname) - printf("%s Default Configuration: '%s'\n", p, uname); + printf("%*s Default Configuration: '%s'\n", p, "", uname); /* Process its subnodes, print out configurations details */ for (ndepth = 0, count = 0, @@ -466,10 +463,12 @@ void fit_print(struct fit_print_ctx *ctx) * Direct child node of the configurations parent node, * i.e. configuration node. */ - printf("%s Configuration %u (%s)\n", p, count++, + printf("%*s Configuration %u (%s)\n", p, "", count++, fit_get_name(fit, noffset)); + ctx->indent += 2; fit_conf_print(ctx, noffset); + ctx->indent -= 2; } } } @@ -478,6 +477,6 @@ void fit_print_contents(const void *fit) { struct fit_print_ctx ctx; - fit_print_init(&ctx, fit, IMAGE_INDENT_STRING); + fit_print_init(&ctx, fit); fit_print(&ctx); } diff --git a/boot/image-fit.c b/boot/image-fit.c index bb8a96fe39e..defe45b1df0 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1557,7 +1557,7 @@ static int print_and_verify(const void *fit, int rd_noffset, int verify) { struct fit_print_ctx ctx; - fit_print_init(&ctx, fit, " "); + fit_print_init(&ctx, fit); fit_image_print(&ctx, rd_noffset); if (verify) { diff --git a/include/image.h b/include/image.h index d5c3cc03de5..476f35128f4 100644 --- a/include/image.h +++ b/include/image.h @@ -26,6 +26,7 @@ struct fdt_region; #include <sys/types.h> #include <linux/kconfig.h> +#define IMAGE_INDENT 0 #define IMAGE_INDENT_STRING "" #define BIT(nr) (1UL << (nr)) @@ -37,6 +38,7 @@ struct fdt_region; #include <linker_lists.h> #include <linux/bitops.h> +#define IMAGE_INDENT 3 #define IMAGE_INDENT_STRING " " #endif /* USE_HOSTCC */ @@ -1202,12 +1204,12 @@ int fit_get_subimage_count(const void *fit, int images_noffset); /** * struct fit_print_ctx - context for FIT printing * @fit: pointer to the FIT format image header - * @indent: indentation string for printing + * @indent: indentation level for printing * @tab: amount of space to tab out for the label */ struct fit_print_ctx { const void *fit; - const char *indent; + int indent; int tab; }; @@ -1217,12 +1219,10 @@ struct fit_print_ctx { * fit_print_init() - initialize FIT print context * @ctx: pointer to FIT print context to initialize * @fit: pointer to the FIT format image header - * @indent: indentation string for printing * * This inits a fit_print_ctx structure with the given FIT image. */ -void fit_print_init(struct fit_print_ctx *ctx, const void *fit, - const char *indent); +void fit_print_init(struct fit_print_ctx *ctx, const void *fit); /** * fit_print() - prints out the contents of the FIT format image @@ -1268,8 +1268,7 @@ void fit_print_contents(const void *fit); #else /* !FIT_PRINT */ -static inline void fit_print_init(struct fit_print_ctx *ctx, const void *fit, - const char *indent) +static inline void fit_print_init(struct fit_print_ctx *ctx, const void *fit) { } static inline void fit_print(const void *fit) {} diff --git a/tools/fit_image.c b/tools/fit_image.c index 10815e8f4d3..2e08b68d479 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -940,10 +940,10 @@ static int fit_extract_contents(void *ptr, struct imgtool *itl) int ndepth; const void *fit = ptr; int count = 0; - const char *p; + int p; - /* Indent string is defined in header image.h */ - p = IMAGE_INDENT_STRING; + /* Indent value is defined in header image.h */ + p = 5; /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); @@ -973,10 +973,10 @@ static int fit_extract_contents(void *ptr, struct imgtool *itl) if (itl->pflag == count) { struct fit_print_ctx ctx; - printf("Extracted:\n%s Image %u (%s)\n", p, + printf("Extracted:\n%*s Image %u (%s)\n", p, "", count, fit_get_name(fit, noffset)); - fit_print_init(&ctx, fit, p); + fit_print_init(&ctx, fit); fit_image_print(&ctx, noffset); return fit_image_extract(fit, noffset, -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Line up the values witht the FIT Description and Created items at the top. This looks a little nicer. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 11 +- test/boot/fit_print.c | 202 ++++++++++++++++---------------- test/py/tests/test_fit_print.py | 186 ++++++++++++++--------------- 3 files changed, 200 insertions(+), 199 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index a361ec21b5e..e26f2294229 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -35,7 +35,7 @@ void fit_print_init(struct fit_print_ctx *ctx, const void *fit) { ctx->fit = fit; ctx->indent = IMAGE_INDENT; - ctx->tab = 16 + IMAGE_INDENT; + ctx->tab = 17 + IMAGE_INDENT; } /** @@ -113,6 +113,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, int value_len, ret, i; uint8_t *value; + debug("%s node: '%s'\n", type, fit_get_name(fit, noffset)); emit_type(ctx, type, "algo"); if (fit_image_hash_get_algo(fit, noffset, &algo)) { printf("invalid/unsupported\n"); @@ -126,7 +127,7 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, padding = fdt_getprop(fit, noffset, "padding", NULL); if (padding) - printf("%*s%s padding: %s\n", p, "", type, padding); + printf("%*s%s padding: %s\n", p, "", type, padding); ret = fit_image_hash_get_value(fit, noffset, &value, &value_len); emit_type(ctx, type, "value"); @@ -341,7 +342,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "FDT"); else - printf("%*s ", p, ""); + printf("%*s ", p, ""); printf("%s\n", uname); } @@ -357,7 +358,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "Loadables"); else - printf("%*s ", p, ""); + printf("%*s ", p, ""); printf("%s\n", uname); } @@ -367,7 +368,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) if (!i) emit_label(ctx, "Compatible"); else - printf("%*s ", p, ""); + printf("%*s ", p, ""); printf("%s\n", uname); } diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c index 8e8d81e7f6b..3b105045667 100644 --- a/test/boot/fit_print.c +++ b/test/boot/fit_print.c @@ -39,118 +39,118 @@ static int test_fit_print_norun(struct unit_test_state *uts) ut_assert_nextline(" FIT description: Test FIT image for printing"); ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Image 0 (kernel)"); - ut_assert_nextline(" Description: Test kernel"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Kernel Image"); - ut_assert_nextline(" Compression: gzip compressed"); - ut_assert_nextline(" Data Start: 0x000100c4"); - ut_assert_nextline(" Data Size: 327 Bytes = 327 Bytes"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" OS: Linux"); - ut_assert_nextline(" Load Address: 0x01000000"); - ut_assert_nextline(" Entry Point: 0x01000000"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee"); + ut_assert_nextline(" Description: Test kernel"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Kernel Image"); + ut_assert_nextline(" Compression: gzip compressed"); + ut_assert_nextline(" Data Start: 0x000100c4"); + ut_assert_nextline(" Data Size: 327 Bytes = 327 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x01000000"); + ut_assert_nextline(" Entry Point: 0x01000000"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee"); ut_assert_nextline(" Image 1 (ramdisk)"); - ut_assert_nextline(" Description: Test ramdisk"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: RAMDisk Image"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x00010304"); - ut_assert_nextline(" Data Size: 301 Bytes = 301 Bytes"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" OS: Linux"); - ut_assert_nextline(" Load Address: 0x02000000"); - ut_assert_nextline(" Entry Point: unavailable"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655"); + ut_assert_nextline(" Description: Test ramdisk"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: RAMDisk Image"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010304"); + ut_assert_nextline(" Data Size: 301 Bytes = 301 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x02000000"); + ut_assert_nextline(" Entry Point: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655"); ut_assert_nextline(" Image 2 (fdt-1)"); - ut_assert_nextline(" Description: Test FDT 1"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Flat Device Tree"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x00010518"); - ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb"); + ut_assert_nextline(" Description: Test FDT 1"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Flat Device Tree"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010518"); + ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb"); ut_assert_nextline(" Image 3 (fdt-2)"); - ut_assert_nextline(" Description: Test FDT 2"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Flat Device Tree"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x0001067c"); - ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4"); + ut_assert_nextline(" Description: Test FDT 2"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Flat Device Tree"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x0001067c"); + ut_assert_nextline(" Data Size: 161 Bytes = 161 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4"); ut_assert_nextline(" Image 4 (firmware-1)"); - ut_assert_nextline(" Description: Test Firmware 1"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Firmware"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x000107e8"); - ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" OS: Unknown OS"); - ut_assert_nextline(" Load Address: unavailable"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414"); + ut_assert_nextline(" Description: Test Firmware 1"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Firmware"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000107e8"); + ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Unknown OS"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414"); ut_assert_nextline(" Image 5 (firmware-2)"); - ut_assert_nextline(" Description: Test Firmware 2"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Firmware"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x000117e8"); - ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); - ut_assert_nextline(" Architecture: Sandbox"); - ut_assert_nextline(" OS: Unknown OS"); - ut_assert_nextline(" Load Address: unavailable"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1"); + ut_assert_nextline(" Description: Test Firmware 2"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Firmware"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000117e8"); + ut_assert_nextline(" Data Size: 3891 Bytes = 3.8 KiB"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Unknown OS"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1"); ut_assert_nextline(" Image 6 (fpga)"); - ut_assert_nextline(" Description: Test FPGA"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: FPGA Image"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x000127e0"); - ut_assert_nextline(" Data Size: 4291 Bytes = 4.2 KiB"); - ut_assert_nextline(" Load Address: unavailable"); - ut_assert_nextline(" Hash algo: sha256"); - ut_assert_nextline(" Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622"); + ut_assert_nextline(" Description: Test FPGA"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: FPGA Image"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x000127e0"); + ut_assert_nextline(" Data Size: 4291 Bytes = 4.2 KiB"); + ut_assert_nextline(" Load Address: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622"); ut_assert_nextline(" Image 7 (script)"); - ut_assert_nextline(" Description: unavailable"); - ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); - ut_assert_nextline(" Type: Script"); - ut_assert_nextline(" Compression: uncompressed"); - ut_assert_nextline(" Data Start: 0x0001394c"); - ut_assert_nextline(" Data Size: 3791 Bytes = 3.7 KiB"); - ut_assert_nextline(" Hash algo: invalid/unsupported"); + ut_assert_nextline(" Description: unavailable"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Script"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x0001394c"); + ut_assert_nextline(" Data Size: 3791 Bytes = 3.7 KiB"); + ut_assert_nextline(" Hash algo: invalid/unsupported"); ut_assert_nextline(" Default Configuration: 'conf-1'"); ut_assert_nextline(" Configuration 0 (conf-1)"); - ut_assert_nextline(" Description: Test configuration"); - ut_assert_nextline(" Kernel: kernel"); - ut_assert_nextline(" Init Ramdisk: ramdisk"); - ut_assert_nextline(" FDT: fdt-1"); - ut_assert_nextline(" Compatible: vendor,board-1.0"); - ut_assert_nextline(" vendor,board"); - ut_assert_nextline(" Sign algo: sha256,rsa2048:test-key"); - ut_assert_nextline(" Sign padding: pkcs-1.5"); - ut_assert_nextlinen(" Sign value: c20f64d9bf79ddb0b1a6"); - ut_assert_nextline(" Timestamp: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Description: Test configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" Init Ramdisk: ramdisk"); + ut_assert_nextline(" FDT: fdt-1"); + ut_assert_nextline(" Compatible: vendor,board-1.0"); + ut_assert_nextline(" vendor,board"); + ut_assert_nextline(" Sign algo: sha256,rsa2048:test-key"); + ut_assert_nextline(" Sign padding: pkcs-1.5"); + ut_assert_nextlinen(" Sign value: c20f64d9bf79ddb0b1a6"); + ut_assert_nextline(" Timestamp: 2009-02-13 23:31:30 UTC"); ut_assert_nextline(" Configuration 1 (conf-2)"); - ut_assert_nextline(" Description: Alternate configuration"); - ut_assert_nextline(" Kernel: kernel"); - ut_assert_nextline(" FDT: fdt-1"); - ut_assert_nextline(" fdt-2"); - ut_assert_nextline(" FPGA: fpga"); - ut_assert_nextline(" Loadables: firmware-1"); - ut_assert_nextline(" firmware-2"); - ut_assert_nextline(" Compatible: vendor,board-2.0"); + ut_assert_nextline(" Description: Alternate configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" FDT: fdt-1"); + ut_assert_nextline(" fdt-2"); + ut_assert_nextline(" FPGA: fpga"); + ut_assert_nextline(" Loadables: firmware-1"); + ut_assert_nextline(" firmware-2"); + ut_assert_nextline(" Compatible: vendor,board-2.0"); ut_assert_nextline(" Configuration 2 (conf-3)"); - ut_assert_nextline(" Description: unavailable"); - ut_assert_nextline(" Kernel: unavailable"); - ut_assert_nextline(" Loadables: script"); + ut_assert_nextline(" Description: unavailable"); + ut_assert_nextline(" Kernel: unavailable"); + ut_assert_nextline(" Loadables: script"); ut_assert_console_end(); os_free(buf); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py index 180467fba72..d8b034e9ce9 100644 --- a/test/py/tests/test_fit_print.py +++ b/test/py/tests/test_fit_print.py @@ -318,110 +318,110 @@ def test_fit_print_mkimage(ubman): FIT description: Test FIT image for printing Created: {timestamp_str} Image 0 (kernel) - Description: Test kernel - Created: {timestamp_str} - Type: Kernel Image - Compression: gzip compressed - Data Size: 327 Bytes = 0.32 KiB = 0.00 MiB - Architecture: Sandbox - OS: Linux - Load Address: 0x01000000 - Entry Point: 0x01000000 - Hash algo: sha256 - Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee + Description: Test kernel + Created: {timestamp_str} + Type: Kernel Image + Compression: gzip compressed + Data Size: 327 Bytes = 0.32 KiB = 0.00 MiB + Architecture: Sandbox + OS: Linux + Load Address: 0x01000000 + Entry Point: 0x01000000 + Hash algo: sha256 + Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee Image 1 (ramdisk) - Description: Test ramdisk - Created: {timestamp_str} - Type: RAMDisk Image - Compression: uncompressed - Data Size: 301 Bytes = 0.29 KiB = 0.00 MiB - Architecture: Sandbox - OS: Linux - Load Address: 0x02000000 - Entry Point: unavailable - Hash algo: sha256 - Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655 + Description: Test ramdisk + Created: {timestamp_str} + Type: RAMDisk Image + Compression: uncompressed + Data Size: 301 Bytes = 0.29 KiB = 0.00 MiB + Architecture: Sandbox + OS: Linux + Load Address: 0x02000000 + Entry Point: unavailable + Hash algo: sha256 + Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655 Image 2 (fdt-1) - Description: Test FDT 1 - Created: {timestamp_str} - Type: Flat Device Tree - Compression: uncompressed - Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB - Architecture: Sandbox - Hash algo: sha256 - Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb + Description: Test FDT 1 + Created: {timestamp_str} + Type: Flat Device Tree + Compression: uncompressed + Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB + Architecture: Sandbox + Hash algo: sha256 + Hash value: 1264bc4619a1162736fdca8e63e44a1b009fbeaaa259c356b555b91186257ffb Image 3 (fdt-2) - Description: Test FDT 2 - Created: {timestamp_str} - Type: Flat Device Tree - Compression: uncompressed - Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB - Architecture: Sandbox - Hash algo: sha256 - Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4 + Description: Test FDT 2 + Created: {timestamp_str} + Type: Flat Device Tree + Compression: uncompressed + Data Size: 161 Bytes = 0.16 KiB = 0.00 MiB + Architecture: Sandbox + Hash algo: sha256 + Hash value: 3a07e37c76dd48c2a17927981f0959758ac6fd0d649e2032143c5afeea9a98a4 Image 4 (firmware-1) - Description: Test Firmware 1 - Created: {timestamp_str} - Type: Firmware - Compression: uncompressed - Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB - Architecture: Sandbox - OS: Unknown OS - Load Address: unavailable - Hash algo: sha256 - Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414 + Description: Test Firmware 1 + Created: {timestamp_str} + Type: Firmware + Compression: uncompressed + Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB + Architecture: Sandbox + OS: Unknown OS + Load Address: unavailable + Hash algo: sha256 + Hash value: 53f1358540a556282764ceaf2912e701d2e25902a6b069b329e57e3c59148414 Image 5 (firmware-2) - Description: Test Firmware 2 - Created: {timestamp_str} - Type: Firmware - Compression: uncompressed - Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB - Architecture: Sandbox - OS: Unknown OS - Load Address: unavailable - Hash algo: sha256 - Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1 + Description: Test Firmware 2 + Created: {timestamp_str} + Type: Firmware + Compression: uncompressed + Data Size: 3891 Bytes = 3.80 KiB = 0.00 MiB + Architecture: Sandbox + OS: Unknown OS + Load Address: unavailable + Hash algo: sha256 + Hash value: 6a12ac2283f3c9605113b5c2287e983da5671d8d0015381009d75169526676f1 Image 6 (fpga) - Description: Test FPGA - Created: {timestamp_str} - Type: FPGA Image - Compression: uncompressed - Data Size: 4291 Bytes = 4.19 KiB = 0.00 MiB - Load Address: unavailable - Hash algo: sha256 - Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622 + Description: Test FPGA + Created: {timestamp_str} + Type: FPGA Image + Compression: uncompressed + Data Size: 4291 Bytes = 4.19 KiB = 0.00 MiB + Load Address: unavailable + Hash algo: sha256 + Hash value: 2f588e50e95abc7f9d6afd1d5b3f2bf285cccd55efcf52f47a975dbff3265622 Image 7 (script) - Description: unavailable - Created: {timestamp_str} - Type: Script - Compression: uncompressed - Data Size: 3791 Bytes = 3.70 KiB = 0.00 MiB - Hash algo: invalid/unsupported + Description: unavailable + Created: {timestamp_str} + Type: Script + Compression: uncompressed + Data Size: 3791 Bytes = 3.70 KiB = 0.00 MiB + Hash algo: invalid/unsupported Default Configuration: 'conf-1' Configuration 0 (conf-1) - Description: Test configuration - Kernel: kernel - Init Ramdisk: ramdisk - FDT: fdt-1 - Compatible: vendor,board-1.0 - vendor,board - Sign algo: sha256,rsa2048:test-key - Sign padding: pkcs-1.5 - Sign value: c20f64d9bf79ddb0b1a69293b2375ad88e70536684705a9577f2156e6da4df6d - Timestamp: {timestamp_str} + Description: Test configuration + Kernel: kernel + Init Ramdisk: ramdisk + FDT: fdt-1 + Compatible: vendor,board-1.0 + vendor,board + Sign algo: sha256,rsa2048:test-key + Sign padding: pkcs-1.5 + Sign value: c20f64d9bf79ddb0b1a69293b2375ad88e70536684705a9577f2156e6da4df6d + Timestamp: {timestamp_str} Configuration 1 (conf-2) - Description: Alternate configuration - Kernel: kernel - FDT: fdt-1 - fdt-2 - FPGA: fpga - Loadables: firmware-1 - firmware-2 - Compatible: vendor,board-2.0 + Description: Alternate configuration + Kernel: kernel + FDT: fdt-1 + fdt-2 + FPGA: fpga + Loadables: firmware-1 + firmware-2 + Compatible: vendor,board-2.0 Configuration 2 (conf-3) - Description: unavailable - Kernel: unavailable - Loadables: script + Description: unavailable + Kernel: unavailable + Loadables: script '''.strip().split('\n') lines = output.split('\n') -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Refactor the printing of multi-line properties to use the emit_label_val() helper function instead of custom formatting. Update emit_label() to deal with an empty label and not show a colon in that case. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index e26f2294229..628d6108bea 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -69,7 +69,7 @@ static void emit_label(struct fit_print_ctx *ctx, const char *label) { int len; - len = printf("%*s%s:", ctx->indent, "", label); + len = printf("%*s%s%c", ctx->indent, "", label, *label ? ':' : ' '); printf("%*s", ctx->tab - len, ""); } @@ -315,7 +315,6 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; - int p = ctx->indent; const char *uname, *desc; int ret, ndepth, i; @@ -338,13 +337,8 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, i, NULL), uname; - i++) { - if (!i) - emit_label(ctx, "FDT"); - else - printf("%*s ", p, ""); - printf("%s\n", uname); - } + i++) + emit_label_val(ctx, i ? "" : "FDT", uname); uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); if (uname) @@ -354,23 +348,13 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP, i, NULL), uname; - i++) { - if (!i) - emit_label(ctx, "Loadables"); - else - printf("%*s ", p, ""); - printf("%s\n", uname); - } + i++) + emit_label_val(ctx, i ? "" : "Loadables", uname); /* Show the list of compatible strings */ for (i = 0; uname = fdt_stringlist_get(fit, noffset, - FIT_COMPATIBLE_PROP, i, NULL), uname; i++) { - if (!i) - emit_label(ctx, "Compatible"); - else - printf("%*s ", p, ""); - printf("%s\n", uname); - } + FIT_COMPATIBLE_PROP, i, NULL), uname; i++) + emit_label_val(ctx, i ? "" : "Compatible", uname); /* Process all hash subnodes of the component configuration node */ for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth); @@ -399,11 +383,7 @@ void fit_print(struct fit_print_ctx *ctx) /* Root node properties */ ret = fit_get_desc(fit, 0, &desc); - printf("%*sFIT description: ", p, ""); - if (ret) - printf("unavailable\n"); - else - printf("%s\n", desc); + emit_label_val(ctx, "FIT description", ret ? "unavailable" : desc); if (IMAGE_ENABLE_TIMESTAMP) { ret = fit_get_timestamp(fit, 0, ×tamp); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a new emit_prop() helper function to simplify printing optional properties in FIT configurations. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 628d6108bea..84836a71090 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -90,6 +90,27 @@ static void emit_label_val(struct fit_print_ctx *ctx, const char *label, printf("%s\n", val); } +/** + * emit_prop() - print a property if it exists + * @ctx: pointer to FIT print context + * @noffset: offset of the node containing the property + * @prop: property name to get and print + * @label: label string to use when printing + * + * Gets a property from the specified node and prints it with the given label + * only if the property exists. This is a convenience function for optional + * properties that should only be printed when present. + */ +static void emit_prop(struct fit_print_ctx *ctx, int noffset, + const char *prop, const char *label) +{ + const char *val; + + val = fdt_getprop(ctx->fit, noffset, prop, NULL); + if (val) + emit_label_val(ctx, label, val); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -326,13 +347,8 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) emit_label_val(ctx, "Kernel", uname ?: "unavailable"); /* Optional properties */ - uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); - if (uname) - emit_label_val(ctx, "Init Ramdisk", uname); - - uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL); - if (uname) - emit_label_val(ctx, "Firmware", uname); + emit_prop(ctx, noffset, FIT_RAMDISK_PROP, "Init Ramdisk"); + emit_prop(ctx, noffset, FIT_FIRMWARE_PROP, "Firmware"); for (i = 0; uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, @@ -340,9 +356,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) i++) emit_label_val(ctx, i ? "" : "FDT", uname); - uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); - if (uname) - emit_label_val(ctx, "FPGA", uname); + emit_prop(ctx, noffset, FIT_FPGA_PROP, "FPGA"); /* Print out all of the specified loadables */ for (i = 0; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a new emit_timestamp() helper function to handle printing timestamps in FITs. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 56 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 84836a71090..9696679762d 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -111,6 +111,28 @@ static void emit_prop(struct fit_print_ctx *ctx, int noffset, emit_label_val(ctx, label, val); } +/** + * emit_timestamp() - print a timestamp + * @ctx: pointer to FIT print context + * @noffset: offset of the node containing the timestamp + * @label: label string to use when printing + * + * Gets the timestamp from the specified node and prints it with the given + * label. If the timestamp is not available, prints "unavailable" instead. + * This is a convenience function for printing FIT timestamps. + */ +static void emit_timestamp(struct fit_print_ctx *ctx, int noffset, + const char *label) +{ + time_t timestamp; + + emit_label(ctx, label); + if (fit_get_timestamp(ctx->fit, noffset, ×tamp)) + printf("unavailable\n"); + else + genimg_print_time(timestamp); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -163,15 +185,8 @@ static void fit_image_print_data(struct fit_print_ctx *ctx, int noffset, debug("%s len: %d\n", type, value_len); /* Signatures have a time stamp */ - if (IMAGE_ENABLE_TIMESTAMP && keyname) { - time_t timestamp; - - emit_label(ctx, "Timestamp"); - if (fit_get_timestamp(fit, noffset, ×tamp)) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } + if (IMAGE_ENABLE_TIMESTAMP && keyname) + emit_timestamp(ctx, noffset, "Timestamp"); } /** @@ -233,16 +248,8 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) ret = fit_get_desc(fit, image_noffset, &desc); emit_label_val(ctx, "Description", ret ? "unavailable" : desc); - if (IMAGE_ENABLE_TIMESTAMP) { - time_t timestamp; - - ret = fit_get_timestamp(fit, 0, ×tamp); - emit_label(ctx, "Created"); - if (ret) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } + if (IMAGE_ENABLE_TIMESTAMP) + emit_timestamp(ctx, 0, "Created"); fit_image_get_type(fit, image_noffset, &type); emit_label_val(ctx, "Type", genimg_get_type_name(type)); @@ -393,20 +400,13 @@ void fit_print(struct fit_print_ctx *ctx) int ndepth; int count = 0; int ret; - time_t timestamp; /* Root node properties */ ret = fit_get_desc(fit, 0, &desc); emit_label_val(ctx, "FIT description", ret ? "unavailable" : desc); - if (IMAGE_ENABLE_TIMESTAMP) { - ret = fit_get_timestamp(fit, 0, ×tamp); - printf("%*sCreated: ", p, ""); - if (ret) - printf("unavailable\n"); - else - genimg_print_time(timestamp); - } + if (IMAGE_ENABLE_TIMESTAMP) + emit_timestamp(ctx, 0, "Created"); /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a emit_stringlist() helper function to simplify printing stringlist properties in FIT configurations. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 56 +++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 9696679762d..8781d5a7da7 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -126,6 +126,8 @@ static void emit_timestamp(struct fit_print_ctx *ctx, int noffset, { time_t timestamp; + if (!IMAGE_ENABLE_TIMESTAMP) + return; emit_label(ctx, label); if (fit_get_timestamp(ctx->fit, noffset, ×tamp)) printf("unavailable\n"); @@ -133,6 +135,30 @@ static void emit_timestamp(struct fit_print_ctx *ctx, int noffset, genimg_print_time(timestamp); } +/** + * emit_stringlist() - print a stringlist property + * @ctx: pointer to FIT print context + * @noffset: offset of the node containing the property + * @prop: property name to get and print + * @label: label string to use when printing + * + * Gets a stringlist property from the specified node and prints each string + * with the given label. The first string shows the label, subsequent strings + * are indented to align with the first value. If the property doesn't exist, + * nothing is printed. + */ +static void emit_stringlist(struct fit_print_ctx *ctx, int noffset, + const char *prop, const char *label) +{ + const char *val; + int i; + + for (i = 0; + val = fdt_stringlist_get(ctx->fit, noffset, prop, i, NULL), val; + i++) + emit_label_val(ctx, i ? "" : label, val); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -248,8 +274,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) ret = fit_get_desc(fit, image_noffset, &desc); emit_label_val(ctx, "Description", ret ? "unavailable" : desc); - if (IMAGE_ENABLE_TIMESTAMP) - emit_timestamp(ctx, 0, "Created"); + emit_timestamp(ctx, 0, "Created"); fit_image_get_type(fit, image_noffset, &type); emit_label_val(ctx, "Type", genimg_get_type_name(type)); @@ -344,7 +369,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; const char *uname, *desc; - int ret, ndepth, i; + int ret, ndepth; /* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc); @@ -356,26 +381,10 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) /* Optional properties */ emit_prop(ctx, noffset, FIT_RAMDISK_PROP, "Init Ramdisk"); emit_prop(ctx, noffset, FIT_FIRMWARE_PROP, "Firmware"); - - for (i = 0; - uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP, - i, NULL), uname; - i++) - emit_label_val(ctx, i ? "" : "FDT", uname); - + emit_stringlist(ctx, noffset, FIT_FDT_PROP, "FDT"); emit_prop(ctx, noffset, FIT_FPGA_PROP, "FPGA"); - - /* Print out all of the specified loadables */ - for (i = 0; - uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP, - i, NULL), uname; - i++) - emit_label_val(ctx, i ? "" : "Loadables", uname); - - /* Show the list of compatible strings */ - for (i = 0; uname = fdt_stringlist_get(fit, noffset, - FIT_COMPATIBLE_PROP, i, NULL), uname; i++) - emit_label_val(ctx, i ? "" : "Compatible", uname); + emit_stringlist(ctx, noffset, FIT_LOADABLE_PROP, "Loadables"); + emit_stringlist(ctx, noffset, FIT_COMPATIBLE_PROP, "Compatible"); /* Process all hash subnodes of the component configuration node */ for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth); @@ -405,8 +414,7 @@ void fit_print(struct fit_print_ctx *ctx) ret = fit_get_desc(fit, 0, &desc); emit_label_val(ctx, "FIT description", ret ? "unavailable" : desc); - if (IMAGE_ENABLE_TIMESTAMP) - emit_timestamp(ctx, 0, "Created"); + emit_timestamp(ctx, 0, "Created"); /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add emit_desc() which handles getting and printing descriptions from FIT nodes. Handle the "unavailable" case when a description is missing. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 8781d5a7da7..069afbe8567 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -159,6 +159,26 @@ static void emit_stringlist(struct fit_print_ctx *ctx, int noffset, emit_label_val(ctx, i ? "" : label, val); } +/** + * emit_desc() - print a description + * @ctx: pointer to FIT print context + * @noffset: offset of the node containing the description + * @label: label string to use when printing + * + * Gets the description from the specified node and prints it with the given + * label. If the description is not available, prints "unavailable" instead. + * This is a convenience function for printing FIT descriptions. + */ +static void emit_desc(struct fit_print_ctx *ctx, int noffset, + const char *label) +{ + const char *desc; + int ret; + + ret = fit_get_desc(ctx->fit, noffset, &desc); + emit_label_val(ctx, label, ret ? "unavailable" : desc); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -262,7 +282,6 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) { const void *fit = ctx->fit; uint8_t type, arch, os, comp = IH_COMP_NONE; - const char *desc; size_t size; ulong load, entry; const void *data; @@ -271,8 +290,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) int ret; /* Mandatory properties */ - ret = fit_get_desc(fit, image_noffset, &desc); - emit_label_val(ctx, "Description", ret ? "unavailable" : desc); + emit_desc(ctx, image_noffset, "Description"); emit_timestamp(ctx, 0, "Created"); @@ -368,12 +386,11 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; - const char *uname, *desc; - int ret, ndepth; + const char *uname; + int ndepth; /* Mandatory properties */ - ret = fit_get_desc(fit, noffset, &desc); - emit_label_val(ctx, "Description", ret ? "unavailable" : desc); + emit_desc(ctx, noffset, "Description"); uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); emit_label_val(ctx, "Kernel", uname ?: "unavailable"); @@ -401,18 +418,15 @@ void fit_print(struct fit_print_ctx *ctx) { const void *fit = ctx->fit; int p = ctx->indent; - const char *desc; char *uname; int images_noffset; int confs_noffset; int noffset; int ndepth; int count = 0; - int ret; /* Root node properties */ - ret = fit_get_desc(fit, 0, &desc); - emit_label_val(ctx, "FIT description", ret ? "unavailable" : desc); + emit_desc(ctx, 0, "FIT description"); emit_timestamp(ctx, 0, "Created"); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add emit_addr() to handle printing load an entry addresses. The helper takes a 'valid' boolean parameter to determine whether to print the address value or 'unavailable'. Combine the two separate if() blocks for the load address. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 069afbe8567..70199a34c18 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -179,6 +179,26 @@ static void emit_desc(struct fit_print_ctx *ctx, int noffset, emit_label_val(ctx, label, ret ? "unavailable" : desc); } +/** + * emit_addr() - print an address property + * @ctx: pointer to FIT print context + * @label: label string to use when printing + * @addr: address value to print + * @valid: true if the address is valid, false to print "unavailable" + * + * Prints an address with the given label. If valid is false, prints + * "unavailable" instead of the address value. + */ +static void emit_addr(struct fit_print_ctx *ctx, const char *label, ulong addr, + bool valid) +{ + emit_label(ctx, label); + if (valid) + printf("0x%08lx\n", addr); + else + printf("unavailable\n"); +} + /** * fit_image_print_data() - prints out the hash node details * @ctx: pointer to FIT print context @@ -335,30 +355,16 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || type == IH_TYPE_FIRMWARE || type == IH_TYPE_RAMDISK || - type == IH_TYPE_FPGA) { + type == IH_TYPE_FPGA || type == IH_TYPE_FLATDT) { ret = fit_image_get_load(fit, image_noffset, &load); - emit_label(ctx, "Load Address"); - if (ret) - printf("unavailable\n"); - else - printf("0x%08lx\n", load); - } - - /* optional load address for FDT */ - if (type == IH_TYPE_FLATDT && - !fit_image_get_load(fit, image_noffset, &load)) { - emit_label(ctx, "Load Address"); - printf("0x%08lx\n", load); + if ((type != IH_TYPE_FLATDT) || !ret) + emit_addr(ctx, "Load Address", load, !ret); } if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || type == IH_TYPE_RAMDISK) { ret = fit_image_get_entry(fit, image_noffset, &entry); - emit_label(ctx, "Entry Point"); - if (ret) - printf("unavailable\n"); - else - printf("0x%08lx\n", entry); + emit_addr(ctx, "Entry Point", entry, !ret); } /* Process all hash subnodes of the component image node */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a boolean variable 'loadable' that combines the common type check for kernel, standalone, and ramdisk images. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 70199a34c18..6772460a151 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -340,29 +340,27 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) genimg_print_size(size); /* Remaining, type dependent properties */ - if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || - type == IH_TYPE_RAMDISK || type == IH_TYPE_FIRMWARE || - type == IH_TYPE_FLATDT) { + bool loadable = type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || + type == IH_TYPE_RAMDISK; + + if (loadable || type == IH_TYPE_FIRMWARE || type == IH_TYPE_FLATDT) { fit_image_get_arch(fit, image_noffset, &arch); emit_label_val(ctx, "Architecture", genimg_get_arch_name(arch)); } - if (type == IH_TYPE_KERNEL || type == IH_TYPE_RAMDISK || - type == IH_TYPE_FIRMWARE) { + if (loadable || type == IH_TYPE_FIRMWARE) { fit_image_get_os(fit, image_noffset, &os); emit_label_val(ctx, "OS", genimg_get_os_name(os)); } - if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || - type == IH_TYPE_FIRMWARE || type == IH_TYPE_RAMDISK || - type == IH_TYPE_FPGA || type == IH_TYPE_FLATDT) { + if (loadable || type == IH_TYPE_FIRMWARE || type == IH_TYPE_FPGA || + type == IH_TYPE_FLATDT) { ret = fit_image_get_load(fit, image_noffset, &load); - if ((type != IH_TYPE_FLATDT) || !ret) + if (type != IH_TYPE_FLATDT || !ret) emit_addr(ctx, "Load Address", load, !ret); } - if (type == IH_TYPE_KERNEL || type == IH_TYPE_STANDALONE || - type == IH_TYPE_RAMDISK) { + if (loadable) { ret = fit_image_get_entry(fit, image_noffset, &entry); emit_addr(ctx, "Entry Point", entry, !ret); } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The pattern for iterating through and processing hash/signature subnodes is repeated in two places. Add a new process_subnodes() helper to reduce code duplication. Drop the now-unused ndepth and noffset local variables. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 6772460a151..638f66942e9 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -283,6 +283,28 @@ static void fit_image_print_verification_data(struct fit_print_ctx *ctx, fit_image_print_data(ctx, noffset, "Sign"); } +/** + * process_subnodes() - process and print verification data for all subnodes + * @ctx: pointer to FIT print context + * @parent: parent node offset + * + * Iterates through all direct child nodes of the parent and prints their + * verification data (hash/signature information). + */ +static void process_subnodes(struct fit_print_ctx *ctx, int parent) +{ + const void *fit = ctx->fit; + int noffset; + int ndepth; + + for (ndepth = 0, noffset = fdt_next_node(fit, parent, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) + fit_image_print_verification_data(ctx, noffset); + } +} + /** * fit_image_print - prints out the FIT component image details * @ctx: pointer to FIT print context @@ -305,8 +327,6 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) size_t size; ulong load, entry; const void *data; - int noffset; - int ndepth; int ret; /* Mandatory properties */ @@ -366,14 +386,7 @@ void fit_image_print(struct fit_print_ctx *ctx, int image_noffset) } /* Process all hash subnodes of the component image node */ - for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* Direct child node of the component image node */ - fit_image_print_verification_data(ctx, noffset); - } - } + process_subnodes(ctx, image_noffset); } /** @@ -391,7 +404,6 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) { const void *fit = ctx->fit; const char *uname; - int ndepth; /* Mandatory properties */ emit_desc(ctx, noffset, "Description"); @@ -408,14 +420,7 @@ static void fit_conf_print(struct fit_print_ctx *ctx, int noffset) emit_stringlist(ctx, noffset, FIT_COMPATIBLE_PROP, "Compatible"); /* Process all hash subnodes of the component configuration node */ - for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* Direct child node of the component config node */ - fit_image_print_verification_data(ctx, noffset); - } - } + process_subnodes(ctx, noffset); } void fit_print(struct fit_print_ctx *ctx) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Replace fdt_next_node() with depth tracking with fdt_for_each_subnode() which has been available for some time. This also fixes a latent bug where the default configuration was being read from the wrong node offset. It happened to work before because noffset ended up at the right value after the images loop. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/fit_print.c | 70 +++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/boot/fit_print.c b/boot/fit_print.c index 638f66942e9..f4428d020e5 100644 --- a/boot/fit_print.c +++ b/boot/fit_print.c @@ -295,14 +295,9 @@ static void process_subnodes(struct fit_print_ctx *ctx, int parent) { const void *fit = ctx->fit; int noffset; - int ndepth; - for (ndepth = 0, noffset = fdt_next_node(fit, parent, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) - fit_image_print_verification_data(ctx, noffset); - } + fdt_for_each_subnode(noffset, fit, parent) + fit_image_print_verification_data(ctx, noffset); } /** @@ -431,8 +426,7 @@ void fit_print(struct fit_print_ctx *ctx) int images_noffset; int confs_noffset; int noffset; - int ndepth; - int count = 0; + int count; /* Root node properties */ emit_desc(ctx, 0, "FIT description"); @@ -448,22 +442,18 @@ void fit_print(struct fit_print_ctx *ctx) } /* Process its subnodes, print out component images details */ - for (ndepth = 0, count = 0, - noffset = fdt_next_node(fit, images_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* - * Direct child node of the images parent node, - * i.e. component image node. - */ - printf("%*s Image %u (%s)\n", p, "", count++, - fit_get_name(fit, noffset)); - - ctx->indent += 2; - fit_image_print(ctx, noffset); - ctx->indent -= 2; - } + count = 0; + fdt_for_each_subnode(noffset, fit, images_noffset) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf("%*s Image %u (%s)\n", p, "", count++, + fit_get_name(fit, noffset)); + + ctx->indent += 2; + fit_image_print(ctx, noffset); + ctx->indent -= 2; } /* Find configurations parent node offset */ @@ -475,27 +465,23 @@ void fit_print(struct fit_print_ctx *ctx) } /* get default configuration unit name from default property */ - uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); + uname = (char *)fdt_getprop(fit, confs_noffset, FIT_DEFAULT_PROP, NULL); if (uname) printf("%*s Default Configuration: '%s'\n", p, "", uname); /* Process its subnodes, print out configurations details */ - for (ndepth = 0, count = 0, - noffset = fdt_next_node(fit, confs_noffset, &ndepth); - (noffset >= 0) && (ndepth > 0); - noffset = fdt_next_node(fit, noffset, &ndepth)) { - if (ndepth == 1) { - /* - * Direct child node of the configurations parent node, - * i.e. configuration node. - */ - printf("%*s Configuration %u (%s)\n", p, "", count++, - fit_get_name(fit, noffset)); - - ctx->indent += 2; - fit_conf_print(ctx, noffset); - ctx->indent -= 2; - } + count = 0; + fdt_for_each_subnode(noffset, fit, confs_noffset) { + /* + * Direct child node of the configurations parent node, + * i.e. configuration node. + */ + printf("%*s Configuration %u (%s)\n", p, "", count++, + fit_get_name(fit, noffset)); + + ctx->indent += 2; + fit_conf_print(ctx, noffset); + ctx->indent -= 2; } } -- 2.43.0
participants (1)
-
Simon Glass