Add ext2 superblock, document file system
diff --git a/.vscode/settings.json b/.vscode/settings.json
index a79fd77..19972d2 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,4 @@
 {
-    "restructuredtext.confPath": "${workspaceFolder}/doc",
-    "restructuredtext.languageServer.disabled": true
+    "restructuredtext.languageServer.disabled": true,
+    "restructuredtext.confPath": "${workspaceFolder}/doc"
 }
\ No newline at end of file
diff --git a/bin/jmk b/bin/jmk
index 5730b5f..ffd3993 100755
--- a/bin/jmk
+++ b/bin/jmk
@@ -2,7 +2,8 @@
 
 # Jay MaKe
 
-root="$(pwd)"
+dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+root="$(dirname $dir)"
 jmkscript="$root/share/jmk/jmk.m4"
 
 for file in $(find -name Jmk); do
diff --git a/doc/build.rst b/doc/build.rst
index aefa6bf..3826238 100644
--- a/doc/build.rst
+++ b/doc/build.rst
@@ -36,4 +36,4 @@
     gcc gcc-multilib nasm qemu-system-i386 make m4 python3 awk
 
 There are some additional dependencies for building a GRUB ISO but I don't
-remember them at the time of writing.
\ No newline at end of file
+remember them at the time of writing.
diff --git a/doc/filesystem.rst b/doc/filesystem.rst
new file mode 100644
index 0000000..fc8a025
--- /dev/null
+++ b/doc/filesystem.rst
@@ -0,0 +1,23 @@
+Bluejay Filesystem
+==================
+
+Filesystem drivers are still a work in progress. To test a file system you will
+want to create and mount a virtual block device. The makefile in ``src/kernel``
+will generate an ``hd0.img`` EXT2 disk image for you automatically. The default
+size is 32 megabytes, but you can create your own of any size if you want. Once
+the image has been created it will be loaded by QEMU automatically.
+
+In order to write to the virtual hard disk from your host operating system you
+should mount it. The ``make mount`` command in ``src/kernel`` mount the image to
+``$(BLUEJAY_ROOT)/mnt``. It will automatically give read and write permissions
+to the current user. This operation uses ``sudo`` internally, you will be
+prompted for your password.
+
+Virtual Filesystem
+------------------
+
+The Bluejay VFS is heavily inspired by UNIX. It relies on inodes and a tree of
+file nodes. The source can be found in ``src/kernel/vfs.c``. This also exports a
+very low-level API for dealing with files -- including the usual read(),
+write(), readdir(), etc -- but this should not be used for much longer. A high
+level API utilizing file descriptors will be implemented to make this simpler.
diff --git a/doc/index.rst b/doc/index.rst
index 9e3d07b..5baa0ef 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -6,6 +6,9 @@
 The Bluejay Operating System
 ============================
 
+.. image:: https://builds.sr.ht/~swisschili/bluejay/commits/.build.yml.svg
+   :target: https://builds.sr.ht/~swisschili/bluejay/commits/.build.yml?
+
 .. toctree::
    :maxdepth: 2
    :caption: Contents:
@@ -14,8 +17,7 @@
    *
 
 Bluejay is an operating system inspired by UNIX and early Lisp machines.
-Currently it only targets x86, and there are no plans to port to other
-platforms.
+Currently it only targets x86. There are no plans to port to other platforms.
 
 This documentation is incomplete, but should provide a general introduction to
 compiling and developing Bluejay.
diff --git a/include/kernel/dri/fs/ext2/ext2.h b/include/kernel/dri/fs/ext2/ext2.h
index a94fb77..1adf51c 100644
--- a/include/kernel/dri/fs/ext2/ext2.h
+++ b/include/kernel/dri/fs/ext2/ext2.h
@@ -78,4 +78,5 @@
 	EXT2_OS_OTHER_BSD,
 };
 
+struct ext2_superblock ext2_read_superblock();
 void ext2_mount(struct fs_node *where);
diff --git a/src/kernel/Jmk b/src/kernel/Jmk
index a821bae..3b718b8 100644
--- a/src/kernel/Jmk
+++ b/src/kernel/Jmk
@@ -14,17 +14,20 @@
 depends(ata_pio, dri/ata_pio, ata_pio.a)
 depends(pci, dri/pci, pci.a)
 depends(ide, dri/ide, ide.a)
+depends(ext2, dri/fs/ext2, ext2.a)
 # AHCI not yet implemented
 # depends(ahci, dri/ahci, ahci.a)
 
 TEST ?=
 test_defines = $(TEST:%=-DTEST_%)
 
+FS ?= ext2
+
 CFLAGS += -I $(ROOT)/include/kernel $(test_defines)
 
 LDFLAGS += -Tlink.ld -melf_i386
 ASMFLAGS += -felf -Fdwarf
-QEMUFLAGS = -d cpu_reset -hda hd0.img
+QEMUFLAGS = -d cpu_reset -hda hd0_$(FS).img
 
 OBJECTS = 	boot.o \
 			main.o \
@@ -49,6 +52,7 @@
 			task.o \
 			task_api.o \
 			faults.o \
+			lib(ext2) \
 			lib(ata_pio) \
 			lib(pci) \
 			lib(ide)
@@ -64,12 +68,12 @@
 	gdb $<
 	@pkill qemu-system-i38
 
-hd0.img:
+hd0_%.img:
 	status_log(MKFS, $@)
 	@dd bs=4M count=8 if=/dev/zero of=$@
-	@mkfs.ext2 $@
+	@$(patsubst hd0_%.img,mkfs.%,$@) $@
 
-qemu: kernel.elf hd0.img
+qemu: kernel.elf hd0_$(FS).img
 	qemu-system-i386 $(QEMUFLAGS) -monitor stdio -kernel kernel.elf -no-reboot
 
 qemu-iso: install
@@ -78,11 +82,11 @@
 scan_codes.c: gen_scan_codes.py scan_codes.tsv 
 	python3 $< > $@
 
-mount: hd0.img
+mount: hd0_$(FS).img
 	status_log(MOUNT, $^ $(ROOT)/mnt)
+	@if [ $(whoami) = root ]; then echo "DON'T RUN THIS AS ROOT" && exit 1; fi
 	@mkdir -p $(ROOT)/mnt
-	@mount $^ $(ROOT)/mnt
-	@if [ $$(whoami) = root ]; then echo 'You ran this as root, you probably want to chown $(ROOT)/mnt now.'; fi
+	@sudo mount $^ $(ROOT)/mnt -o rw,uid=$$(id -u),gid=$$(id -g)
 
 umount:
 	status_log(UMOUNT, $(ROOT)/mnt)
diff --git a/src/kernel/boot.s b/src/kernel/boot.s
index 043c42c..047b326 100644
--- a/src/kernel/boot.s
+++ b/src/kernel/boot.s
@@ -100,7 +100,7 @@
 	[extern kmain]				; C code
 
 start equ (_start)
-	
+
 _start:
 	;; First set up GDT
 	mov eax, (gdt_pointer - KERNEL_VIRTUAL_BASE)
diff --git a/src/kernel/dri/fs/ext2/Jmk b/src/kernel/dri/fs/ext2/Jmk
index b0da0c3..aac4c5c 100644
--- a/src/kernel/dri/fs/ext2/Jmk
+++ b/src/kernel/dri/fs/ext2/Jmk
@@ -8,7 +8,7 @@
 
 archetype(c)
 
-CFLAGS += -I/include/kernel
+CFLAGS += -I$(ROOT)/include/kernel
 
 OBJECTS = ext2.o
 
diff --git a/src/kernel/dri/fs/ext2/ext2.c b/src/kernel/dri/fs/ext2/ext2.c
index eb6842b..31ed7fe 100644
--- a/src/kernel/dri/fs/ext2/ext2.c
+++ b/src/kernel/dri/fs/ext2/ext2.c
@@ -1,7 +1,20 @@
 #include <dri/fs/ext2/ext2.h>
+#include <dri/ata_pio/ata_pio.h>
 #include <kint.h>
+#include <log.h>
+
+struct ext2_superblock ext2_read_superblock()
+{
+	uchar buffer[512 * 2];
+	ata_pio_read_sectors(buffer, 2, 2);
+
+	struct ext2_superblock *sb = (void *)(buffer);
+	return *sb;
+}
 
 void ext2_mount(struct fs_node *where)
 {
-	// TODO
+	struct ext2_superblock sb = ext2_read_superblock();
+
+	kprintf("Magic = 0x%x\n", sb.signature);
 }
diff --git a/src/kernel/main.c b/src/kernel/main.c
index b973b41..0fef9c5 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -13,6 +13,7 @@
 #include <dri/ata_pio/ata_pio.h>
 #include <dri/pci/pci.h>
 #include <dri/ide/ide.h>
+#include <dri/fs/ext2/ext2.h>
 
 void greet()
 {
@@ -77,10 +78,7 @@
 
 	asm("sti");
 
-	kprintf("initializing tasks\n");
 	init_tasks();
-	kprintf("\ndone initializing tasks\n");
-
 	pci_init();
 
 	// Register PCI drivers
@@ -94,15 +92,17 @@
 	greet();
 #endif
 
-#ifdef TEST_ATA_PIO
-	test_ata_pio();
-#endif
-
 #ifdef TEST_PCI
 	pci_print_devices();
 	pci_print_drivers();
 #endif
 
+#ifdef TEST_ATA_PIO
+	test_ata_pio();
+#endif
+
+	ext2_mount(&root);
+
 	while (true)
 		asm("hlt");
 
diff --git a/src/kernel/task.c b/src/kernel/task.c
index b8ce525..c8068c4 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -27,8 +27,6 @@
 
 void _init_tasks(uint kernel_esp, uint kernel_ebp, uint kernel_eip)
 {
-	kprintf("_init_tasks\n");
-
 	processes[0] = (struct process){
 		.exists = true,
 		.id = 0,
@@ -44,7 +42,6 @@
 		.last_stack_pos = 0xFFFFF000,
 	};
 	strcpy(processes[0].name, "kernel");
-	kprintf("in _init_tasks, strlen of 'kernel' is %d\n", strlen("kernel"));
 
 	first_task = last_task = current_task = malloc(sizeof(struct ll_task_i));
 
@@ -58,8 +55,6 @@
 		.id = next_task_id++,
 	};
 
-	kprintf("Returning from _init_tasks\n");
-
 	tasks_initialized = true;
 }