diff options
author | Tom Rini <trini@konsulko.com> | 2025-01-15 17:34:26 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-01-15 19:27:14 -0600 |
commit | 178f6ecb21fe12ada74a9a1a08093c812b15eea5 (patch) | |
tree | 60dee6152b33cbd13f311875ce2fc8e9350a8c3d /boot/bootflow.c | |
parent | e26a9ac4c6900cac2fa043ac50a3a3c038f4505d (diff) | |
parent | a3d0fadca6b14f57477a4143334993daf52f89dc (diff) |
Merge patch series "bootstd: Support recording images"
Simon Glass <sjg@chromium.org> says:
This series provides a way to keep track of the images used in bootstd,
including the type of each image.
At present this is sort-of handled by struct bootflow but in quite an
ad-hoc way. The structure has become quite large and is hard to query.
Future work will be able to reduce its size.
Ultimately the 'bootflow info' command may change to also show images as
a list, but that is left for later, as this series is already fairly
long. So for now, just introduce the concept and adjust bootstd to use
it, with a simple command to list the images.
This series includes various alist enhancements, to make use of this new
data structure a little easier.
[trini: Drop patch 18 and 19 for now due to size considerations]
Link: https://lore.kernel.org/r/20241115231926.211999-1-sjg@chromium.org
Diffstat (limited to 'boot/bootflow.c')
-rw-r--r-- | boot/bootflow.c | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/boot/bootflow.c b/boot/bootflow.c index d8807eb109d..58a1afa7a75 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -23,6 +23,13 @@ enum { BF_NO_MORE_DEVICES = -ENODEV, }; +static const char *const bootflow_img[BFI_COUNT - BFI_FIRST] = { + "extlinux_cfg", + "logo", + "efi", + "cmdline", +}; + /** * bootflow_state - name for each state * @@ -55,11 +62,10 @@ int bootflow_first_glob(struct bootflow **bflowp) if (ret) return ret; - if (list_empty(&std->glob_head)) + if (!std->bootflows.count) return -ENOENT; - *bflowp = list_first_entry(&std->glob_head, struct bootflow, - glob_node); + *bflowp = alist_getw(&std->bootflows, 0, struct bootflow); return 0; } @@ -67,20 +73,16 @@ int bootflow_first_glob(struct bootflow **bflowp) int bootflow_next_glob(struct bootflow **bflowp) { struct bootstd_priv *std; - struct bootflow *bflow = *bflowp; int ret; ret = bootstd_get_priv(&std); if (ret) return ret; - *bflowp = NULL; - - if (list_is_last(&bflow->glob_node, &std->glob_head)) + *bflowp = alist_nextw(&std->bootflows, *bflowp); + if (!*bflowp) return -ENOENT; - *bflowp = list_entry(bflow->glob_node.next, struct bootflow, glob_node); - return 0; } @@ -460,10 +462,13 @@ void bootflow_init(struct bootflow *bflow, struct udevice *bootdev, bflow->dev = bootdev; bflow->method = meth; bflow->state = BOOTFLOWST_BASE; + alist_init_struct(&bflow->images, struct bootflow_img); } void bootflow_free(struct bootflow *bflow) { + struct bootflow_img *img; + free(bflow->name); free(bflow->subdir); free(bflow->fname); @@ -472,16 +477,15 @@ void bootflow_free(struct bootflow *bflow) free(bflow->os_name); free(bflow->fdt_fname); free(bflow->bootmeth_priv); + + alist_for_each(img, &bflow->images) + free(img->fname); + alist_empty(&bflow->images); } void bootflow_remove(struct bootflow *bflow) { - if (bflow->dev) - list_del(&bflow->bm_node); - list_del(&bflow->glob_node); - bootflow_free(bflow); - free(bflow); } #if CONFIG_IS_ENABLED(BOOTSTD_FULL) @@ -960,3 +964,48 @@ int bootflow_cmdline_auto(struct bootflow *bflow, const char *arg) return 0; } + +const char *bootflow_img_type_name(enum bootflow_img_t type) +{ + const char *name; + + if (type >= BFI_FIRST && type < BFI_COUNT) + name = bootflow_img[type - BFI_FIRST]; + else + name = genimg_get_type_short_name(type); + + return name; +} + +struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname, + enum bootflow_img_t type, ulong addr, + ulong size) +{ + struct bootflow_img img, *ptr; + + memset(&img, '\0', sizeof(struct bootflow_img)); + img.fname = strdup(fname); + if (!img.fname) + return NULL; + + img.type = type; + img.addr = addr; + img.size = size; + ptr = alist_add(&bflow->images, img); + if (!ptr) + return NULL; + + return ptr; +} + +int bootflow_get_seq(const struct bootflow *bflow) +{ + struct bootstd_priv *std; + int ret; + + ret = bootstd_get_priv(&std); + if (ret) + return ret; + + return alist_calc_index(&std->bootflows, bflow); +} |