summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-01-29 18:34:54 -0800
committerPixel <pixel@nobis-crew.org>2011-01-29 18:34:54 -0800
commitea49b5b3f435bce0a301111fad0738efb0b39e0d (patch)
treeaa595cc250514f5225f624d2e691e144c740c567
parent7182d70210f4880e66ae9e5a5531bddd3a90737b (diff)
Adding some romfs support.
-rw-r--r--Makefile9
-rw-r--r--arch/arm/lpc17xx/ldscript17
-rw-r--r--os/Makefile2
-rw-r--r--os/include/fio.h1
-rw-r--r--os/include/romfs.h9
-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
-rw-r--r--tools/Makefile15
-rw-r--r--tools/mkromfs.c127
-rw-r--r--tools/romfs.txt6
14 files changed, 320 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 370bd08..d2b5619 100644
--- a/Makefile
+++ b/Makefile
@@ -6,14 +6,15 @@ export ROOTDIR = $(CURDIR)
include common.mk
-all: libs $(TARGET)
+all: tools libs $(TARGET)
clean: clean-generic
$(Q)$(MAKE) $(MAKE_OPTS) -C FreeRTOS clean
$(Q)$(MAKE) $(MAKE_OPTS) -C arch clean
$(Q)$(MAKE) $(MAKE_OPTS) -C os clean
+ $(Q)$(MAKE) $(MAKE_OPTS) -C tools clean
-.PHONY: libs FreeRTOS arch os
+.PHONY: libs FreeRTOS arch os tools
FreeRTOS/libFreeRTOS.a: FreeRTOS
arch/libarch.a: arch
@@ -33,6 +34,10 @@ os:
$(E) "[MAKE] Entering os"
$(Q)$(MAKE) $(MAKE_OPTS) -C os
+tools:
+ $(E) "[MAKE] Entering tools"
+ $(Q)$(MAKE) $(MAKE_OPTS) -C tools
+
include FreeRTOS/config.mk
include arch/config.mk
include os/config.mk
diff --git a/arch/arm/lpc17xx/ldscript b/arch/arm/lpc17xx/ldscript
index 2468d12..b8ca0b7 100644
--- a/arch/arm/lpc17xx/ldscript
+++ b/arch/arm/lpc17xx/ldscript
@@ -101,30 +101,30 @@ SECTIONS
*(.eh_frame_hdr)
*(.eh_frame)
- . = ALIGN(4);
+ . = ALIGN(16);
KEEP(*(.init))
- . = ALIGN(4);
+ . = ALIGN(16);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
- . = ALIGN(4);
+ . = ALIGN(16);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
- . = ALIGN(0x4);
+ . = ALIGN(16);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
- . = ALIGN(4);
+ . = ALIGN(16);
KEEP(*(.fini))
- . = ALIGN(4);
+ . = ALIGN(16);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
@@ -135,13 +135,16 @@ SECTIONS
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
- . = ALIGN(4);
+ . = ALIGN(16);
__cs3_regions = .;
LONG (0)
LONG (__cs3_region_init_ram)
LONG (__cs3_region_start_ram)
LONG (__cs3_region_init_size_ram)
LONG (__cs3_region_zero_size_ram)
+
+ . = ALIGN(16);
+ *(.romfs.data)
}
/* .ARM.exidx is sorted, so has to go in its own output section. */
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;
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 0000000..65ff73f
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,15 @@
+CC = gcc
+LD = gcc
+CPPFLAGS = -O3
+
+TARGETS = mkromfs
+MKROMFS_SRCS = mkromfs.c
+MKROMFS_OBJS = $(addsuffix .o, $(basename $(MKROMFS_SRCS)))
+
+all: $(TARGETS)
+
+mkromfs: $(MKROMFS_OBJS)
+ $(LD) -o mkromfs $(MKROMFS_OBJS)
+
+clean:
+ rm -rf $(MKROMFS_OBJS) $(TARGETS)
diff --git a/tools/mkromfs.c b/tools/mkromfs.c
new file mode 100644
index 0000000..be46a44
--- /dev/null
+++ b/tools/mkromfs.c
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <string.h>
+
+#define hash_init 5381
+
+uint32_t hash_djb2(const uint8_t * str, uint32_t hash) {
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) ^ c;
+
+ return hash;
+}
+
+void usage(const char * binname) {
+ printf("Usage: %s [-d <dir>] [outfile]\n", binname);
+ exit(-1);
+}
+
+void processdir(DIR * dirp, const char * curpath, FILE * outfile) {
+ char fullpath[1024];
+ char buf[16 * 1024];
+ struct dirent * ent;
+ DIR * rec_dirp;
+ uint32_t cur_hash = hash_djb2(curpath, hash_init);
+ uint32_t size, w, hash;
+ uint8_t b;
+ FILE * infile;
+
+ while ((ent = readdir(dirp))) {
+ strcpy(fullpath, curpath);
+ strcat(fullpath, ent->d_name);
+ switch(ent->d_type) {
+ case DT_DIR:
+ if (strcmp(ent->d_name, ".") == 0)
+ continue;
+ if (strcmp(ent->d_name, "..") == 0)
+ continue;
+ strcat(fullpath, "/");
+ rec_dirp = opendir(fullpath);
+ processdir(rec_dirp, fullpath, outfile);
+ closedir(rec_dirp);
+ break;
+ case DT_REG:
+ case DT_LNK:
+ hash = hash_djb2(ent->d_name, cur_hash);
+ infile = fopen(fullpath, "rb");
+ if (!infile) {
+ perror("opening file");
+ exit(-1);
+ }
+ b = (hash >> 0) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (hash >> 8) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (hash >> 16) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (hash >> 24) & 0xff; fwrite(&b, 1, 1, outfile);
+ fseek(infile, 0, SEEK_END);
+ size = ftell(infile);
+ fseek(infile, 0, SEEK_SET);
+ b = (size >> 0) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (size >> 8) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (size >> 16) & 0xff; fwrite(&b, 1, 1, outfile);
+ b = (size >> 24) & 0xff; fwrite(&b, 1, 1, outfile);
+ while (size) {
+ w = size > 16 * 1024 ? 16 * 1024 : size;
+ fread(buf, 1, w, infile);
+ fwrite(buf, 1, w, outfile);
+ size -= w;
+ }
+ fclose(infile);
+ break;
+ }
+ }
+}
+
+int main(int argc, char ** argv) {
+ char * binname = *argv++;
+ char * o;
+ char * outname = NULL;
+ char * dirname = ".";
+ uint64_t z = 0;
+ FILE * outfile;
+ DIR * dirp;
+
+ while ((o = *argv++)) {
+ if (*o == '-') {
+ o++;
+ switch (*o) {
+ case 'd':
+ dirname = o;
+ break;
+ default:
+ usage(binname);
+ break;
+ }
+ } else {
+ if (outname)
+ usage(binname);
+ outname = o;
+ }
+ }
+
+ if (!outname)
+ outfile = stdout;
+ else
+ outfile = fopen(outname, "wb");
+
+ if (!outfile) {
+ perror("opening file");
+ exit(-1);
+ }
+
+ dirp = opendir(dirname);
+ if (!dirp) {
+ perror("opening directory");
+ exit(-1);
+ }
+
+ processdir(dirp, "", outfile);
+ fwrite(&z, 1, 8, outfile);
+ if (outname)
+ fclose(outfile);
+ closedir(dirp);
+}
diff --git a/tools/romfs.txt b/tools/romfs.txt
new file mode 100644
index 0000000..bf184e5
--- /dev/null
+++ b/tools/romfs.txt
@@ -0,0 +1,6 @@
+Format is excessively simple and short. Read the source for help.
+
+Converting to an object:
+
+$ arm-none-eabi-objcopy -I binary -O elf32-littlearm \
+--prefix-sections '.romfs' --binary-architecture arm my-romfs.bin my-romfs.o