[PATCH v2 12/28] fs: Add semihosting filesystem
Sean Anderson
sean.anderson at seco.com
Thu Mar 10 21:50:42 CET 2022
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 at seco.com>
---
(no changes since v1)
disk/part.c | 4 +-
fs/Makefile | 1 +
fs/fs.c | 20 +++++++
fs/semihostingfs.c | 115 ++++++++++++++++++++++++++++++++++++++++
include/fs.h | 1 +
include/semihostingfs.h | 21 ++++++++
6 files changed, 160 insertions(+), 2 deletions(-)
create mode 100644 fs/semihostingfs.c
create mode 100644 include/semihostingfs.h
diff --git a/disk/part.c b/disk/part.c
index 49e39a24e8..b95405bb49 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -455,7 +455,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
int part;
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
* 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->bootable = 0;
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)
info->uuid[0] = 0;
#endif
diff --git a/fs/Makefile b/fs/Makefile
index 937cbcf6e8..c25d022946 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_FS_FAT) += fat/
obj-$(CONFIG_FS_JFFS2) += jffs2/
obj-$(CONFIG_CMD_REISER) += reiserfs/
obj-$(CONFIG_SANDBOX) += sandbox/
+obj-$(CONFIG_SEMIHOSTING) += semihostingfs.o
obj-$(CONFIG_CMD_UBIFS) += ubifs/
obj-$(CONFIG_YAFFS2) += yaffs2/
obj-$(CONFIG_CMD_ZFS) += zfs/
diff --git a/fs/fs.c b/fs/fs.c
index 023f89cafe..bba010ea99 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -18,6 +18,7 @@
#include <fat.h>
#include <fs.h>
#include <sandboxfs.h>
+#include <semihostingfs.h>
#include <ubifs_uboot.h>
#include <btrfs.h>
#include <asm/global_data.h>
@@ -246,6 +247,25 @@ static struct fstype_info fstypes[] = {
.ln = fs_ln_unsupported,
},
#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
{
.fstype = FS_TYPE_UBIFS,
diff --git a/fs/semihostingfs.c b/fs/semihostingfs.c
new file mode 100644
index 0000000000..96eb3349a2
--- /dev/null
+++ b/fs/semihostingfs.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022, Sean Anderson <sean.anderson at 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;
+}
diff --git a/include/fs.h b/include/fs.h
index c8df3886ac..2f631624b5 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -17,6 +17,7 @@ struct cmd_tbl;
#define FS_TYPE_UBIFS 4
#define FS_TYPE_BTRFS 5
#define FS_TYPE_SQUASHFS 6
+#define FS_TYPE_SEMIHOSTING 7
struct blk_desc;
diff --git a/include/semihostingfs.h b/include/semihostingfs.h
new file mode 100644
index 0000000000..25ebdbbeff
--- /dev/null
+++ b/include/semihostingfs.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022, Sean Anderson <sean.anderson at 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
--
2.25.1
More information about the U-Boot
mailing list