diff options
Diffstat (limited to 'src/fs/initrd.c')
-rw-r--r-- | src/fs/initrd.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/fs/initrd.c b/src/fs/initrd.c index de00a4a..efd586c 100644 --- a/src/fs/initrd.c +++ b/src/fs/initrd.c @@ -28,6 +28,7 @@ typedef struct { uint32_t size; } initrd_info; +// Defined by linker script extern uint8_t _binary_initrd_img_start[]; extern uint8_t _binary_initrd_img_size[]; @@ -39,6 +40,10 @@ uint32_t initrd_read(vfs_file_info *info, uint32_t count, uint8_t *buffer); int initrd_close(vfs_file_info *info); int initrd_seek(vfs_file_info *info, uint32_t offset, int whence); +/** + * Gets the start of the offset-th file in the initrd. + * @return Pointer to the file, NULL otherwise + */ char *initrd_getfile(uint32_t offset); static const vfs_volume_funcs initrd_funcs = { @@ -50,6 +55,9 @@ static const vfs_volume_funcs initrd_funcs = { initrd_seek }; +/** + * Custom strncmp() implementation used by this driver. + */ int initrd_strncmp(const char *a, const char *b, unsigned int n) { for (unsigned int i = 0; i < n; i++) { @@ -67,10 +75,12 @@ void initrd_init(void) void *initrd_open(const char *file) { + // Iterate through all files in the initrd char *ptr; for (uint32_t i = 0; ptr = initrd_getfile(i), ptr != 0; i++) { uint32_t len = *((uint32_t *)ptr); if (!initrd_strncmp(file, ptr + 4, len)) { + // If we found our file, create an info structure and return it initrd_info *file = (initrd_info *)malloc( sizeof(initrd_info)); file->address = ptr + len + 8; @@ -84,17 +94,18 @@ void *initrd_open(const char *file) int initrd_close(vfs_file_info *info) { - // Nothing to do free(info->fsinfo); return 0; } uint32_t initrd_read(vfs_file_info *info, uint32_t count, uint8_t *buffer) { + // Confirm this is a valid file initrd_info *iinfo = (initrd_info *)info->fsinfo; if (iinfo == 0 || iinfo->address == 0) return 0; + // Attempt to read 'count' bytes, breaking if we reach the end of the file uint32_t i; for (i = 0; i < count; i++) { if (info->pos >= iinfo->size) @@ -129,9 +140,11 @@ char *initrd_getfile(uint32_t offset) { char *ptr = (char *)initrd_start; for (uint32_t i = 0; i < offset; i++) { + // Move to the next file 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; } |