diff options
author | Pixel <pixel@nobis-crew.org> | 2011-01-29 18:34:54 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2011-01-29 18:34:54 -0800 |
commit | ea49b5b3f435bce0a301111fad0738efb0b39e0d (patch) | |
tree | aa595cc250514f5225f624d2e691e144c740c567 /os | |
parent | 7182d70210f4880e66ae9e5a5531bddd3a90737b (diff) |
Adding some romfs support.
Diffstat (limited to 'os')
-rw-r--r-- | os/Makefile | 2 | ||||
-rw-r--r-- | os/include/fio.h | 1 | ||||
-rw-r--r-- | os/include/romfs.h | 9 | ||||
-rw-r--r-- | os/src/fio.c | 5 | ||||
-rw-r--r-- | os/src/fread.c | 5 | ||||
-rw-r--r-- | os/src/lseek.c | 22 | ||||
-rw-r--r-- | os/src/read.c | 21 | ||||
-rw-r--r-- | os/src/romfs.c | 94 | ||||
-rw-r--r-- | os/src/write.c | 2 |
9 files changed, 155 insertions, 6 deletions
diff --git a/os/Makefile b/os/Makefile index 75bc575..cfc6e33 100644 --- a/os/Makefile +++ b/os/Makefile @@ -14,6 +14,7 @@ src/filesystem.c \ src/fio.c \ src/hash-djb2.c \ src/osdebug.c \ +src/romfs.c \ \ src/close.c \ src/fstat.c \ @@ -28,6 +29,7 @@ src/fclose.c \ src/fflush.c \ src/fopen.c \ src/fprintf.c \ +src/fread.c \ src/free.c \ src/fwrite.c \ src/malloc.c \ diff --git a/os/include/fio.h b/os/include/fio.h index e4ba659..c57b293 100644 --- a/os/include/fio.h +++ b/os/include/fio.h @@ -24,6 +24,7 @@ ssize_t fio_read(int fd, void * buf, size_t count); ssize_t fio_write(int fd, const void * buf, size_t count); off_t fio_seek(int fd, off_t offset, int whence); int fio_close(int fd); +void fio_set_opaque(int fd, void * opaque); void register_devfs(); diff --git a/os/include/romfs.h b/os/include/romfs.h new file mode 100644 index 0000000..b227baa --- /dev/null +++ b/os/include/romfs.h @@ -0,0 +1,9 @@ +#ifndef __ROMFS_H__ +#define __ROMFS_H__ + +#include <stdint.h> + +void register_romfs(const char * mountpoint, const uint8_t * romfs); + +#endif + 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; |