aboutsummaryrefslogtreecommitdiffstats
path: root/src/fs/initrd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/initrd.c')
-rw-r--r--src/fs/initrd.c15
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;
}