diff options
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | arch/arm/lpc17xx/ldscript | 17 | ||||
| -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 | ||||
| -rw-r--r-- | tools/Makefile | 15 | ||||
| -rw-r--r-- | tools/mkromfs.c | 127 | ||||
| -rw-r--r-- | tools/romfs.txt | 6 | 
14 files changed, 320 insertions, 15 deletions
@@ -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  | 
