[PATCH v4 18/19] bootstd: Add the concept of an ad-hoc bootflow
Simon Glass
sjg at chromium.org
Sat Nov 16 00:19:25 CET 2024
The normal situation with bootstd is that a bootflow is created from a
bootmeth. In some cases, a script or user-command may cause an image to
be loaded. To deal with this, add the concept of an ad-hoc bootflow.
This can be used to record information about manually loaded images.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v3)
Changes in v3:
- Add a new patch supporting ad-hoc bootflows
boot/bootstd-uclass.c | 44 +++++++++++++++++++++++++++++++++++++++++++
cmd/bootflow.c | 5 +++--
include/bootflow.h | 3 ++-
include/bootstd.h | 19 +++++++++++++++++++
4 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c
index 8c0fd4e63c3..9bee73ead58 100644
--- a/boot/bootstd-uclass.c
+++ b/boot/bootstd-uclass.c
@@ -7,6 +7,8 @@
*/
#include <alist.h>
+#include <blk.h>
+#include <bootdev.h>
#include <bootflow.h>
#include <bootstd.h>
#include <dm.h>
@@ -161,11 +163,53 @@ int bootstd_get_priv(struct bootstd_priv **stdp)
return 0;
}
+int bootstd_img_add(struct blk_desc *desc, int part, const char *fname,
+ enum bootflow_img_t type, ulong addr, ulong size)
+{
+ struct udevice *bootdev = NULL;
+ struct bootstd_priv *std;
+ struct bootflow *bflow, bflow_s;
+ int ret;
+
+ ret = bootstd_get_priv(&std);
+ if (ret)
+ return ret;
+
+ if (desc) {
+ ret = bootdev_get_from_blk(desc->bdev, &bootdev);
+ if (ret)
+ return log_msg_ret("iad", ret);
+ }
+
+ bflow = alist_getw(&std->bootflows, std->adhoc_bflow, struct bootflow);
+ if (!bflow) {
+ bflow = &bflow_s;
+
+ bootflow_init(bflow, bootdev, NULL);
+ bflow->name = strdup("ad-hoc");
+ if (!bflow->name)
+ return log_msg_ret("ian", -ENOMEM);
+ }
+
+ if (!bootflow_img_add(bflow, fname, type, addr, size))
+ return log_msg_ret("iaf", -ENOMEM);
+
+ if (bflow == &bflow_s) {
+ ret = bootstd_add_bootflow(bflow);
+ if (ret < 0)
+ return log_msg_ret("iab", ret);
+ std->adhoc_bflow = ret;
+ }
+
+ return 0;
+}
+
static int bootstd_probe(struct udevice *dev)
{
struct bootstd_priv *std = dev_get_priv(dev);
alist_init_struct(&std->bootflows, struct bootflow);
+ std->adhoc_bflow = -1;
return 0;
}
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index f88995a478f..5668a0c9b19 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -68,7 +68,8 @@ static void report_bootflow_err(struct bootflow *bflow, int err)
static void show_bootflow(int index, struct bootflow *bflow, bool errors)
{
printf("%3x %-11s %-6s %-9.9s %4x %-25.25s %s\n", index,
- bflow->method->name, bootflow_state_get_name(bflow->state),
+ bflow->method ? bflow->method->name : "(none)",
+ bootflow_state_get_name(bflow->state),
bflow->dev ? dev_get_uclass_name(dev_get_parent(bflow->dev)) :
"(none)", bflow->part, bflow->name, bflow->fname ?: "");
if (errors)
@@ -388,7 +389,7 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc,
printf("Name: %s\n", bflow->name);
printf("Device: %s\n", bflow->dev->name);
printf("Block dev: %s\n", bflow->blk ? bflow->blk->name : "(none)");
- printf("Method: %s\n", bflow->method->name);
+ printf("Method: %s\n", bflow->method ? bflow->method->name : "(none)");
printf("State: %s\n", bootflow_state_get_name(bflow->state));
printf("Partition: %d\n", bflow->part);
printf("Subdir: %s\n", bflow->subdir ? bflow->subdir : "(none)");
diff --git a/include/bootflow.h b/include/bootflow.h
index 480cf8a5af1..d9045bc3dae 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -68,7 +68,8 @@ enum bootflow_flags_t {
* @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0.
* For example, the sandbox host-filesystem bootdev sets this to
* FS_TYPE_SANDBOX
- * @method: Bootmethod device used to perform the boot and read files
+ * @method: Bootmethod device used to perform the boot and read files; NULL for
+ * ad-hoc bootflows
* @name: Name of bootflow (allocated)
* @state: Current state (enum bootflow_state_t)
* @subdir: Subdirectory to fetch files from (with trailing /), or NULL if none
diff --git a/include/bootstd.h b/include/bootstd.h
index 3398e48e88b..c39058c0787 100644
--- a/include/bootstd.h
+++ b/include/bootstd.h
@@ -10,10 +10,12 @@
#define __bootstd_h
#include <alist.h>
+#include <bootflow.h>
#include <dm/ofnode_decl.h>
#include <linux/list.h>
#include <linux/types.h>
+struct blk_desc;
struct udevice;
/**
@@ -33,6 +35,7 @@ struct udevice;
* @cur_bootflow: Currently selected bootflow (for commands)
* @bootflows: (struct bootflow) Global list of all bootflows across all
* bootdevs
+ * @adhoc_bflow: Index of ad-hoc bootflow in bootflows (-1 if none)
* @bootmeth_count: Number of bootmeth devices in @bootmeth_order
* @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated
* @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none
@@ -47,6 +50,7 @@ struct bootstd_priv {
struct udevice *cur_bootdev;
struct bootflow *cur_bootflow;
struct alist bootflows;
+ int adhoc_bflow;
int bootmeth_count;
struct udevice **bootmeth_order;
struct udevice *vbe_bootmeth;
@@ -151,4 +155,19 @@ int bootstd_add_bootflow(struct bootflow *bflow);
*/
int bootstd_clear_bootflows_for_bootdev(struct udevice *dev);
+/**
+ * bootstd_img_add() - Add an image to the ad-hoc bootflow
+ *
+ * @desc: Block descriptor for the device from which the file was loaded, or
+ * NULL if not a block device
+ * @part: Partition number within the block device
+ * @fname: Filename of loaded file
+ * @type: File type, IH_TYPE_INVALID if not known
+ * @addr: Address where the file was loaded
+ * @size: Size of the file
+ * Return: 0 if OK, or -ve error code
+ */
+int bootstd_img_add(struct blk_desc *desc, int fs_type, const char *fname,
+ enum bootflow_img_t type, ulong addr, ulong size);
+
#endif
--
2.34.1
More information about the U-Boot
mailing list