fs: Add semihosting filesystem
This adds a filesystem which is backed by the host's filesystem. It is modeled off of sandboxfs, which has very similar aims. Semihosting doesn't support listing directories (except with SYS_SYSTEM), so neither do we. it's possible to optimize a bit for the common case of reading a whole file by omitting a call to smh_seek, but this is left as a future optimization. Signed-off-by: Sean Anderson <sean.anderson@seco.com>
This commit is contained in:
parent
8e1c9fe243
commit
f676b45151
@ -455,7 +455,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
|
|||||||
int part;
|
int part;
|
||||||
struct disk_partition tmpinfo;
|
struct disk_partition tmpinfo;
|
||||||
|
|
||||||
#ifdef CONFIG_SANDBOX
|
#if IS_ENABLED(CONFIG_SANDBOX) || IS_ENABLED(CONFIG_SEMIHOSTING)
|
||||||
/*
|
/*
|
||||||
* Special-case a pseudo block device "hostfs", to allow access to the
|
* Special-case a pseudo block device "hostfs", to allow access to the
|
||||||
* host's own filesystem.
|
* host's own filesystem.
|
||||||
@ -467,7 +467,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
|
|||||||
info->blksz = 0;
|
info->blksz = 0;
|
||||||
info->bootable = 0;
|
info->bootable = 0;
|
||||||
strcpy((char *)info->type, BOOT_PART_TYPE);
|
strcpy((char *)info->type, BOOT_PART_TYPE);
|
||||||
strcpy((char *)info->name, "Sandbox host");
|
strcpy((char *)info->name, "Host filesystem");
|
||||||
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
|
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
|
||||||
info->uuid[0] = 0;
|
info->uuid[0] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@ obj-$(CONFIG_FS_FAT) += fat/
|
|||||||
obj-$(CONFIG_FS_JFFS2) += jffs2/
|
obj-$(CONFIG_FS_JFFS2) += jffs2/
|
||||||
obj-$(CONFIG_CMD_REISER) += reiserfs/
|
obj-$(CONFIG_CMD_REISER) += reiserfs/
|
||||||
obj-$(CONFIG_SANDBOX) += sandbox/
|
obj-$(CONFIG_SANDBOX) += sandbox/
|
||||||
|
obj-$(CONFIG_SEMIHOSTING) += semihostingfs.o
|
||||||
obj-$(CONFIG_CMD_UBIFS) += ubifs/
|
obj-$(CONFIG_CMD_UBIFS) += ubifs/
|
||||||
obj-$(CONFIG_YAFFS2) += yaffs2/
|
obj-$(CONFIG_YAFFS2) += yaffs2/
|
||||||
obj-$(CONFIG_CMD_ZFS) += zfs/
|
obj-$(CONFIG_CMD_ZFS) += zfs/
|
||||||
|
20
fs/fs.c
20
fs/fs.c
@ -18,6 +18,7 @@
|
|||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <sandboxfs.h>
|
#include <sandboxfs.h>
|
||||||
|
#include <semihostingfs.h>
|
||||||
#include <ubifs_uboot.h>
|
#include <ubifs_uboot.h>
|
||||||
#include <btrfs.h>
|
#include <btrfs.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
@ -247,6 +248,25 @@ static struct fstype_info fstypes[] = {
|
|||||||
.ln = fs_ln_unsupported,
|
.ln = fs_ln_unsupported,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_SEMIHOSTING
|
||||||
|
{
|
||||||
|
.fstype = FS_TYPE_SEMIHOSTING,
|
||||||
|
.name = "semihosting",
|
||||||
|
.null_dev_desc_ok = true,
|
||||||
|
.probe = smh_fs_set_blk_dev,
|
||||||
|
.close = fs_close_unsupported,
|
||||||
|
.ls = fs_ls_unsupported,
|
||||||
|
.exists = fs_exists_unsupported,
|
||||||
|
.size = smh_fs_size,
|
||||||
|
.read = smh_fs_read,
|
||||||
|
.write = smh_fs_write,
|
||||||
|
.uuid = fs_uuid_unsupported,
|
||||||
|
.opendir = fs_opendir_unsupported,
|
||||||
|
.unlink = fs_unlink_unsupported,
|
||||||
|
.mkdir = fs_mkdir_unsupported,
|
||||||
|
.ln = fs_ln_unsupported,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_CMD_UBIFS
|
#ifdef CONFIG_CMD_UBIFS
|
||||||
{
|
{
|
||||||
.fstype = FS_TYPE_UBIFS,
|
.fstype = FS_TYPE_UBIFS,
|
||||||
|
115
fs/semihostingfs.c
Normal file
115
fs/semihostingfs.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022, Sean Anderson <sean.anderson@seco.com>
|
||||||
|
* Copyright (c) 2012, Google Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <os.h>
|
||||||
|
#include <semihosting.h>
|
||||||
|
#include <semihostingfs.h>
|
||||||
|
|
||||||
|
int smh_fs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only accept a NULL struct blk_desc for the semihosting, which is when
|
||||||
|
* hostfs interface is used
|
||||||
|
*/
|
||||||
|
return !!rbdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smh_fs_read_at(const char *filename, loff_t pos, void *buffer,
|
||||||
|
loff_t maxsize, loff_t *actread)
|
||||||
|
{
|
||||||
|
long fd, size, ret;
|
||||||
|
|
||||||
|
fd = smh_open(filename, MODE_READ | MODE_BINARY);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
ret = smh_seek(fd, pos);
|
||||||
|
if (ret < 0) {
|
||||||
|
smh_close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!maxsize) {
|
||||||
|
size = smh_flen(fd);
|
||||||
|
if (ret < 0) {
|
||||||
|
smh_close(fd);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxsize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = smh_read(fd, buffer, maxsize);
|
||||||
|
smh_close(fd);
|
||||||
|
if (size < 0)
|
||||||
|
return size;
|
||||||
|
|
||||||
|
*actread = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smh_fs_write_at(const char *filename, loff_t pos, void *buffer,
|
||||||
|
loff_t towrite, loff_t *actwrite)
|
||||||
|
{
|
||||||
|
long fd, size, ret;
|
||||||
|
|
||||||
|
fd = smh_open(filename, MODE_READ | MODE_BINARY | MODE_PLUS);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
ret = smh_seek(fd, pos);
|
||||||
|
if (ret < 0) {
|
||||||
|
smh_close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = smh_write(fd, buffer, towrite, &size);
|
||||||
|
smh_close(fd);
|
||||||
|
*actwrite = size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smh_fs_size(const char *filename, loff_t *result)
|
||||||
|
{
|
||||||
|
long fd, size;
|
||||||
|
|
||||||
|
fd = smh_open(filename, MODE_READ | MODE_BINARY);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
size = smh_flen(fd);
|
||||||
|
smh_close(fd);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
return size;
|
||||||
|
|
||||||
|
*result = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smh_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
|
||||||
|
loff_t *actread)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = smh_fs_read_at(filename, offset, buf, len, actread);
|
||||||
|
if (ret)
|
||||||
|
printf("** Unable to read file %s **\n", filename);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smh_fs_write(const char *filename, void *buf, loff_t offset,
|
||||||
|
loff_t len, loff_t *actwrite)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = smh_fs_write_at(filename, offset, buf, len, actwrite);
|
||||||
|
if (ret)
|
||||||
|
printf("** Unable to write file %s **\n", filename);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -18,6 +18,7 @@ struct cmd_tbl;
|
|||||||
#define FS_TYPE_BTRFS 5
|
#define FS_TYPE_BTRFS 5
|
||||||
#define FS_TYPE_SQUASHFS 6
|
#define FS_TYPE_SQUASHFS 6
|
||||||
#define FS_TYPE_EROFS 7
|
#define FS_TYPE_EROFS 7
|
||||||
|
#define FS_TYPE_SEMIHOSTING 8
|
||||||
|
|
||||||
struct blk_desc;
|
struct blk_desc;
|
||||||
|
|
||||||
|
21
include/semihostingfs.h
Normal file
21
include/semihostingfs.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022, Sean Anderson <sean.anderson@seco.com>
|
||||||
|
* Copyright (c) 2012, Google Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SEMIHOSTING_FS__
|
||||||
|
#define __SEMIHOSTING_FS__
|
||||||
|
|
||||||
|
struct blk_desc;
|
||||||
|
struct disk_partition;
|
||||||
|
|
||||||
|
int smh_fs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info);
|
||||||
|
void smh_fs_close(void);
|
||||||
|
int smh_fs_size(const char *filename, loff_t *size);
|
||||||
|
int smh_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
|
||||||
|
loff_t *actread);
|
||||||
|
int smh_fs_write(const char *filename, void *buf, loff_t offset,
|
||||||
|
loff_t len, loff_t *actwrite);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user