summaryrefslogtreecommitdiff
path: root/os/src
diff options
context:
space:
mode:
Diffstat (limited to 'os/src')
-rw-r--r--os/src/fio.c5
-rw-r--r--os/src/fread.c5
-rw-r--r--os/src/lseek.c22
-rw-r--r--os/src/read.c21
-rw-r--r--os/src/romfs.c94
-rw-r--r--os/src/write.c2
6 files changed, 143 insertions, 6 deletions
diff --git a/os/src/fio.c b/os/src/fio.c
index b7e225a..9fe5038 100644
--- a/os/src/fio.c
+++ b/os/src/fio.c
@@ -146,6 +146,11 @@ int fio_close(int fd) {
return r;
}
+void fio_set_opaque(int fd, void * opaque) {
+ if (fio_is_open_int(fd))
+ fio_fds[fd].opaque = opaque;
+}
+
#define stdin_hash 0x0BA00421
#define stdout_hash 0x7FA08308
#define stderr_hash 0x7FA058A3
diff --git a/os/src/fread.c b/os/src/fread.c
new file mode 100644
index 0000000..b003d33
--- /dev/null
+++ b/os/src/fread.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+size_t fread(void * ptr, size_t size, size_t nmemb, FILE * file) {
+ return _fread_r(_impure_ptr, ptr, size, nmemb, file);
+}
diff --git a/os/src/lseek.c b/os/src/lseek.c
index fdd0b94..1cb0234 100644
--- a/os/src/lseek.c
+++ b/os/src/lseek.c
@@ -1,7 +1,25 @@
#include <reent.h>
#include <osdebug.h>
+#include <errno.h>
+#include "fio.h"
_off_t _lseek_r(struct _reent * reent, int fd, _off_t seek, int wheel) {
- DBGOUT("_lseek_r(%p, %d, %d, %d)\r\n", reent, fd, (int) seek, wheel);
- return 0;
+ off_t r;
+
+ if ((wheel != SEEK_SET) && (wheel != SEEK_CUR) && (wheel != SEEK_END)) {
+ reent->_errno = EINVAL;
+ return -1;
+ }
+
+ if (!fio_is_open(fd)) {
+ reent->_errno = EBADF;
+ return -1;
+ }
+
+ r = fio_seek(fd, seek, wheel);
+
+ if (r < 0)
+ reent->_errno = EINVAL;
+
+ return r;
}
diff --git a/os/src/read.c b/os/src/read.c
index 4850c9c..f848812 100644
--- a/os/src/read.c
+++ b/os/src/read.c
@@ -1,7 +1,22 @@
#include <reent.h>
#include <osdebug.h>
+#include <errno.h>
+#include "fio.h"
-_ssize_t _read_r(struct _reent * reent, int fd, void * ptr, size_t size) {
- DBGOUT("_read_r(%p, %d, %p, %u)\r\n", reent, fd, ptr, size);
- return 0;
+_ssize_t _read_r(struct _reent * reent, int fd, void * buf, size_t size) {
+ _ssize_t r;
+
+ if (!fio_is_open(fd)) {
+ reent->_errno = EBADF;
+ return -1;
+ }
+
+ r = fio_read(fd, buf, size);
+
+ if (r < 0) {
+ reent->_errno = EINVAL;
+ return -1;
+ }
+
+ return r;
}
diff --git a/os/src/romfs.c b/os/src/romfs.c
new file mode 100644
index 0000000..403bef9
--- /dev/null
+++ b/os/src/romfs.c
@@ -0,0 +1,94 @@
+#include <string.h>
+#include <FreeRTOS.h>
+#include <semphr.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "fio.h"
+#include "filesystem.h"
+#include "romfs.h"
+#include "osdebug.h"
+#include "hash-djb2.h"
+
+struct romfs_fds_t {
+ const uint8_t * file;
+ uint32_t cursor;
+};
+
+static struct romfs_fds_t romfs_fds[MAX_FDS];
+
+static uint32_t get_unaligned(const uint32_t * _d) {
+ const uint8_t * d = (const uint8_t *) _d;
+ return ((uint32_t) d[0]) | ((uint32_t) (d[1] << 8)) | ((uint32_t) (d[2] << 16)) | ((uint32_t) (d[3] << 24));
+}
+
+static ssize_t romfs_read(void * opaque, void * buf, size_t count) {
+ struct romfs_fds_t * f = (struct romfs_fds_t *) opaque;
+ const uint8_t * size_p = f->file - 4;
+ uint32_t size = get_unaligned((uint32_t *) size_p);
+
+ if ((f->cursor + count) > size)
+ count = size - f->cursor;
+
+ memcpy(buf, f->file + f->cursor, count);
+ f->cursor += count;
+
+ return count;
+}
+
+static off_t romfs_seek(void * opaque, off_t offset, int whence) {
+ struct romfs_fds_t * f = (struct romfs_fds_t *) opaque;
+ const uint8_t * size_p = f->file - 4;
+ uint32_t size = get_unaligned((uint32_t *) size_p);
+ uint32_t origin;
+
+ switch (whence) {
+ case SEEK_SET:
+ origin = 0;
+ break;
+ case SEEK_CUR:
+ origin = f->cursor;
+ break;
+ case SEEK_END:
+ origin = size;
+ break;
+ default:
+ return -1;
+ }
+
+ offset = origin + offset;
+
+ if (offset < 0)
+ return -1;
+ if (offset > size)
+ offset = size;
+
+ f->cursor = offset;
+
+ return offset;
+}
+
+static int romfs_open(void * opaque, const char * path, int flags, int mode) {
+ uint32_t h = hash_djb2((const uint8_t *) path, -1);
+ const uint8_t * romfs = (const uint8_t *) opaque;
+ const uint32_t * meta;
+ int r = -1;
+
+ for (meta = (uint32_t *) romfs; get_unaligned(meta) && get_unaligned(meta + 1); romfs = romfs + meta[1], meta = (uint32_t *) romfs) {
+ if (meta[0] == h) {
+ r = fio_open(romfs_read, NULL, romfs_seek, NULL, NULL);
+ if (r > 0) {
+ romfs_fds[r].file = romfs + 8;
+ romfs_fds[r].cursor = 0;
+ fio_set_opaque(r, romfs_fds + r);
+ }
+ break;
+ }
+ }
+ return r;
+}
+
+void register_romfs(const char * mountpoint, const uint8_t * romfs) {
+ register_fs(mountpoint, romfs_open, (void *) romfs);
+}
diff --git a/os/src/write.c b/os/src/write.c
index 268c0f1..14e26d6 100644
--- a/os/src/write.c
+++ b/os/src/write.c
@@ -4,7 +4,7 @@
#include "fio.h"
_ssize_t _write_r(struct _reent * reent, int fd, const void * buf, size_t size) {
- int r;
+ _ssize_t r;
if (!fio_is_open(fd)) {
reent->_errno = EBADF;