mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2 3/5] cdev-alias: add support for storage{.removable,.builtin}
Date: Fri, 12 Dec 2025 17:12:51 +0100	[thread overview]
Message-ID: <20251212161424.1627626-3-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20251212161424.1627626-1-a.fatoum@pengutronix.de>

Our current of global.boot.default expanding to bootsource doesn't work
when booting from flash that only contains the bootloader.

Improve upon this by adding cdev aliases for removable and builtin
storage devices.

Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
  - add Sascha's R-b
  - fix typo in docs and mention slotted SD-card specially (Sascha)
  - extend help text for boot command (Sascha)
  - replace "boot-only flash" in commit message (Sascha)
---
 Documentation/user/booting-linux.rst | 26 +++++++++
 commands/boot.c                      |  3 +
 common/cdev-alias.c                  | 86 ++++++++++++++++++++++++++++
 include/driver.h                     |  5 ++
 4 files changed, 120 insertions(+)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index b164c538c62a..6a41de6712ea 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -182,6 +182,32 @@ and configure the overrides as arguments to the ``boot`` command:
 
   boot -o bootm.image=/mnt/tftp/oftree mmc
 
+Generic Boot Targets
+^^^^^^^^^^^^^^^^^^^^
+
+A single boot target can yield multiple entries, e.g., one for each
+bootloader spec file detected at runtime as described in the next section.
+
+There is also a number of generic default boot targets available, when
+``CONFIG_BOOT_DEFAULTS`` is enabled. These expands to a single device at most:
+
+* ``bootsource``: expands to the device barebox booted from
+* ``diskuuid.*``: expands to the device with specified ``*`` diskuuid
+
+For these targets that expand to a single device, a partition can also be specified,
+e.g., ``bootsource.esp`` to reference the partition with the ``esp`` partition
+label within the bootsource.
+
+Following target can expand to multiple devices:
+
+* ``storage.removable``: expands to removable storage devices,
+  like USB flash drives or SD-Cards in slots
+* ``storage.builtin``: expands to built-in storage devices, like eMMC
+* ``storage``: expands to all of the above ``storage.*``
+
+If the bootsource exists within any of these targets, it will be the first
+device in the returned list.
+
 .. _bootloader_spec:
 
 Boot Loader Specification
diff --git a/commands/boot.c b/commands/boot.c
index 97c574b4a0a3..9cfb7c6b0d5e 100644
--- a/commands/boot.c
+++ b/commands/boot.c
@@ -185,6 +185,9 @@ BAREBOX_CMD_HELP_TEXT("- \"bootchooser\": boot with barebox bootchooser")
 #ifdef CONFIG_BOOT_DEFAULTS
 BAREBOX_CMD_HELP_TEXT("- \"bootsource\": boot from the device barebox has been started from")
 BAREBOX_CMD_HELP_TEXT("- \"diskuuid.*\": boot from disk with specified diskuuid")
+BAREBOX_CMD_HELP_TEXT("- \"storage.removable\": boot from removable media")
+BAREBOX_CMD_HELP_TEXT("- \"storage.builtin\": boot from non-removable media")
+BAREBOX_CMD_HELP_TEXT("- \"storage\": boot from any available media")
 #endif
 BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Multiple bootsources may be given which are probed in order until")
diff --git a/common/cdev-alias.c b/common/cdev-alias.c
index 3732fd90525f..82b91108c1fc 100644
--- a/common/cdev-alias.c
+++ b/common/cdev-alias.c
@@ -9,7 +9,9 @@
 #include <stringlist.h>
 #include <bootsource.h>
 #include <driver.h>
+#include <block.h>
 #include <init.h>
+#include <linux/bits.h>
 
 struct cdev_alias_res {
 	const char *name;
@@ -77,9 +79,93 @@ static int cdev_alias_resolve_diskuuid(struct cdev_alias_res *cdev_alias_res,
 	return ret;
 }
 
+#define STORAGE_REMOVABLE	BIT(0)
+#define STORAGE_BUILTIN		BIT(1)
+
+/**
+ * call_for_each_storage() - invoke callback for each storage medium
+ *
+ * @fn:			callback to invoke
+ * @data:		callback-specific data
+ * @filter:		OR-ed types of STORAGE_* to filter for
+ * @only_bootsource:	If true, include only bootsource if available,
+ *			otherwise omit always
+ * Return:		number of successful callback invocations or a negative error
+ */
+static int call_for_each_storage(cdev_alias_processor_t fn,
+				 void *data,
+				 unsigned filter,
+				 bool only_bootsource)
+{
+	struct cdev *cdev, *bootcdev;
+	int ret, nmatches = 0;
+
+	bootcdev = bootsource_of_cdev_find();
+
+	for_each_cdev(cdev) {
+		struct block_device *bdev;
+
+		if (!cdev_is_storage(cdev) || cdev_is_partition(cdev))
+			continue;
+
+		bdev = cdev_get_block_device(cdev);
+
+		if (((filter & STORAGE_REMOVABLE) && bdev && bdev->removable) ||
+		    ((filter & STORAGE_BUILTIN) && (!bdev || !bdev->removable))) {
+			if (only_bootsource && cdev != bootcdev)
+				continue;
+			if (!only_bootsource && cdev == bootcdev)
+				continue;
+
+			ret = fn(cdev, data);
+			if (ret < 0)
+				return ret;
+			nmatches++;
+
+			/* Got our bootsource, no need to continue iteration */
+			if (only_bootsource)
+				break;
+		}
+	}
+
+	return nmatches;
+}
+
+static int cdev_alias_resolve_storage(struct cdev_alias_res *cdev_alias_res,
+				      const char *class,
+				      cdev_alias_processor_t fn,
+				      void *data)
+{
+	struct cdev *bootcdev;
+	unsigned filter = 0;
+	int bootsource, nmatches;
+
+	if (!class)
+		filter = ~0;
+	else if (streq_ptr(class, "removable"))
+		filter |= STORAGE_REMOVABLE;
+	else if (streq_ptr(class, "builtin"))
+		filter |= STORAGE_BUILTIN;
+	else
+		return -EINVAL;
+
+	bootcdev = bootsource_of_cdev_find();
+
+	bootsource = call_for_each_storage(fn, data, filter, true);
+	if (bootsource < 0)
+		return bootsource;
+
+	nmatches = call_for_each_storage(fn, data, filter, false);
+	if (nmatches < 0)
+		return nmatches;
+
+	return bootsource + nmatches;
+}
+
 static struct cdev_alias_res cdev_alias_aliases[] = {
 	{ "bootsource", cdev_alias_resolve_bootsource },
 	{ "diskuuid", cdev_alias_resolve_diskuuid },
+	{ "storage", cdev_alias_resolve_storage },
 	{ /* sentinel */}
 };
 
diff --git a/include/driver.h b/include/driver.h
index a941ca6127e6..de5a63c379eb 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -597,6 +597,11 @@ get_inheritable_devfs_flags(const struct cdev *parent_cdev)
 	return parent_cdev->flags & DEVFS_INHERITABLE_FLAGS;
 }
 
+static inline bool cdev_is_storage(const struct cdev *cdev)
+{
+	return (cdev->flags & DEVFS_IS_BLOCK_DEV) || cdev->mtd;
+}
+
 struct cdev *
 cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid);
 
-- 
2.47.3




  parent reply	other threads:[~2025-12-12 16:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-12 16:12 [PATCH v2 1/5] cdev-alias: support referencing diskuuid without child partition Ahmad Fatoum
2025-12-12 16:12 ` [PATCH v2 2/5] cdev-alias: fix memory leak in diskuuid handling Ahmad Fatoum
2025-12-12 16:12 ` Ahmad Fatoum [this message]
2025-12-12 16:12 ` [PATCH v2 4/5] boot: try builtin and removable media before net for boot.default Ahmad Fatoum
2025-12-12 16:12 ` [PATCH v2 5/5] boot: assign names to bootentry providers Ahmad Fatoum
2025-12-15  8:15 ` [PATCH v2 1/5] cdev-alias: support referencing diskuuid without child partition Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251212161424.1627626-3-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox