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>
This commit is contained in:
parent
2175e76a51
commit
24d8e1b37b
6 changed files with 95 additions and 13 deletions
|
@ -290,11 +290,35 @@ 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;
|
||||
int ret;
|
||||
|
||||
buf = malloc(size + 1);
|
||||
if (!buf)
|
||||
return log_msg_ret("buf", -ENOMEM);
|
||||
addr = map_to_sysmem(buf);
|
||||
|
||||
ret = fs_read(fname, addr, 0, size, &bytes_read);
|
||||
if (ret) {
|
||||
free(buf);
|
||||
return log_msg_ret("read", ret);
|
||||
}
|
||||
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;
|
||||
|
||||
|
@ -303,25 +327,52 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
|
|||
if (size > size_limit)
|
||||
return log_msg_ret("chk", -E2BIG);
|
||||
|
||||
buf = memalign(align, size + 1);
|
||||
if (!buf)
|
||||
return log_msg_ret("buf", -ENOMEM);
|
||||
addr = map_to_sysmem(buf);
|
||||
ret = alloc_file(bflow->fname, bflow->size, &buf);
|
||||
if (ret)
|
||||
return log_msg_ret("all", ret);
|
||||
|
||||
ret = fs_read(bflow->fname, addr, 0, 0, &bytes_read);
|
||||
if (ret) {
|
||||
free(buf);
|
||||
return log_msg_ret("read", ret);
|
||||
}
|
||||
if (size != bytes_read)
|
||||
return log_msg_ret("bread", -EINVAL);
|
||||
buf[size] = '\0';
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -265,6 +265,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
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue