diff options
author | Simon Glass <sjg@chromium.org> | 2012-07-12 08:52:49 -0700 |
---|---|---|
committer | Jon Loeliger <jdl@jdl.com> | 2012-07-12 11:57:36 -0500 |
commit | d46c2de5700fd8d43de67ca3709c276beba39b39 (patch) | |
tree | 51f7146ed1c9d294bcfd03708427c54b4fd54fee | |
parent | f58dff50407c0ee56b372ab201469c18dc042f56 (diff) | |
download | dtc-d46c2de5700fd8d43de67ca3709c276beba39b39.zip dtc-d46c2de5700fd8d43de67ca3709c276beba39b39.tar.gz dtc-d46c2de5700fd8d43de67ca3709c276beba39b39.tar.bz2 |
fdtput: Add -c option to create nodes
This option allows the creation of new nodes in a dtb file. The syntax
is:
fdtput -c <dtb_file> <node_path>
The node_path contains the path of the node to be created. All path
components up to the final one must exist already. The final one must
not exist already.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | fdtput.c | 52 | ||||
-rwxr-xr-x | tests/run_tests.sh | 13 |
2 files changed, 64 insertions, 1 deletions
@@ -31,6 +31,7 @@ /* These are the operations we support */ enum oper_type { OPER_WRITE_PROP, /* Write a property in a node */ + OPER_CREATE_NODE, /* Create a new node */ }; struct display_info { @@ -138,6 +139,46 @@ static int store_key_value(void *blob, const char *node_name, return 0; } +/** + * Create a new node in the fdt. + * + * This will overwrite the node_name string. Any error is reported. + * + * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this. + * + * @param blob FDT blob to write into + * @param node_name Name of node to create + * @return new node offset if found, or -1 on failure + */ +static int create_node(void *blob, const char *node_name) +{ + int node = 0; + char *p; + + p = strrchr(node_name, '/'); + if (!p) { + report_error(node_name, -FDT_ERR_BADPATH); + return -1; + } + *p = '\0'; + + if (p > node_name) { + node = fdt_path_offset(blob, node_name); + if (node < 0) { + report_error(node_name, node); + return -1; + } + } + + node = fdt_add_subnode(blob, node, p + 1); + if (node < 0) { + report_error(p + 1, node); + return -1; + } + + return 0; +} + static int do_fdtput(struct display_info *disp, const char *filename, char **arg, int arg_count) { @@ -160,6 +201,10 @@ static int do_fdtput(struct display_info *disp, const char *filename, store_key_value(blob, *arg, arg[1], value, len)) ret = -1; break; + case OPER_CREATE_NODE: + for (; ret >= 0 && arg_count--; arg++) + ret = create_node(blob, *arg); + break; } if (ret >= 0) ret = utilfdt_write(filename, blob); @@ -175,7 +220,9 @@ static const char *usage_msg = "\n" "Usage:\n" " fdtput <options> <dt file> <node> <property> [<value>...]\n" + " fdtput -c <options> <dt file> [<node>...]\n" "Options:\n" + "\t-c\t\tCreate nodes if they don't already exist\n" "\t-t <type>\tType of data\n" "\t-v\t\tVerbose: display each value decoded from command line\n" "\t-h\t\tPrint this help\n\n" @@ -199,7 +246,7 @@ int main(int argc, char *argv[]) disp.size = -1; disp.oper = OPER_WRITE_PROP; for (;;) { - int c = getopt(argc, argv, "ht:v"); + int c = getopt(argc, argv, "cht:v"); if (c == -1) break; @@ -213,6 +260,9 @@ int main(int argc, char *argv[]) * - expand fdt if value doesn't fit */ switch (c) { + case 'c': + disp.oper = OPER_CREATE_NODE; + break; case 'h': case '?': usage(NULL); diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 169a829..617372d 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -536,6 +536,19 @@ fdtput_tests () { # This should be larger than available space in the fdt run_wrap_error_test $DTPUT $dtb /randomnode blob -ts "$(cat $text $text)" + # Start again with a fresh dtb + run_dtc_test -O dtb -p $(stat -c %s $text) -o $dtb $dts + + # Node creation + run_wrap_error_test $DTPUT $dtb -c /baldrick sod + run_wrap_test $DTPUT $dtb -c /chosen/son /chosen/daughter + run_fdtput_test "eva" $dtb /chosen/daughter name "" -ts "eva" + run_fdtput_test "adam" $dtb /chosen/son name "" -ts "adam" + + # Not allowed to create an existing node + run_wrap_error_test $DTPUT $dtb -c /chosen + run_wrap_error_test $DTPUT $dtb -c /chosen/son + # TODO: Add tests for verbose mode? } |