mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
fs: Create functions to load and allocate a file
This functionality current sits in bootstd, but it is more generally useful. Add a function to load a file into memory, allocating it as needed. Adjust bootstd to use this version. Note: Tests are added in the subsequent patch which converts the 'cat' command to use this function. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
5904d953a1
commit
de7b5a8a1a
3 changed files with 98 additions and 28 deletions
|
@ -301,32 +301,6 @@ int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
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", -EIO);
|
||||
buf[size] = '\0';
|
||||
|
||||
*bufp = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
|
||||
{
|
||||
void *buf;
|
||||
|
@ -338,7 +312,7 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
|
|||
if (size > size_limit)
|
||||
return log_msg_ret("chk", -E2BIG);
|
||||
|
||||
ret = alloc_file(bflow->fname, bflow->size, &buf);
|
||||
ret = fs_read_alloc(bflow->fname, bflow->size, align, &buf);
|
||||
if (ret)
|
||||
return log_msg_ret("all", ret);
|
||||
|
||||
|
@ -374,7 +348,7 @@ int bootmeth_alloc_other(struct bootflow *bflow, const char *fname,
|
|||
if (ret)
|
||||
return log_msg_ret("fs", ret);
|
||||
|
||||
ret = alloc_file(path, size, &buf);
|
||||
ret = fs_read_alloc(path, size, 0, &buf);
|
||||
if (ret)
|
||||
return log_msg_ret("all", ret);
|
||||
|
||||
|
|
58
fs/fs.c
58
fs/fs.c
|
@ -13,6 +13,7 @@
|
|||
#include <env.h>
|
||||
#include <lmb.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <mapmem.h>
|
||||
#include <part.h>
|
||||
#include <ext4fs.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <div64.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <efi_loader.h>
|
||||
#include <squashfs.h>
|
||||
#include <erofs.h>
|
||||
|
@ -1008,3 +1010,59 @@ int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
|
|||
puts("\n");
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp)
|
||||
{
|
||||
loff_t bytes_read;
|
||||
ulong addr;
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
buf = memalign(align, 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", -EIO);
|
||||
buf[size] = '\0';
|
||||
|
||||
*bufp = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_load_alloc(const char *ifname, const char *dev_part_str,
|
||||
const char *fname, ulong max_size, ulong align, void **bufp,
|
||||
ulong *sizep)
|
||||
{
|
||||
loff_t size;
|
||||
void *buf;
|
||||
int ret;
|
||||
|
||||
if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
|
||||
return log_msg_ret("set", -ENOMEDIUM);
|
||||
|
||||
ret = fs_size(fname, &size);
|
||||
if (ret)
|
||||
return log_msg_ret("sz", -ENOENT);
|
||||
|
||||
if (size >= (max_size ?: SZ_1G))
|
||||
return log_msg_ret("sz", -E2BIG);
|
||||
|
||||
if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
|
||||
return log_msg_ret("set", -ENOMEDIUM);
|
||||
|
||||
ret = fs_read_alloc(fname, size, align, &buf);
|
||||
if (ret)
|
||||
return log_msg_ret("al", ret);
|
||||
*sizep = size;
|
||||
*bufp = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
38
include/fs.h
38
include/fs.h
|
@ -300,4 +300,42 @@ int do_fs_type(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
|||
*/
|
||||
int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
|
||||
|
||||
/**
|
||||
* fs_read_alloc() - Allocate space for a file and read it
|
||||
*
|
||||
* You must call fs_set_blk_dev() or a similar function before calling this,
|
||||
* since that sets up the block device to use.
|
||||
*
|
||||
* The file is terminated with a nul character
|
||||
*
|
||||
* @fname: Filename to read
|
||||
* @size: Size of file to read (must be correct!)
|
||||
* @align: Alignment to use for memory allocation (0 for default)
|
||||
* @bufp: On success, returns the allocated buffer with the nul-terminated file
|
||||
* in it
|
||||
* Return: 0 if OK, -ENOMEM if out of memory, -EIO if read failed
|
||||
*/
|
||||
int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp);
|
||||
|
||||
/**
|
||||
* fs_load_alloc() - Load a file into allocated space
|
||||
*
|
||||
* The file is terminated with a nul character
|
||||
*
|
||||
* @ifname: Interface name to read from (e.g. "mmc")
|
||||
* @dev_part_str: Device and partition string (e.g. "1:2")
|
||||
* @fname: Filename to read
|
||||
* @max_size: Maximum allowed size for the file (use 0 for 1GB)
|
||||
* @align: Alignment to use for memory allocation (0 for default)
|
||||
* @bufp: On success, returns the allocated buffer with the nul-terminated file
|
||||
* in it
|
||||
* @sizep: On success, returns the size of the file
|
||||
* Return: 0 if OK, -ENOMEM if out of memory, -ENOENT if the file does not
|
||||
* exist, -ENOMEDIUM if the device does not exist, -E2BIG if the file is too
|
||||
* large (greater than @max_size), -EIO if read failed
|
||||
*/
|
||||
int fs_load_alloc(const char *ifname, const char *dev_part_str,
|
||||
const char *fname, ulong max_size, ulong align, void **bufp,
|
||||
ulong *sizep);
|
||||
|
||||
#endif /* _FS_H */
|
||||
|
|
Loading…
Reference in a new issue