From 367e12597617b2581eb72b3676c6cb86822268b5 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:34:35 +0000 Subject: fdt: Check error codes returned from fdtlib when loading ITB Before this patch, error codes returned from fdtlib were ignored and continued access would cause a crash. Now just check if the image is truncated and error if so. Signed-off-by: Joe Hershberger --- common/image.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'common') diff --git a/common/image.c b/common/image.c index f084d2bae..852a96fab 100644 --- a/common/image.c +++ b/common/image.c @@ -2820,6 +2820,11 @@ int fit_image_check_hashes(const void *fit, int image_noffset) } } + if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { + err_msg = " error!\nCorrupted or truncated tree"; + goto error; + } + return 1; error: -- cgit v1.2.3 From f0a29d43313c9d0d9091aeae175bd7e8e7ac6124 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:34:36 +0000 Subject: fdt: Limit printed hex in fdt print and list commands Prevent printing the entire image in a itb. It is most likely unhelpful to have the hex of the entire image scroll for minutes on your slow serial console. Signed-off-by: Joe Hershberger --- common/cmd_fdt.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'common') diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index e2225c4d5..699441b51 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -35,6 +35,9 @@ #define MAX_LEVEL 32 /* how deeply nested we will go */ #define SCRATCHPAD 1024 /* bytes of scratchpad memory */ +#ifndef CONFIG_CMD_FDT_MAX_DUMP +#define CONFIG_CMD_FDT_MAX_DUMP 64 +#endif /* * Global data (for the gd->bd) @@ -672,19 +675,28 @@ static void print_data(const void *data, int len) } if ((len %4) == 0) { - const u32 *p; - - printf("<"); - for (j = 0, p = data; j < len/4; j ++) - printf("0x%x%s", fdt32_to_cpu(p[j]), j < (len/4 - 1) ? " " : ""); - printf(">"); + if (len > CONFIG_CMD_FDT_MAX_DUMP) + printf("* 0x%08x [0x%08x]", (unsigned int)data, len); + else { + const u32 *p; + + printf("<"); + for (j = 0, p = data; j < len/4; j++) + printf("0x%08x%s", fdt32_to_cpu(p[j]), + j < (len/4 - 1) ? " " : ""); + printf(">"); + } } else { /* anything else... hexdump */ - const u8 *s; - - printf("["); - for (j = 0, s = data; j < len; j++) - printf("%02x%s", s[j], j < len - 1 ? " " : ""); - printf("]"); + if (len > CONFIG_CMD_FDT_MAX_DUMP) + printf("* 0x%08x [0x%08x]", (unsigned int)data, len); + else { + const u8 *s; + + printf("["); + for (j = 0, s = data; j < len; j++) + printf("%02x%s", s[j], j < len - 1 ? " " : ""); + printf("]"); + } } } -- cgit v1.2.3 From bc80295b620c5abf9d4fb3b00846ef018e921540 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:34:37 +0000 Subject: fdt: Add get commands to fdt Add commands to access data in the fdt. This allows data from a dtb or itb to be accessed from the shell scripts. Signed-off-by: Joe Hershberger --- common/cmd_fdt.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) (limited to 'common') diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 699441b51..299745237 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; static int fdt_valid(void); static int fdt_parse_prop(char *const*newval, int count, char *data, int *len); static int fdt_print(const char *pathp, char *prop, int depth); +static int is_printable_string(const void *data, int len); /* * The working_fdt points to our working flattened device tree. @@ -63,6 +64,34 @@ void set_working_fdt_addr(void *addr) setenv("fdtaddr", buf); } +/* + * Get a value from the fdt and format it to be set in the environment + */ +static int fdt_value_setenv(const void *nodep, int len, const char *var) +{ + if (is_printable_string(nodep, len)) + setenv(var, (void *)nodep); + else if (len == 4) { + char buf[11]; + + sprintf(buf, "0x%08X", *(uint32_t *)nodep); + setenv(var, buf); + } else if (len%4 == 0 && len <= 20) { + /* Needed to print things like sha1 hashes. */ + char buf[41]; + int i; + + for (i = 0; i < len; i += sizeof(unsigned int)) + sprintf(buf + (i * 2), "%08x", + *(unsigned int *)(nodep + i)); + setenv(var, buf); + } else { + printf("error: unprintable value\n"); + return 1; + } + return 0; +} + /* * Flattened Device Tree command, see the help for parameter definitions. */ @@ -253,6 +282,117 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 1; } + /******************************************************************** + * Get the value of a property in the working_fdt. + ********************************************************************/ + } else if (argv[1][0] == 'g') { + char *subcmd; /* sub-command */ + char *pathp; /* path */ + char *prop; /* property */ + char *var; /* variable to store result */ + int nodeoffset; /* node offset from libfdt */ + const void *nodep; /* property node pointer */ + int len = 0; /* new length of the property */ + + /* + * Parameters: Node path, property, optional value. + */ + if (argc < 5) + return CMD_RET_USAGE; + + subcmd = argv[2]; + + if (argc < 6 && subcmd[0] != 's') + return CMD_RET_USAGE; + + var = argv[3]; + pathp = argv[4]; + prop = argv[5]; + + nodeoffset = fdt_path_offset(working_fdt, pathp); + if (nodeoffset < 0) { + /* + * Not found or something else bad happened. + */ + printf("libfdt fdt_path_offset() returned %s\n", + fdt_strerror(nodeoffset)); + return 1; + } + + if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) { + int reqIndex = -1; + int startDepth = fdt_node_depth( + working_fdt, nodeoffset); + int curDepth = startDepth; + int curIndex = -1; + int nextNodeOffset = fdt_next_node( + working_fdt, nodeoffset, &curDepth); + + if (subcmd[0] == 'n') + reqIndex = simple_strtoul(argv[5], NULL, 16); + + while (curDepth > startDepth) { + if (curDepth == startDepth + 1) + curIndex++; + if (subcmd[0] == 'n' && curIndex == reqIndex) { + const char *nodeName = fdt_get_name( + working_fdt, nextNodeOffset, NULL); + + setenv(var, (char *)nodeName); + return 0; + } + nextNodeOffset = fdt_next_node( + working_fdt, nextNodeOffset, &curDepth); + if (nextNodeOffset < 0) + break; + } + if (subcmd[0] == 's') { + /* get the num nodes at this level */ + char buf[11]; + + sprintf(buf, "%d", curIndex + 1); + setenv(var, buf); + } else { + /* node index not found */ + printf("libfdt node not found\n"); + return 1; + } + } else { + nodep = fdt_getprop( + working_fdt, nodeoffset, prop, &len); + if (len == 0) { + /* no property value */ + setenv(var, ""); + return 0; + } else if (len > 0) { + if (subcmd[0] == 'v') { + int ret; + + ret = fdt_value_setenv(nodep, len, var); + if (ret != 0) + return ret; + } else if (subcmd[0] == 'a') { + /* Get address */ + char buf[11]; + + sprintf(buf, "0x%08X", (uint32_t)nodep); + setenv(var, buf); + } else if (subcmd[0] == 's') { + /* Get size */ + char buf[11]; + + sprintf(buf, "0x%08X", len); + setenv(var, buf); + } else + return CMD_RET_USAGE; + return 0; + } else { + printf("libfdt fdt_getprop(): %s\n", + fdt_strerror(len)); + return 1; + } + } + /* * Print (recursive) / List (single level) */ @@ -836,6 +976,10 @@ U_BOOT_CMD( "fdt resize - Resize fdt to size + padding to 4k addr\n" "fdt print [] - Recursive print starting at \n" "fdt list [] - Print one level starting at \n" + "fdt get value - Get and store in \n" + "fdt get name - Get name of node and store in \n" + "fdt get addr - Get start address of and store in \n" + "fdt get size [] - Get size of [] or num nodes and store in \n" "fdt set [] - Set [to ]\n" "fdt mknode - Create a new node after \n" "fdt rm [] - Delete the node or \n" -- cgit v1.2.3 From 8805beec8f51e861996860db71a831e4c263cf4c Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:34:38 +0000 Subject: fdt: Identify scripts in ITBs as printable strings Scripts in the ITB format will have spaces in them and will end in a newline charachter. Make sure that these are considered printable. Signed-off-by: Joe Hershberger --- common/cmd_fdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 299745237..a5e2cfcbf 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -754,12 +754,12 @@ static int is_printable_string(const void *data, int len) if (len == 0) return 0; - /* must terminate with zero */ - if (s[len - 1] != '\0') + /* must terminate with zero or '\n' */ + if (s[len - 1] != '\0' && s[len - 1] != '\n') return 0; /* printable or a null byte (concatenated strings) */ - while (((*s == '\0') || isprint(*s)) && (len > 0)) { + while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) { /* * If we see a null, there are three possibilities: * 1) If len == 1, it is the end of the string, printable -- cgit v1.2.3 From 8ac88f2d2818c8efc1558626a4e7fb47dcc18987 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:34:39 +0000 Subject: fdt: Check for a token to skip auto-hash validation Allow the itb file to declare to u-boot that its hash should not be checked automatically on bootm or iminfo. This allows an image to either be checked automatically or to include a script which may check it otherwise (such as after part of the itb has been relocated to RAM by the script). Signed-off-by: Joe Hershberger --- common/image.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'common') diff --git a/common/image.c b/common/image.c index 852a96fab..750a98b6b 100644 --- a/common/image.c +++ b/common/image.c @@ -2496,6 +2496,36 @@ int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, return 0; } +#ifndef USE_HOSTCC +/** + * fit_image_hash_get_ignore - get hash ignore flag + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @ignore: pointer to an int, will hold hash ignore flag + * + * fit_image_hash_get_ignore() finds hash ignore property in a given hash node. + * If the property is found and non-zero, the hash algorithm is not verified by + * u-boot automatically. + * + * returns: + * 0, on ignore not found + * value, on ignore found + */ +int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) +{ + int len; + int *value; + + value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len); + if (value == NULL || len != sizeof(int)) + *ignore = 0; + else + *ignore = *value; + + return 0; +} +#endif + /** * fit_set_timestamp - set node timestamp property * @fit: pointer to the FIT format image header @@ -2759,6 +2789,9 @@ int fit_image_check_hashes(const void *fit, int image_noffset) char *algo; uint8_t *fit_value; int fit_value_len; +#ifndef USE_HOSTCC + int ignore; +#endif uint8_t value[FIT_MAX_HASH_LEN]; int value_len; int noffset; @@ -2795,6 +2828,14 @@ int fit_image_check_hashes(const void *fit, int image_noffset) } printf("%s", algo); +#ifndef USE_HOSTCC + fit_image_hash_get_ignore(fit, noffset, &ignore); + if (ignore) { + printf("-skipped "); + continue; + } +#endif + if (fit_image_hash_get_value(fit, noffset, &fit_value, &fit_value_len)) { err_msg = " error!\nCan't get hash value " -- cgit v1.2.3