summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-01-06 17:52:34 +0300
committerTom Rini <trini@konsulko.com>2023-01-17 02:26:50 +0300
commit24d8e1b37b90760a6c9867f37210aa4b1f2e8f63 (patch)
treec9193497e5ac61483354472520a01f872f0cb2f3
parent2175e76a51e53798ee4e19903b368a7e6c98356a (diff)
downloadu-boot-24d8e1b37b90760a6c9867f37210aa4b1f2e8f63.tar.xz
bootstd: Allow reading a logo for the OS
Some operating systems provide a logo in bmp format. Read this in if present so it can be displayed in the menu. Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r--boot/bootmeth-uclass.c69
-rw-r--r--boot/bootmeth_script.c4
-rw-r--r--cmd/bootflow.c6
-rw-r--r--include/bootflow.h4
-rw-r--r--include/bootmeth.h16
-rw-r--r--test/boot/bootflow.c1
6 files changed, 91 insertions, 9 deletions
diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c
index 25552dd96f..4c3529d155 100644
--- a/boot/bootmeth-uclass.c
+++ b/boot/bootmeth-uclass.c
@@ -290,25 +290,19 @@ int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc,
return 0;
}
-int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
+static int alloc_file(const char *fname, uint size, void **bufp)
{
loff_t bytes_read;
ulong addr;
char *buf;
- uint size;
int ret;
- size = bflow->size;
- log_debug(" - script file size %x\n", size);
- if (size > size_limit)
- return log_msg_ret("chk", -E2BIG);
-
- buf = memalign(align, size + 1);
+ buf = malloc(size + 1);
if (!buf)
return log_msg_ret("buf", -ENOMEM);
addr = map_to_sysmem(buf);
- ret = fs_read(bflow->fname, addr, 0, 0, &bytes_read);
+ ret = fs_read(fname, addr, 0, size, &bytes_read);
if (ret) {
free(buf);
return log_msg_ret("read", ret);
@@ -316,12 +310,69 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
if (size != bytes_read)
return log_msg_ret("bread", -EINVAL);
buf[size] = '\0';
+
+ *bufp = buf;
+
+ return 0;
+}
+
+int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
+{
+ void *buf;
+ uint size;
+ int ret;
+
+ size = bflow->size;
+ log_debug(" - script file size %x\n", size);
+ if (size > size_limit)
+ return log_msg_ret("chk", -E2BIG);
+
+ ret = alloc_file(bflow->fname, bflow->size, &buf);
+ if (ret)
+ return log_msg_ret("all", ret);
+
bflow->state = BOOTFLOWST_READY;
bflow->buf = buf;
return 0;
}
+int bootmeth_alloc_other(struct bootflow *bflow, const char *fname,
+ void **bufp, uint *sizep)
+{
+ struct blk_desc *desc = NULL;
+ char path[200];
+ loff_t size;
+ void *buf;
+ int ret;
+
+ snprintf(path, sizeof(path), "%s%s", bflow->subdir, fname);
+ log_debug("trying: %s\n", path);
+
+ if (bflow->blk)
+ desc = dev_get_uclass_plat(bflow->blk);
+
+ ret = setup_fs(bflow, desc);
+ if (ret)
+ return log_msg_ret("fs", ret);
+
+ ret = fs_size(path, &size);
+ log_debug(" %s - err=%d\n", path, ret);
+
+ ret = setup_fs(bflow, desc);
+ if (ret)
+ return log_msg_ret("fs", ret);
+
+ ret = alloc_file(path, size, &buf);
+ if (ret)
+ return log_msg_ret("all", ret);
+
+ *bufp = buf;
+ *sizep = size;
+
+ return 0;
+}
+
int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow,
const char *file_path, ulong addr, ulong *sizep)
{
diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c
index ba8e5d0438..c7061eb998 100644
--- a/boot/bootmeth_script.c
+++ b/boot/bootmeth_script.c
@@ -109,6 +109,10 @@ static int script_read_bootflow(struct udevice *dev, struct bootflow *bflow)
if (ret)
return log_msg_ret("inf", ret);
+ ret = bootmeth_alloc_other(bflow, "boot.bmp", &bflow->logo,
+ &bflow->logo_size);
+ /* ignore error */
+
return 0;
}
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 6b8ac8c850..495ef85f25 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -338,6 +338,12 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc,
printf("Buffer: %lx\n", (ulong)map_to_sysmem(bflow->buf));
printf("Size: %x (%d bytes)\n", bflow->size, bflow->size);
printf("OS: %s\n", bflow->os_name ? bflow->os_name : "(none)");
+ printf("Logo: %s\n", bflow->logo ?
+ simple_xtoa((ulong)map_to_sysmem(bflow->logo)) : "(none)");
+ if (bflow->logo) {
+ printf("Logo size: %x (%d bytes)\n", bflow->logo_size,
+ bflow->logo_size);
+ }
printf("Error: %d\n", bflow->err);
if (dump && bflow->buf) {
/* Set some sort of maximum on the size */
diff --git a/include/bootflow.h b/include/bootflow.h
index 776158c65d..8a07ab3019 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -49,6 +49,8 @@ enum bootflow_state_t {
* @state: Current state (enum bootflow_state_t)
* @subdir: Subdirectory to fetch files from (with trailing /), or NULL if none
* @fname: Filename of bootflow file (allocated)
+ * @logo: Logo to display for this bootflow (BMP format)
+ * @logo_size: Size of the logo in bytes
* @buf: Bootflow file contents (allocated)
* @size: Size of bootflow file in bytes
* @err: Error number received (0 if OK)
@@ -67,6 +69,8 @@ struct bootflow {
enum bootflow_state_t state;
char *subdir;
char *fname;
+ void *logo;
+ uint logo_size;
char *buf;
int size;
int err;
diff --git a/include/bootmeth.h b/include/bootmeth.h
index 50ded055f3..669b14ce81 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -266,6 +266,22 @@ int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc,
int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align);
/**
+ * bootmeth_alloc_other() - Allocate and read a file for a bootflow
+ *
+ * This reads an arbitrary file in the same directory as the bootflow,
+ * allocating memory for it. The buffer is one byte larger than the file length,
+ * so that it can be nul-terminated.
+ *
+ * @bflow: Information about file to read
+ * @fname: Filename to read from (within bootflow->subdir)
+ * @bufp: Returns a pointer to the allocated buffer
+ * @sizep: Returns the size of the buffer
+ * Return: 0 if OK, -ENOMEM if out of memory, other -ve on other error
+ */
+int bootmeth_alloc_other(struct bootflow *bflow, const char *fname,
+ void **bufp, uint *sizep);
+
+/**
* bootmeth_common_read_file() - Common handler for reading a file
*
* Reads a named file from the same location as the bootflow file.
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 3296316cf0..00dfd99068 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -189,6 +189,7 @@ static int bootflow_cmd_info(struct unit_test_state *uts)
ut_assert_nextlinen("Buffer: ");
ut_assert_nextline("Size: 253 (595 bytes)");
ut_assert_nextline("OS: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)");
+ ut_assert_nextline("Logo: (none)");
ut_assert_nextline("Error: 0");
ut_assert_console_end();