Add EXT2 stub
diff --git a/include/kernel/dri/fs/ext2/ext2.h b/include/kernel/dri/fs/ext2/ext2.h
new file mode 100644
index 0000000..a94fb77
--- /dev/null
+++ b/include/kernel/dri/fs/ext2/ext2.h
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <vfs.h>
+
+struct ext2_superblock
+{
+	// Total number of inodes
+	uint total_inodes;
+	// Total number of blocks
+	uint total_blocks;
+	// Number of blocks reserved for superuser
+	uint blocks_reserved_for_superuser;
+	// Number of unallocated blocks
+	uint unallocated_blocks;
+	// Number of unallocated inodes
+	uint unallocated_inodes;
+	// Block number containing the superblock
+	uint superblock_block_number;
+	// the number to shift 1024 to the left by to get the block size
+	uint block_size_shift;
+	// the number to shift 1024 to the left by to get the fragment size
+	uint fragment_size_shift;
+	// Number of blocks in one block group
+	uint blocks_per_block_group;
+	// Number of fragments in one block group
+	uint fragments_per_block_group;
+	// Number of inodse in one block group
+	uint inodes_per_block_group;
+	// UNIX time of last mount
+	uint last_mount_time;
+	// UNIX time of last write
+	uint last_write_time;
+	// Number of mounts since last consistency check
+	ushort mounts_since_last_fsck;
+	// Number of mounts allowed between consistency checks
+	ushort mounts_allowed_before_fsck;
+	// EXT2 signature, should be 0xef53
+	ushort signature;
+	// File system state, see enum ext2_fs_state
+	ushort state;
+	// What to do in case of an error, see enum ext2_error_case
+	ushort error_case;
+	// Minor portion of version
+	ushort version_minor;
+	// UNIX time of last consistency check
+	uint last_fsck_time;
+	// Max time between consistency checks
+	uint fsck_time_interval;
+	// Operating system ID of creator
+	uint creator_os_id;
+	// Major portion of version
+	uint version_major;
+	// User ID that can use reserved blocks
+	ushort reserved_blocks_uid;
+	// Group ID that can use reserved blocks
+	ushort reserved_blocks_gid;
+};
+
+enum ext2_fs_state
+{
+	EXT2_STATE_CLEAN = 1,
+	EXT2_STATE_ERRORS = 2,
+};
+
+enum ext2_error_case
+{
+	EXT2_ERROR_IGNORE = 1,
+	EXT2_ERROR_REMOUNT = 2,
+	EXT2_ERROR_KPANIC = 3,
+};
+
+enum ext2_os_id
+{
+	EXT2_OS_LINUX = 0,
+	EXT2_OS_HURD,
+	EXT2_OS_MASIX,
+	EXT2_OS_FREEBSD,
+	EXT2_OS_OTHER_BSD,
+};
+
+void ext2_mount(struct fs_node *where);
diff --git a/include/kernel/dri/ide/ide.h b/include/kernel/dri/ide/ide.h
index 0283999..3376cb5 100644
--- a/include/kernel/dri/ide/ide.h
+++ b/include/kernel/dri/ide/ide.h
@@ -2,4 +2,18 @@
 
 #include <dri/pci/pci.h>
 
+enum ide_mode
+{
+    IDE_PCI_NATIVE,
+    IDE_COMPAT,
+};
+
+struct ide_device
+{
+    enum ide_mode channel_mode[2];
+    bool channel_mode_modifiable[2];
+    bool supports_dma;
+};
+
 void ide_register();
+void ide_print_device(struct ide_device *dev);
diff --git a/include/kernel/vfs.h b/include/kernel/vfs.h
new file mode 100644
index 0000000..1da0d6e
--- /dev/null
+++ b/include/kernel/vfs.h
@@ -0,0 +1,80 @@
+#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 bool (* fs_readdir_t)(struct fs_node *node, uint index, struct fs_dirent *dirent);
+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 */
+};
+
+extern struct fs_node root, dev, initrd;
+
+/* Not to be confused normal open, close, etc functions, these operate
+ * on the VFS directly
+ * read and write return the number of bytes written/read,  */
+
+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);
+
+bool fs_readdir(struct fs_node *node, uint index, struct fs_dirent *out);
+struct fs_node *fs_finddir(struct fs_node *node, char *name);
+
+/* Returns the following error codes:
+ * 0: success
+ * 1: target is not a directory
+ * 2: target is already a mount point
+ * 3: source is not a directory */
+uint fs_mount(struct fs_node *target, struct fs_node *source);
+
+void init_vfs();