Add VFS, start of initrd
diff --git a/.gitignore b/.gitignore
index a931712..851dad4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
 *.bin
 *.o
 *.a
-*.so
\ No newline at end of file
+*.so
+compile-commands.json
\ No newline at end of file
diff --git a/include/initrd/initrd.h b/include/initrd/initrd.h
new file mode 100644
index 0000000..69f2bac
--- /dev/null
+++ b/include/initrd/initrd.h
@@ -0,0 +1,15 @@
+#pragma once
+
+struct initrd_global_header
+{
+	unsigned int magic;
+	unsigned long num_files;
+} __attribute__((packed));
+
+struct initrd_file_header
+{
+	char name[64];
+	unsigned long size;
+};
+
+/* that's it! */
diff --git a/src/Makefile b/src/Makefile
index 55265bc..fc7b8e3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,2 +1,7 @@
+all: kernel mkinitrd
+
 kernel:
 	$(MAKE) -C kernel install
+
+mkinitrd:
+	$(MAKE) -C mkinitrd
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 4137f84..3cb20f8 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -13,15 +13,17 @@
 			switch_table.o \
 			scan_codes.o \
 			kheap.o \
-			alloc.o
+			alloc.o \
+			vfs.o
+
+JAYROOT = ../../
 CFLAGS = -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding \
-			-m32 -O2 -g -Wall -Wno-unused-function -Wno-unused-variable
+			-m32 -O2 -g -Wall -Wno-unused-function -Wno-unused-variable \
+			-I$(JAYROOT)/include
 LDFLAGS = -Tlink.ld -melf_i386
 ASMFLAGS = -felf
 QEMUFLAGS = -d cpu_reset
 
-JAYROOT = ../../
-
 kernel.elf: $(SOURCES)
 	ld $(LDFLAGS) -o $@ $^
 
diff --git a/src/kernel/alloc.c b/src/kernel/alloc.c
index bcd58ae..c6e092c 100644
--- a/src/kernel/alloc.c
+++ b/src/kernel/alloc.c
@@ -254,6 +254,8 @@
 		base->size = full_size;
 		base->magic = HEAP_MAGIC;
 		base->allocated = true;
+
+		return mem;
 	}
 	else
 	{
diff --git a/src/kernel/vfs.c b/src/kernel/vfs.c
new file mode 100644
index 0000000..59ccaf5
--- /dev/null
+++ b/src/kernel/vfs.c
@@ -0,0 +1,49 @@
+#include "vfs.h"
+
+uint fs_read(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
+{
+	if (!node || !node->vtable || !node->vtable->read)
+		return 0;
+
+	return node->vtable->read(node, offset, size, buffer);
+}
+
+uint fs_write(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
+{
+	if (!node || !node->vtable || !node->vtable->write)
+		return 0;
+
+	return node->vtable->write(node, offset, size, buffer);
+}
+
+void fs_open(struct fs_node *node)
+{
+	if (!node || !node->vtable || !node->vtable->open)
+		return;
+
+	node->vtable->open(node);
+}
+
+void fs_close(struct fs_node *node)
+{
+	if (!node || !node->vtable || !node->vtable->close)
+		return;
+
+	node->vtable->close(node);
+}
+
+struct fs_dirent *fs_readdir(struct fs_node *node, uint index)
+{
+	if (!node || !node->vtable || !node->vtable->readdir || (node->flags & 7) != FS_DIRECTORY)
+		return NULL;
+
+	return node->vtable->readdir(node, index);
+}
+
+struct fs_node *fs_finddir(struct fs_node *node, char *name)
+{
+	if (!node || !node->vtable || !node->vtable->finddir || (node->flags & 7) != FS_DIRECTORY)
+		return NULL;
+
+	return node->vtable->finddir(node, name);
+}
diff --git a/src/kernel/vfs.h b/src/kernel/vfs.h
new file mode 100644
index 0000000..1c62a80
--- /dev/null
+++ b/src/kernel/vfs.h
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "kint.h"
+
+struct fs_vtable;
+
+struct fs_node
+{
+	char name[128]; /* file name */
+	uint inode;     /* identifier */
+	uint flags;     /* type of node */
+	uint mask;      /* permissions */
+	uint gid;       /* group id */
+	uint uid;       /* user id */
+	size_t size;    /* size in bytes */
+	uint dri_res;   /* reserved for driver */
+
+	struct fs_vtable *vtable;
+
+	struct fs_node *mount; /* used for mounts */
+};
+
+struct fs_dirent
+{
+	char name[128];
+	uint inode;
+};
+
+typedef uint (* fs_read_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef uint (* fs_write_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef void (* fs_open_t)(struct fs_node *node);
+typedef void (* fs_close_t)(struct fs_node *node);
+
+typedef struct fs_dirent *(* fs_readdir_t)(struct fs_node *node, uint index);
+typedef struct fs_node *(* fs_finddir_t)(struct fs_node *node, char *name);
+
+struct fs_vtable
+{
+	fs_read_t read;
+	fs_write_t write;
+	fs_open_t open;
+	fs_close_t close;
+	fs_readdir_t readdir;
+	fs_finddir_t finddir;
+};
+
+enum fs_flags
+{
+	FS_FILE = 1,
+	FS_DIRECTORY,
+	FS_CHARDEVICE,
+	FS_BLOCKDEVICE,
+	FS_PIPE,
+	FS_SYMLINK,
+	
+	FS_MOUNT = 8,   /* Can be or'd with others */
+};
+
+/* Not to be confused normal open, close, etc functions, these operate
+ * on the VFS directly */
+
+uint fs_read(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+uint fs_write(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+void fs_open(struct fs_node *node);
+void fs_close(struct fs_node *node);
+
+struct fs_dirent *fs_readdir(struct fs_node *node, uint index);
+struct fs_node *fs_finddir(struct fs_node *node, char *name);
diff --git a/src/mkinitrd/Makefile b/src/mkinitrd/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/mkinitrd/Makefile
diff --git a/src/mkinitrd/compile_commands.json b/src/mkinitrd/compile_commands.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/src/mkinitrd/compile_commands.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/src/mkinitrd/main.c b/src/mkinitrd/main.c
new file mode 100644
index 0000000..ded5af0
--- /dev/null
+++ b/src/mkinitrd/main.c
@@ -0,0 +1,14 @@
+#include <initrd/initrd.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+	if (argc == 1 || (argc > 1 && !strcmp(argv[1], "-h")))
+	{
+		printf("%s <output> [input...]\n", argv[0]);
+		return argc == 1;
+	}
+
+	FILE *out = fopen(argv[1], "w");
+}