Skip to content

Commit

Permalink
fs: Add semihosting filesystem
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
sean-anderson-seco authored and trini committed Apr 1, 2022
1 parent 8e1c9fe commit f676b45
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 2 deletions.
4 changes: 2 additions & 2 deletions disk/part.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions fs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
20 changes: 20 additions & 0 deletions fs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -247,6 +248,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,
Expand Down
115 changes: 115 additions & 0 deletions fs/semihostingfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022, Sean Anderson <[email protected]>
* 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;
}
1 change: 1 addition & 0 deletions include/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct cmd_tbl;
#define FS_TYPE_BTRFS 5
#define FS_TYPE_SQUASHFS 6
#define FS_TYPE_EROFS 7
#define FS_TYPE_SEMIHOSTING 8

struct blk_desc;

Expand Down
21 changes: 21 additions & 0 deletions include/semihostingfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2022, Sean Anderson <[email protected]>
* 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

0 comments on commit f676b45

Please sign in to comment.