grub-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]