From: Tobias Heider <m...@tobhe.de> With this change it is possible to access properties in subnodes using the -n argument as in 'fdtdump -n chosen -p stdout-path'. It is also possible to access deeper nested properties by passing a path separated by '/' such as 'fdtdump -n path/to/node'
Signed-off-by: Tobias Heider <tobias.hei...@canonical.com> --- docs/grub.texi | 6 +++++- grub-core/loader/efi/fdt.c | 32 +++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index a050dc0fc..06d41fa03 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4909,13 +4909,17 @@ such as @code{if} and @code{while} (@pxref{Shell-like scripting}). @subsection fdtdump @deffn Command fdtdump @ + [@option{--node} @var{node}] @ [@option{--prop} @var{prop}] @ [@option{--set} @var{variable}] Retrieve device tree information. The @command{fdtdump} command returns the value of a property in the device tree provided by the firmware. The @option{--prop} option determines which -property to select. +property to select. By default fdtdump returns properties from the root of +the device tree unless a different @var{node} is specified with the +@option{--node} option. @var{node} can be the name of a root subnode or a path +from the root separated by '/' for deeper nested nodes. The default action is to print the value of the requested field to the console, but a variable name can be specified with @option{--set} to store the value diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c index b43ff730d..7319af0e9 100644 --- a/grub-core/loader/efi/fdt.c +++ b/grub-core/loader/efi/fdt.c @@ -40,6 +40,7 @@ static void *fdt; sizeof (FDT_SIZE_CELLS_STRING)) static const struct grub_arg_option options_fdtdump[] = { + {"node", 'n', 0, N_("Device tree node."), N_("node"), ARG_TYPE_STRING}, {"prop", 'p', 0, N_("Get property."), N_("prop"), ARG_TYPE_STRING}, {"set", '\0', 0, N_("Store the value in the given variable name."), N_("variable"), ARG_TYPE_STRING}, @@ -184,17 +185,34 @@ grub_cmd_fdtdump (grub_extcmd_context_t ctxt, { struct grub_arg_list *state = ctxt->state; const unsigned char *value = NULL; - char *str; + char *node_name, *str, *p; void *fw_fdt; grub_uint32_t len; + int node = 0; fw_fdt = grub_efi_get_firmware_fdt (); if (fw_fdt == NULL) - return grub_error (GRUB_ERR_IO, - N_("No device tree found")); + return grub_error (GRUB_ERR_IO, N_("No device tree found")); if (state[0].set) - value = grub_fdt_get_prop (fw_fdt, 0, state[0].arg, &len); + { + node_name = state[0].arg; + while ((p = grub_strchr (node_name, '/')) != NULL) { + *p = '\0'; + + node = grub_fdt_find_subnode (fw_fdt, node, node_name); + if (node < 1) + return grub_error (GRUB_ERR_IO, N_("failed to find node in fdt")); + + node_name = ++p; + } + node = grub_fdt_find_subnode (fw_fdt, node, node_name); + if (node < 1) + return grub_error (GRUB_ERR_IO, N_("failed to find node in fdt")); + } + + if (state[1].set) + value = grub_fdt_get_prop (fw_fdt, node, state[1].arg, &len); if (value == NULL) return grub_error (GRUB_ERR_OUT_OF_RANGE, @@ -204,8 +222,8 @@ grub_cmd_fdtdump (grub_extcmd_context_t ctxt, if (str == NULL) return grub_error (GRUB_ERR_IO, N_("Failed to print string")); - if (state[1].set) - grub_env_set (state[1].arg, str); + if (state[2].set) + grub_env_set (state[2].arg, str); else grub_printf ("%s", str); @@ -220,7 +238,7 @@ GRUB_MOD_INIT (fdt) { cmd_fdtdump = grub_register_extcmd ("fdtdump", grub_cmd_fdtdump, 0, - N_("[-p] [--set variable]"), + N_("[-n] [-p] [--set variable]"), N_("Retrieve device tree information."), options_fdtdump); cmd_devicetree = -- 2.43.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel