Rewrite documentation
diff --git a/.gitignore b/.gitignore
index 6661bef..3c21329 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,6 @@
 .gitignore
 .idea
 **/.#*
-src/kernel/dri/pci/vendors.c
\ No newline at end of file
+src/kernel/dri/pci/vendors.c
+doc/_build
+!doc/Makefile
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..36e5778
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+    "restructuredtext.confPath": "${workspaceFolder}/doc"
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 3ca0ef0..4052e94 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -12,6 +12,11 @@
                 "kind": "build",
                 "isDefault": true
             }
+        },
+        {
+            "type": "shell",
+            "label": "sphynx:watch",
+            "command": "make -C doc/ watch"
         }
     ],
 }
\ No newline at end of file
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..5afd552
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,23 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+watch:
+	sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/doc/architecture.rst b/doc/architecture.rst
new file mode 100644
index 0000000..0c8fe0f
--- /dev/null
+++ b/doc/architecture.rst
@@ -0,0 +1,42 @@
+Architecture
+============
+
+This document seeks to provide a brief overview of Bluejay architecture. This
+should be a good starting point for understanding the code.
+
+Bluejay is exclusively a multiboot kernel, it neither provides nor supports
+alternative bootloaders.
+
+The bootloader (probably GRUB) will initially run the code in ``boot.s``. This
+is where it all begins. This code sets up segmentation and paging and maps the
+higher-half of virtual memory (everything above ``0xC0000000``) to the kernel. 
+At first it only maps 8 megabytes, more memory can be mapped on request.
+
+After moving to high memory the kernel jumps to C code and enters ``kmain`` in
+``main.c``. This is the highest level procedure in the kernel, which sets up
+kernel services and drivers one at a time.
+
+This includes VGA, keyboard, and PCI drivers, as well as paging and preemptive
+multi tasking.
+
+Multi tasking
+-------------
+
+Multi tasking is handled by code in ``task.c``. It is first initialized in
+``init_tasks``, which sets up the initial task. Once this is called kernel
+threads can be spawned at will.
+
+Every clock tick an interrupt is triggered (see ``clock.c`` for timing) which
+causes a task switch to occur. Bluejay uses a simple round-robin scheduler, and
+there is no way for tasks to voluntarily give up their processing time (even in
+the case of blocking IO operations). ``task.c`` contains the implementation of
+the scheduler.
+
+Drivers
+-------
+
+So far I have only written very low level drivers (stuff like ATA PIO, PCI, VGA
+text mode, etc). These drivers have all been "bare-metal", ie: interfacing with
+hardware through ``in`` and ``out`` instructions. Higher level drivers will be
+built on top of existing ones. An interface will be created for defining, for
+example, PCI device drivers, or USB device drivers.
diff --git a/doc/build.rst b/doc/build.rst
new file mode 100644
index 0000000..aefa6bf
--- /dev/null
+++ b/doc/build.rst
@@ -0,0 +1,39 @@
+Building Bluejay
+================
+
+Bluejay uses the home-grown ``Jmk`` build system, which is basically just a GNU
+m4 script that generates makefiles from ``Jmk`` files --- makefiles with some
+custom macros.
+
+To build a fresh clone of Bluejay the first thing you will need to do is run
+``bin/jmk`` to generate your makefiles for you. You should get some output like
+this:
+
+.. code-block::
+
+    Processing ./boot/initrd/Jmk
+    Processing ./src/kernel/dri/ata_pio/Jmk
+    Processing ./src/kernel/dri/ahci/Jmk
+    Processing ./src/kernel/dri/pci/Jmk
+    Processing ./src/kernel/Jmk
+    Processing ./src/mkinitrd/Jmk
+    Processing ./src/lisp/Jmk
+
+Then just build using ``src/kernel/Makefile``. There are a few additional
+targets for your convenience:
+
+- ``qemu`` builds and launches the kernel using QEMU's SeaBIOS
+- ``qemu-iso`` builds a GRUB ISO and launches using QEMU
+- ``install`` builds a GRUB ISO and installs it to ``boot/bluejay.iso``
+- ``debug`` launches kernel in QEMU and launches GDB in the terminal.
+- ``debug-wait`` launches kernel in QEMU and starts a GDB server on ``localhost:1234``.
+  This is recommended if you want to debug since you can connect to it from vscode or
+  any other IDE. ``.vscode/launch.json`` is set up to work with this so you can debug
+  the kernel very easily.
+
+In order to build Bluejay you will need the following dependencies::
+
+    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
diff --git a/doc/building.9 b/doc/building.9
deleted file mode 100644
index d19b224..0000000
--- a/doc/building.9
+++ /dev/null
@@ -1,22 +0,0 @@
-.TH building 9 "13 March 2021" "1" "Building the kernel"
-.SH SYNOPSIS
-Bluejay uses the JMK build system, a simple M4 script that generates Makefiles.
-Use the jmk binary in bin/ to generate Makefiles, then build the kernel with the
-Makefile in src/kernel/.
-.SH DESCRIPTION
-The included Makefile provides several targets useful for building and
-debugging the kernel.  Here are the useful targets:
-
-kernel.elf:  compile multiboot kernel
-
-qemu:        run multiboot kernel in qemu
-
-debug:       run qemu with debug server and attach gdb
-
-install:     build bootable grub image in /bin/bluejay.iso
-
-qemu-iso:    boot the iso file
-
-clean:       delete build artifacts
-.SH SEE ALSO
-jmk(1)
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..c284239
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,14 @@
+project = 'Bluejay'
+copyright = '2021, swissChili'
+author = 'swissChili'
+
+extensions = [
+]
+
+templates_path = ['_templates']
+
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+html_theme = 'alabaster'
+
+html_static_path = ['_static']
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..9e3d07b
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,21 @@
+.. Bluejay documentation master file, created by
+   sphinx-quickstart on Sun May 30 17:09:32 2021.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+The Bluejay Operating System
+============================
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+   :glob:
+
+   *
+
+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.
+
+This documentation is incomplete, but should provide a general introduction to
+compiling and developing Bluejay.
diff --git a/doc/jmk.1 b/doc/jmk.1
deleted file mode 100644
index b33bd89..0000000
--- a/doc/jmk.1
+++ /dev/null
@@ -1,6 +0,0 @@
-.TH jmk 1 "13 March 2021" "1" "JMK build system"
-.SH SYNOPSIS
-JMK -- Build system for Bluejay
-.SH DESCRIPTION
-When run, JMK will search all subdirectories for files named "Jmk" and will
-process them to create a Makefile in the same directory.
diff --git a/doc/jmk.5 b/doc/jmk.5
deleted file mode 100644
index 0262ba0..0000000
--- a/doc/jmk.5
+++ /dev/null
@@ -1,174 +0,0 @@
-.TH jmk 5 "13 March 2021" "1" "JMK format"
-.SH SYNOPSIS
-The JMK format is processed by jmk(1) to generate a Makefile.
-.SH DESCRIPTION
-jmk(1) is a simple M4 script which provides a handful of macros.
-These macros can be used to automate many tedious parts of creating
-makefiles.
-.SH OVERVIEW
-The following macros are provided by JMK:
-
-.B
-init(project, [target])
-.NB
-.RS
-Initialize the project named <project> to build the target <target>.
-If <target> is not provided, it defaults to <project>.
-.B
-Example:
-.NB
-
-.EX
-init(kernel, kernel.elf)
-# or
-init(my_lib, my_lib.a)
-.EE
-.RE
-
-.B
-preset(preset_name)
-.NB
-.RS
-Apply a preset to the project.
-Currently the following presets are available:
-
-freestanding: Applies CFLAGS suitable for freestanding targets.
-
-optimize: Applies -O2 optimization level
-
-debug: Applies -g
-
-32: Sets target architecture to 32 bit
-
-warn: Enables all warnings except unused-function and unused-variable.
-
-nasm: Forces the assembler to be nasm.
-
-.B
-Example:
-.NB
-
-.EX
-preset(32)
-preset(debug)
-CFLAGS += -my-flag
-.EE
-.RE
-
-.B
-archetype(archetype_name)
-.NB
-.RS
-Applies a given archetype to the project.
-An archetype provides support to compile a certain language or type of program.
-The two archetypes available by default are
-.B
-c
-.NB
-and
-.B
-asm,
-.NB
-whose meanings are self explanatory.
-.B
-Example:
-.NB
-
-.EX
-archetype(c)
-archetype(asm)
-.EE
-.RE
-
-.B
-depends(name, directory, [target])
-.NB
-.RS
-Register the target called <target> located in <directory> as a dependency named <name>.
-By default, <target> is set to the last segment of the directory path plus .a.
-E.g.: for foo/bar <target> would be bar.a by default.
-This is usually used in conjunction with lib().
-
-Internally this will generate a target for this library that will call make on the
-other project in order to build the target.
-See lib() for examples.
-.RE
-
-.B
-lib(dependency_name)
-.NB
-.RS
-Lib expands to the path to the dependency called <dependency_name> as defined by depends().
-This can, for example, be used in OBJECTS to specify the project's dependency on another
-(sub)project, or it can be used anywhere you would need to refer to the path of the
-target generated by that project.
-Despite the name, lib can be used for any type of dependency, not just for libraries.
-.B
-Example:
-.NB
-
-.EX
-depends(libc, $(ROOT)/src/libc, libc.a)
-OBJECTS = main.o lib(libc)
-.EE
-.RE
-
-.B
-phony(target)
-.NB
-.RS
-Adds <target> to the list of .PHONY targets.
-.RE
-
-.B
-type(type)
-.NB
-.RS
-Sets the project type and generates the actual target for the project.
-If you need to build your final target in a way unsupported by default, feel free to omit
-this and write the target by hand. <type> can be one of executable, static_lib or
-custom_link.
-The first two cases will build an executable and library respectively, using $(CC) and ar.
-custom_link will invoke $(LD), passing LDFLAGS.
-
-Note that the objects to include in the target are to be specified in OBJECTS,
-and should be built either automatically by an included archetype, or manually.
-.RE
-
-.B
-finish
-.NB
-.RS
-Include this at the end of every Jmk file, this generates some targets like .PHONY
-and clean, as well as setting up automatic Makefile regeneration.
-.RE
-
-.SH EXAMPLE
-Here is a full example of a JMK project:
-
-.EX
-init(kernel, kernel.elf)
-
-preset(freestanding)
-preset(optimize)
-preset(32)
-preset(nasm)
-
-LDFLAGS += -Tlink.ld
-
-archetype(c)
-archetype(asm)
-
-depends(some_driver, dri/some/driver/, driver.a)
-
-OBJECTS = boot.o main.o other.o something.o lib(some_driver)
-
-type(custom_link)
-
-qemu: kernel.elf
-    qemu-system-i386 $<
-
-finish
-.EE
-.SH SEE ALSO
-jmk(1), building(9)
diff --git a/doc/make.bat b/doc/make.bat
new file mode 100644
index 0000000..2119f51
--- /dev/null
+++ b/doc/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF

+

+pushd %~dp0

+

+REM Command file for Sphinx documentation

+

+if "%SPHINXBUILD%" == "" (

+	set SPHINXBUILD=sphinx-build

+)

+set SOURCEDIR=.

+set BUILDDIR=_build

+

+if "%1" == "" goto help

+

+%SPHINXBUILD% >NUL 2>NUL

+if errorlevel 9009 (

+	echo.

+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx

+	echo.installed, then set the SPHINXBUILD environment variable to point

+	echo.to the full path of the 'sphinx-build' executable. Alternatively you

+	echo.may add the Sphinx directory to PATH.

+	echo.

+	echo.If you don't have Sphinx installed, grab it from

+	echo.http://sphinx-doc.org/

+	exit /b 1

+)

+

+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

+goto end

+

+:help

+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

+

+:end

+popd

diff --git a/doc/mkinitrd.1 b/doc/mkinitrd.1
deleted file mode 100644
index 0d77c97..0000000
--- a/doc/mkinitrd.1
+++ /dev/null
@@ -1,12 +0,0 @@
-.TH mkinitrd 1 "2 March 2021" "1" "Make initial ramdisk"
-.SH SYNOPSIS
-mkinitrd <output> [input...]
-.SH DESCRIPTION
-Make initial ramdisk from list of input files.
-Generated ramdisk should be placed in /boot/initrd.img of kernel boot ISO.
-
-Make sure that each input path is formatted as it should appear in the file system.
-I.e.: treat each path passed to mkinitrd as absolute.
-
-Paths must be a maximum of 63 characters long (64 including NULL byte).
-Paths longer than this will be truncated.
diff --git a/doc/paging.9 b/doc/paging.9
deleted file mode 100644
index 808dc74..0000000
--- a/doc/paging.9
+++ /dev/null
@@ -1,34 +0,0 @@
-.\" Kernel paging docs, largely as a reference for myself.
-.TH paging 9 "18 February 2021" "1" "Paging"
-.SH NAME
-Paging - kernel memory paging overview
-.SH SYNOPSIS
-Paging allows the kernel to map arbitrary virtual memory addresses to
-locations in physical memory.
-.SH DESCRIPTION
-On x86 each page is fixed at 4kb.  Mapping each 4kb page for the
-entire memory takes a lot of space, so instead,
-.B
-page directories
-.NB
-and
-.B
-page tables
-.NB
-are used.  The kernel stores one or more page directories, each of
-which contains 1024 pointers to page tables (which may be null), each
-of which in turn contains 1024
-.B
-page table entries
-.NB
-
-Each page table entry contains the upper 20 bits of the physical
-memory location it maps to
-.B
-(frame).
-.NB
-It also contains several flags describing if the page is readable or
-writable in user mode, as well as flags set by the CPU: such as if the
-page has been accessed or modified.
-.SH SEE ALSO
-src/paging.c, src/paging.h, Intel manual volume 4, Figure 4-4.