From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 3/5] cdev-alias: add support for storage{.removable,.builtin}
Date: Thu, 11 Dec 2025 22:00:45 +0100 [thread overview]
Message-ID: <20251211210049.3170349-3-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20251211210049.3170349-1-a.fatoum@pengutronix.de>
Our current of global.boot.default expanding to bootsource doesn't work
when booting from boot-only flash. Improve upon this by adding cdev
aliases for removable and builtin storage devices.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Documentation/user/booting-linux.rst | 25 ++++++++
common/cdev-alias.c | 86 ++++++++++++++++++++++++++++
include/driver.h | 5 ++
3 files changed, 116 insertions(+)
diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index b164c538c62a..f1df5ee2bbf0 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -182,6 +182,31 @@ 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 built-in storage devices, like USB sticks
+* ``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/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
next prev parent reply other threads:[~2025-12-11 21:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-11 21:00 [PATCH 1/5] cdev-alias: support referencing diskuuid without child partition Ahmad Fatoum
2025-12-11 21:00 ` [PATCH 2/5] cdev-alias: fix memory leak in diskuuid handling Ahmad Fatoum
2025-12-11 21:00 ` Ahmad Fatoum [this message]
2025-12-12 8:32 ` [PATCH 3/5] cdev-alias: add support for storage{.removable,.builtin} Sascha Hauer
2025-12-11 21:00 ` [PATCH 4/5] boot: try builtin and removable media before net for boot.default Ahmad Fatoum
2025-12-11 21:00 ` [PATCH 5/5] boot: assign names to bootentry providers Ahmad Fatoum
2025-12-12 8:36 ` [PATCH 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=20251211210049.3170349-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