diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-11-04 23:46:12 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-11-04 23:46:12 -0500 |
commit | 2f719330b8afee5075b48d428c836e2c0a3bb14e (patch) | |
tree | da51902d1659383016cec9cbfbab34f2ec9a7826 /src/fs | |
parent | 3a798edb836a30f612b6dd40334b69a2dbeeca22 (diff) |
vfs, initrd
Diffstat (limited to 'src/fs')
-rw-r--r-- | src/fs/Makefile | 22 | ||||
-rw-r--r-- | src/fs/initrd.c | 97 | ||||
-rw-r--r-- | src/fs/initrd.h | 6 |
3 files changed, 125 insertions, 0 deletions
diff --git a/src/fs/Makefile b/src/fs/Makefile new file mode 100644 index 0000000..d22fbf3 --- /dev/null +++ b/src/fs/Makefile @@ -0,0 +1,22 @@ +CFILES = $(wildcard *.c) +AFILES = $(wildcard *.s) +OFILES = $(patsubst %.c, %.o, $(CFILES)) \ + $(patsubst %.s, %.asm.o, $(AFILES)) + +CFLAGS += -I.. -I../arch/cmsis + +all: $(OFILES) + +%.o: %.c + @echo " CC " $< + @$(CROSS)$(CC) $(CFLAGS) -c $< -o $@ + +%.asm.o: %.s + @echo " AS " $< + @$(CROSS)$(AS) $(AFLAGS) -c $< -o $@ + +clean: + @echo " CLEAN" + @rm -f $(OFILES) + + diff --git a/src/fs/initrd.c b/src/fs/initrd.c new file mode 100644 index 0000000..efa430c --- /dev/null +++ b/src/fs/initrd.c @@ -0,0 +1,97 @@ +#include <stdint.h> +#include <string.h> + +#include <kernel/heap.h> +#include <kernel/vfs.h> + +typedef struct { + char *address; + uint32_t pos; + uint32_t size; +} initrd_info; + +extern uint8_t _binary_initrd_img_start[]; +extern uint8_t _binary_initrd_img_size[]; + +static const uint8_t *initrd_start = (uint8_t *)_binary_initrd_img_start; +static const uint32_t initrd_size = (uint32_t)_binary_initrd_img_size; + +void *initrd_open(const char *file); +uint32_t initrd_read(void *info, uint32_t count, uint8_t *buffer); + +char *initrd_getfile(uint32_t offset); + +static const vfs_volume_funcs initrd_funcs = { + initrd_open, + 0, // close + initrd_read, + 0, // write + 0 // readdir +}; + +void initrd_init(void) +{ + vfs_mount(&initrd_funcs, VFS_READONLY); +} + +void *initrd_open(const char *file) +{ + char *ptr; + for (uint32_t i = 0; ptr = initrd_getfile(i), ptr != 0; i++) { + uint32_t len = *((uint32_t *)ptr); + if (!strncmp(file, ptr + 4, len)) { + initrd_info *file = (initrd_info *)malloc( + sizeof(initrd_info)); + file->address = ptr + len + 8; + file->pos = 0; + file->size = *(uint32_t *)(ptr + len + 4); + return file; + } + } + + return 0; +} + +uint32_t initrd_read(void *info, uint32_t count, uint8_t *buffer) +{ + initrd_info *iinfo = (initrd_info *)info; + if (iinfo == 0 || iinfo->address == 0) + return 0; + + uint32_t i; + for (i = 0; i < count; i++) { + if (iinfo->pos >= iinfo->size) + break; + + buffer[iinfo->pos] = iinfo->address[iinfo->pos]; + iinfo->pos++; + } + + return i; +} + +/*char *readfile(const char *name) +{ + char *ptr; + for (uint32_t i = 0; ptr = getfile(i), ptr != 0; i++) { + uint32_t len = *((uint32_t *)ptr); + if (!strncmp(name, ptr + 4, len)) + return ptr + len + 8; + } + return 0; +}*/ + +char *initrd_getfile(uint32_t offset) +{ + char *ptr = (char *)initrd_start; + for (uint32_t i = 0; i < offset; i++) { + uint32_t len = *((uint32_t *)ptr); + uint32_t datalen = *((uint32_t *)(ptr + 4 + len)); + ptr += len + datalen + 8; + if (ptr >= (char *)(initrd_start + initrd_size)) + return 0; + } + + return ptr; +} + diff --git a/src/fs/initrd.h b/src/fs/initrd.h new file mode 100644 index 0000000..dbc0079 --- /dev/null +++ b/src/fs/initrd.h @@ -0,0 +1,6 @@ +#ifndef INTIRD_H_ +#define INITRD_H_ + +void initrd_init(void); + +#endif // INITRD_H_ |