Hi Sascha,

On 2025-11-17 09:35, Sascha Hauer wrote:
Most SoCs have a unique ID (UID) which can be used to identify a
particular SoC instance. This is exposed to the environment by some SoC
drivers as soc0.serial_number like also done in Linux. The SoC UID can
also conveniently be used to generate a unique machine_id on systems
with a readonly rootfs. The two usecases require the SoC UID in different
formats. While machine_id_set_hashable() takes a binary representation
of the SoC UID, soc0.serial_number is a string. The conversion from the
binary representation to the string is SoC specific, some SoCs interpret
the binary data as a byte array (AM62x for example), others interpret it
as words of different lengths in different endianesses (i.MX). Others
even print the binary data as decimal (qcom).

Needing a SoC driver for providing the SoC UID is an unlucky choice as
some SoCs do not have a SoC driver, but instead read the SoC UID in
their eFuse driver in drivers/nvmem (STM32MP bsec). These drivers
provide hashable data to generate a machine_id, but do not expose the
SoC ID.

This patch introduces barebox_set_soc_uid(). This function provides a
new environment variable global.soc_uid which contains the SoC UID.
It also passes the SoC UID to machine_id_set_hashable() for generating a
machine_id. To accomodate for different string representations of the
binary data barebox_set_soc_uid() takes both the binary data and a
string in the SoCs preferred format of the same data.

Signed-off-by: Sascha Hauer <[email protected]>

I wonder if soc_uid is really the global variable we are looking for. I
understand what we want is a hardware-provided unique ID of a board.
However boards can have multiple or no SoC UIDs.

I assume a board with multiple SoCs can have a soc1.serial_number too,
then having all UIDs provided via the serial_number interface but only a
single soc_uid global seems confusing to me.

A SoC or SoM that provides no SoC UID may still provide means of unique
hardware identification and the global we are introducing here could
allow us to abstract away from this.

Can we name this something like hardware_uid to be more flexible about
its origin?

---
  common/misc.c          | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
  include/barebox-info.h |  4 ++++
  2 files changed, 62 insertions(+)

diff --git a/common/misc.c b/common/misc.c
index 
0af5a9cf30cdb952063974969c368061420a6e2b..ef6687f01389beaed44fc446b25ec5f21e712366
 100644
--- a/common/misc.c
+++ b/common/misc.c
@@ -16,6 +16,7 @@
  #include <restart.h>
  #include <poweroff.h>
  #include <string.h>
+#include <machine_id.h>
  #include <linux/stringify.h>
int errno;
@@ -252,6 +253,63 @@ const char *barebox_get_serial_number(void)
BAREBOX_MAGICVAR(global.serial_number, "Board serial number"); +static char *soc_uid_str;
+static void *soc_uid;
+static size_t soc_uid_len;
+
+/*
+ * barebox_set_soc_uid - set a Unique SoC ID
+ *
+ * Set a Unique SoC ID. The ID is usually read from SoC internal eFuses. It

"The UID" please

+ * can vary in length on different SoCs and can have different canonical hex
+ * representations. @uidstr can be NULL in which case uidbuf is interpreted
+ * as a byte array.
+ *
+ * barebox uses the SoC ID to generate a machine_id and exports it to the

SoC UID

+ * environment via global.soc_uid.
+ *
+ * In Linux the serial number is exported as /sys/devices/soc0/serial_number

"In Linux, the SoC UID is exported as /sys/devices/soc0/serial_number"?

+ * which should generally have the same format as *uidstr.
+ */
+void barebox_set_soc_uid(const char *uidstr, const void *uidbuf, size_t len)
+{
+       if (soc_uid_str) {
+               pr_warn("SoC UID already set. Ignoring\n");
+               return;
+       }
+
+       soc_uid = xmemdup(uidbuf, len);
+       soc_uid_len = len;
+
+       if (uidstr) {
+               soc_uid_str = xstrdup(uidstr);
+       } else {
+               soc_uid_str = xzalloc(len * 2 + 1);
+               bin2hex(soc_uid_str, uidbuf, len);
+       }
+
+       machine_id_set_hashable(uidbuf, len);
+
+       globalvar_add_simple_string("soc_uid", &soc_uid_str);
+}
+BAREBOX_MAGICVAR(global.soc_uid, "SoC Unique ID");
+
+const char *barebox_get_soc_uid(void)
+{
+       return soc_uid_str;
+}
+
+int barebox_get_soc_uid_bin(const void **buf, size_t *len)
+{
+       if (!soc_uid)
+               return -ENOENT;
+
+       *buf = soc_uid;
+       *len = soc_uid_len;
+
+       return 0;
+}
+
  #ifdef CONFIG_OFTREE
  static char *of_machine_compatible;
diff --git a/include/barebox-info.h b/include/barebox-info.h
index 
bcceb7b0e0211c8c7dccd6b9f480c9fbc13dcf63..898fb493b6348ee64670f928a3598a7c3d277554
 100644
--- a/include/barebox-info.h
+++ b/include/barebox-info.h
@@ -25,6 +25,10 @@ bool barebox_hostname_is_valid(const char *s);
  const char *barebox_get_serial_number(void);
  void barebox_set_serial_number(const char *);
+void barebox_set_soc_uid(const char *uidstr, const void *uidbuf, size_t len);
+const char *barebox_get_soc_uid(void);
+int barebox_get_soc_uid_bin(const void **buf, size_t *len);
+
  #ifdef CONFIG_OFTREE
  void barebox_set_of_machine_compatible(const char *);
  const char *barebox_get_of_machine_compatible(void);


Regards,
Jonas

--
Pengutronix e.K.                           | Jonas Rebmann               |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9    |

Reply via email to