[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/2] fdtdump: add optional node argument to access nested propert
From: |
Tobias Heider |
Subject: |
[PATCH 2/2] fdtdump: add optional node argument to access nested properties |
Date: |
Thu, 8 Aug 2024 17:37:47 +0200 |
From: Tobias Heider <me@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.heider@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