summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2024-05-22 13:00:41 -0400
committerJon Santmyer <jon@jonsantmyer.com>2024-05-22 13:00:41 -0400
commitace65b453151845bc361f21f3e5b651c35f9f126 (patch)
tree262ebd29b0ca1d8584f0b6f1efa7a00d9f4f3e43 /include
parentf004c1ade8d617a82cea2fe249434cccb47a2358 (diff)
downloadjove-kernel-master.tar.gz
jove-kernel-master.tar.bz2
jove-kernel-master.zip
massive refactor for mp and organizationHEADmaster
Diffstat (limited to 'include')
-rw-r--r--include/api/errno.h9
-rw-r--r--include/api/syscall.h39
-rw-r--r--include/arch/cpu.h14
-rw-r--r--include/arch/elf.h12
-rw-r--r--include/arch/page.h34
-rw-r--r--include/arch/processor.h39
-rw-r--r--include/arch/x86_64/cpu.h6
-rw-r--r--include/arch/x86_64/elf.h93
-rw-r--r--include/arch/x86_64/gdt.h23
-rw-r--r--include/arch/x86_64/idt.h25
-rw-r--r--include/arch/x86_64/msr.h56
-rw-r--r--include/arch/x86_64/page.h40
-rw-r--r--include/arch/x86_64/processor.h17
-rw-r--r--include/arch/x86_64/tables.h57
-rw-r--r--include/arch/x86_64/tss.h20
-rw-r--r--include/assert.h10
-rw-r--r--include/boot.h38
-rw-r--r--include/commandline.h8
-rw-r--r--include/device/serial.h48
-rw-r--r--include/device/uart.h19
-rw-r--r--include/initrd.h17
-rw-r--r--include/jove.h13
-rw-r--r--include/memory.h49
-rw-r--r--include/print.h25
-rw-r--r--include/slab.h44
-rw-r--r--include/string.h18
-rw-r--r--include/tasking.h44
-rw-r--r--include/umode_vma.h10
-rw-r--r--include/zone.h38
29 files changed, 865 insertions, 0 deletions
diff --git a/include/api/errno.h b/include/api/errno.h
new file mode 100644
index 0000000..51921d2
--- /dev/null
+++ b/include/api/errno.h
@@ -0,0 +1,9 @@
+#ifndef _JOVE_ERRNO_H
+#define _JOVE_ERRNO_H 1
+
+enum {
+ EFAIL = 1,
+ EACCESS
+};
+
+#endif
diff --git a/include/api/syscall.h b/include/api/syscall.h
new file mode 100644
index 0000000..eb4235d
--- /dev/null
+++ b/include/api/syscall.h
@@ -0,0 +1,39 @@
+#ifndef _JOVE_API_SYSCALL_H
+#define _JOVE_API_SYSCALL_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef intmax_t syscall_id_t;
+
+static int __syscall(void *data)
+{
+ intmax_t r;
+ __asm__ volatile(" \
+ movq %1, %%rdi; \
+ syscall; \
+ movq %%rax, %0"
+ : "=r"(r)
+ : "r"(data));
+ return r;
+}
+
+enum {
+ SC_DBG_LOGF = 0,
+ SC_EXIT
+};
+
+struct sc_dbg_log
+{
+ syscall_id_t id;
+ size_t w;
+ const char *s;
+};
+
+struct sc_exit
+{
+ syscall_id_t id;
+ int exit_code;
+};
+
+#endif
diff --git a/include/arch/cpu.h b/include/arch/cpu.h
new file mode 100644
index 0000000..fe89dc0
--- /dev/null
+++ b/include/arch/cpu.h
@@ -0,0 +1,14 @@
+#ifndef _JOVE_ARCH_CPU_H
+#define _JOVE_ARCH_CPU_H 1
+
+#ifdef __x86_64__
+#include "x86_64/cpu.h"
+#endif
+
+void cpu_setup(void);
+
+void cpu_set_syscall_entry(void *entry);
+
+void umode_enter(void *ip, void *sp);
+
+#endif
diff --git a/include/arch/elf.h b/include/arch/elf.h
new file mode 100644
index 0000000..1b8c3dc
--- /dev/null
+++ b/include/arch/elf.h
@@ -0,0 +1,12 @@
+#ifndef _JOVE_ARCH_ELF_H
+#define _JOVE_ARCH_ELF_H 1
+
+#ifdef __x86_64__
+#include "x86_64/elf.h"
+#endif
+
+#include <stddef.h>
+
+uintptr_t elf_load(const void *data, size_t len);
+
+#endif
diff --git a/include/arch/page.h b/include/arch/page.h
new file mode 100644
index 0000000..25c5294
--- /dev/null
+++ b/include/arch/page.h
@@ -0,0 +1,34 @@
+#ifndef _JOVE_ARCH_PAGE_H
+#define _JOVE_ARCH_PAGE_H 1
+
+#define PAGE_SHIFT (12)
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (PAGE_SIZE - 1)
+
+#ifdef __x86_64__
+#include "x86_64/page.h"
+#endif
+
+typedef struct page_mapping_flags
+{
+ char present : 1;
+ char writeable : 1;
+ char useraccess : 1;
+ char executable : 1;
+} page_flags_t;
+
+typedef struct page_mapping
+{
+ uintptr_t phys;
+ page_flags_t pf;
+} page_mapping_t;
+
+typedef intmax_t pdid_t;
+
+page_directory_t *pd_new(void);
+page_directory_t *pd_dup(page_directory_t *pd);
+page_directory_t *pd_get(pdid_t id);
+
+void pd_switch(page_directory_t *pd);
+
+#endif
diff --git a/include/arch/processor.h b/include/arch/processor.h
new file mode 100644
index 0000000..871e5c7
--- /dev/null
+++ b/include/arch/processor.h
@@ -0,0 +1,39 @@
+#ifndef _JOVE_ARCH_PROCESSOR_H
+#define _JOVE_ARCH_PROCESSOR_H 1
+
+#ifdef __x86_64__
+#include "x86_64/processor.h"
+#endif
+
+#include "memory.h"
+#include "tasking.h"
+#include "klib/spinlock.h"
+
+#define _EXRTAB_C (PAGE_SIZE / sizeof(uintptr_t))
+
+typedef struct processor
+{
+ ARCH_SPECIFIC_PROCESSOR_MEMBERS;
+ unsigned int id;
+ unsigned int isr_depth;
+ page_directory_t *pd;
+ tcb_t *tcb;
+
+ uintptr_t exrtab[_EXRTAB_C];
+ size_t ert_i;
+} processor_t;
+
+extern processor_t *proc_bsp;
+
+void processor_setup(processor_t *proc);
+
+processor_t *processor_list(void);
+
+processor_t *processor_current(void);
+page_directory_t *pd_current(void);
+tcb_t *tcb_current(void);
+
+void _exrtab_push(void *v);
+void *_exrtab_pop(void);
+
+#endif
diff --git a/include/arch/x86_64/cpu.h b/include/arch/x86_64/cpu.h
new file mode 100644
index 0000000..6e467c1
--- /dev/null
+++ b/include/arch/x86_64/cpu.h
@@ -0,0 +1,6 @@
+#ifndef _JOVE_x86_64_CPU_H
+#define _JOVE_x86_64_CPU_H 1
+
+void cpu_arch_enable_sce(void);
+
+#endif
diff --git a/include/arch/x86_64/elf.h b/include/arch/x86_64/elf.h
new file mode 100644
index 0000000..1aaf116
--- /dev/null
+++ b/include/arch/x86_64/elf.h
@@ -0,0 +1,93 @@
+#ifndef _JOVE_x86_64_ELF_H
+#define _JOVE_x86_64_ELF_H 1
+
+#include <stdint.h>
+
+#define EI_MAG0 0x7F
+#define EI_MAG1 'E'
+#define EI_MAG2 'L'
+#define EI_MAG3 'F'
+
+#define EI_CLASS_32 1
+#define EI_CLASS_64 2
+
+#define EI_DATA_LE 1
+#define EI_DATA_BE 2
+
+#define EI_VERSION_CURRENT 1
+
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+
+typedef struct elf64_file_header
+{
+ union {
+ struct {
+ uint8_t ei_mag[4];
+ uint8_t ei_class;
+ uint8_t ei_data;
+ uint8_t ei_version;
+ uint8_t ei_osabi;
+ uint8_t ei_abiver;
+ uint8_t ei_pad[7];
+ };
+ uint8_t e_ident[16];
+ };
+ uint16_t e_type;
+ uint16_t e_machine;
+ uint32_t e_version;
+ uint64_t e_entry;
+ uint64_t e_phoff;
+ uint64_t e_shoff;
+ uint32_t e_flags;
+ uint16_t e_ehsize;
+ uint16_t e_phentsize;
+ uint16_t e_phnum;
+ uint16_t e_shentsize;
+ uint16_t e_shnum;
+ uint16_t e_shstrndx;
+} elf_header_t;
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+
+#define PF_X 1
+#define PF_W 2
+#define PF_R 4
+
+typedef struct elf64_program_header
+{
+ uint32_t p_type;
+ uint32_t p_flags;
+ uint64_t p_offset;
+ uint64_t p_vaddr;
+ uint64_t p_paddr;
+ uint64_t p_filesz;
+ uint64_t p_memsz;
+ uint64_t p_align;
+} elf_phdr_t;
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+
+typedef struct elf64_section_header
+{
+ uint32_t sh_name;
+ uint32_t sh_type;
+ uint64_t sh_flags;
+ uint64_t sh_addr;
+ uint64_t sh_offset;
+ uint64_t sh_size;
+ uint64_t sh_addralign;
+ uint64_t sh_entsize;
+} elf_shdr_t;
+
+#endif
diff --git a/include/arch/x86_64/gdt.h b/include/arch/x86_64/gdt.h
new file mode 100644
index 0000000..c17c9eb
--- /dev/null
+++ b/include/arch/x86_64/gdt.h
@@ -0,0 +1,23 @@
+#ifndef _JOVE_x86_64_GDT_H
+#define _JOVE_x86_64_GDT_H 1
+
+#include "tables.h"
+
+enum
+{
+ GDT_SEGMENT_KERNEL_NULL = 0,
+ GDT_SEGMENT_KERNEL_CODE,
+ GDT_SEGMENT_KERNEL_DATA,
+
+ GDT_SEGMENT_USER_NULL,
+ GDT_SEGMENT_USER_DATA,
+ GDT_SEGMENT_USER_CODE,
+
+ GDT_SEGMENT_TSS_LOW,
+ GDT_SEGMENT_TSS_HIGH,
+
+ GDT_SEGMENT_COUNT
+};
+typedef segment_descriptor_t gdt_t[GDT_SEGMENT_COUNT];
+
+#endif
diff --git a/include/arch/x86_64/idt.h b/include/arch/x86_64/idt.h
new file mode 100644
index 0000000..7a5c468
--- /dev/null
+++ b/include/arch/x86_64/idt.h
@@ -0,0 +1,25 @@
+#ifndef _JOVE_x86_64_IDT_H
+#define _JOVE_x86_64_IDT_H 1
+
+#include "tables.h"
+
+typedef struct interrupt_state
+{
+ uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
+ uint64_t bp, di, si, dx, cx, bx, ax;
+ uint64_t ip, cs, flags, sp, ss;
+} int_state_t;
+
+typedef interrupt_gate_t idt_t[48];
+
+typedef int_state_t *(*int_handler_t)(int_state_t *);
+
+void int_handler_set(uint8_t i, int_handler_t handler);
+int_handler_t int_handler_get(uint8_t i);
+
+void int_state_print(int_state_t *state);
+
+extern uint64_t __isr_err;
+extern uint64_t __isr_num;
+
+#endif
diff --git a/include/arch/x86_64/msr.h b/include/arch/x86_64/msr.h
new file mode 100644
index 0000000..c20f8fc
--- /dev/null
+++ b/include/arch/x86_64/msr.h
@@ -0,0 +1,56 @@
+#ifndef _JOVE_x86_64_MSR_H
+#define _JOVE_x86_64_MSR_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MSR_EFER 0xC0000080
+#define MSR_STAR 0xC0000081
+#define MSR_LSTAR 0xC0000082
+#define MSR_SFMASK 0xC0000084
+
+#define MSR_FSBASE 0xC0000100
+#define MSR_GSBASE 0xC0000101
+#define MSR_KERNELGSBASE 0xC0000102
+
+typedef union msr_efer
+{
+ struct {
+ uint8_t sce : 1;
+ uint8_t resv : 7;
+ uint8_t lme : 1;
+ uint8_t unk0 : 1;
+ uint8_t lma : 1;
+ uint8_t nxe : 1;
+ uint8_t svme : 1;
+ uint8_t lmsle : 1;
+ uint8_t ffxsr : 1;
+ uint8_t tce : 1;
+ };
+ uint32_t v[2];
+} msr_efer_t;
+
+typedef union msr_star
+{
+ struct {
+ uint32_t eip;
+ uint16_t kcs;
+ uint16_t ucs;
+ };
+ uint32_t v[2];
+} msr_star_t;
+typedef uintptr_t msr_lstar_t;
+
+void msr_efer_write(msr_efer_t v);
+msr_efer_t msr_efer_read(void);
+
+void msr_star_write(msr_star_t v);
+msr_star_t msr_star_read(void);
+
+void msr_lstar_write(msr_lstar_t v);
+msr_lstar_t msr_lstar_read(void);
+
+void msr_gsbase_write(uintptr_t gsbase);
+uintptr_t msr_gsbase_read(void);
+
+#endif
diff --git a/include/arch/x86_64/page.h b/include/arch/x86_64/page.h
new file mode 100644
index 0000000..cbbf642
--- /dev/null
+++ b/include/arch/x86_64/page.h
@@ -0,0 +1,40 @@
+#ifndef _JOVE_x86_64_PAGE_H
+#define _JOVE_x86_64_PAGE_H 1
+
+#include <stdint.h>
+#include "klib/spinlock.h"
+#include "assert.h"
+
+typedef union page_mapping_level_entry
+{
+ struct {
+ uint8_t p : 1; /* Present */
+ uint8_t rw : 1; /* Read/write. 0 for RO.*/
+ uint8_t us : 1; /* User/supervisor. 0 for DPL3 forbid */
+ uint8_t pwt : 1;
+ uint8_t pcd : 1;
+ uint8_t a : 1; /* Accessed */
+ uint8_t d : 1; /* Dirty */
+ uint8_t ps_pat : 1;
+ uint8_t g : 1; /* Global */
+ uint8_t _r0 : 2;
+ uint8_t r : 1;
+ uint64_t paddr : 35;
+ uint8_t _r1;
+ uint8_t pk : 4;
+ uint8_t xd : 1;
+ }__attribute__((packed));
+ uint64_t value;
+} __attribute__((packed)) pmle_t;
+
+typedef struct page_directory
+{
+ spinlock_t lock;
+ intmax_t id;
+ uintptr_t phys;
+ pmle_t *pml;
+} page_directory_t;
+
+#define _kernel_virtual_base 0xFFFFFFFF80000000ULL
+
+#endif
diff --git a/include/arch/x86_64/processor.h b/include/arch/x86_64/processor.h
new file mode 100644
index 0000000..c208eb1
--- /dev/null
+++ b/include/arch/x86_64/processor.h
@@ -0,0 +1,17 @@
+#ifndef _JOVE_x86_64_PROCESSOR_H
+#define _JOVE_x86_64_PROCESSOR_H 1
+
+#include "tables.h"
+#include "gdt.h"
+#include "idt.h"
+#include "tss.h"
+
+#define PROCESSOR_MAX 8
+
+#define ARCH_SPECIFIC_PROCESSOR_MEMBERS \
+ __attribute__((aligned(0x1000))) gdt_t _gdt; \
+ struct TSS _tss; \
+ struct XDTR _gdtr; \
+ struct XDTR _idtr
+
+#endif
diff --git a/include/arch/x86_64/tables.h b/include/arch/x86_64/tables.h
new file mode 100644
index 0000000..e311192
--- /dev/null
+++ b/include/arch/x86_64/tables.h
@@ -0,0 +1,57 @@
+#ifndef _JOVE_X86_64_TABLES_H
+#define _JOVE_X86_64_TABLES_H 1
+
+#include <stdint.h>
+
+#define CD_SEGMENT_TYPE_ACCESSED 1
+#define CD_SEGMENT_TYPE_WRITEABLE 2
+#define CD_SEGMENT_TYPE_DATA_EXPAND_DOWN 4
+#define CD_SEGMENT_TYPE_CODE_CONFORMING 4
+#define CD_SEGMENT_TYPE_CODE 8
+
+#define S_SEGMENT_TYPE_LDT 2
+#define S_SEGMENT_TYPE_TSS_AVAIL 9
+#define S_SEGMENT_TYPE_TSS_BUSY 11
+#define S_SEGMENT_TYPE_CALLGATE 12
+#define S_SEGMENT_TYPE_INT_GATE 14
+#define S_SEGMENT_TYPE_TRAP_GATE 15
+
+typedef struct segment_descriptor
+{
+ uint16_t limit_0_15; /* Segment limit. */
+ uint16_t base_0_15; /* Segment base. */
+ uint8_t base_16_23;
+ uint8_t type : 4; /* Segment type. */
+ uint8_t s : 1; /* Descriptor type (0 = system, 1 = code/data)*/
+ uint8_t dpl : 2; /* Descriptor privilege level. */
+ uint8_t p : 1; /* Present. */
+ uint8_t limit_16_19 : 4;
+ uint8_t avl : 1; /* Available for use by system software. */
+ uint8_t l : 1; /* 64-bit segment (Ext). */
+ uint8_t d_b : 1; /* Default operation size (0 = 16-bit, 1 = 32-bit)*/
+ uint8_t g : 1; /* Granularity. */
+ uint8_t base_24_31;
+}__attribute__((packed)) segment_descriptor_t;
+
+typedef struct interrupt_gate
+{
+ uint16_t base_0_15;
+ uint16_t segment_selector;
+ uint8_t ist : 3;
+ uint8_t zero_0 : 5;
+ uint8_t type : 4;
+ uint8_t zero_1 : 1;
+ uint8_t dpl : 2;
+ uint8_t p : 1;
+ uint16_t base_16_31;
+ uint32_t base_32_63;
+ uint32_t resv;
+}__attribute__((packed)) interrupt_gate_t;
+
+struct XDTR /* Generic table descriptor struct */
+{
+ uint16_t length;
+ uint64_t address;
+}__attribute__((packed));
+
+#endif
diff --git a/include/arch/x86_64/tss.h b/include/arch/x86_64/tss.h
new file mode 100644
index 0000000..3184df5
--- /dev/null
+++ b/include/arch/x86_64/tss.h
@@ -0,0 +1,20 @@
+#ifndef JOVE_ARCH_x86_64_TSS_H
+#define JOVE_ARCH_x86_64_TSS_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct TSS
+{
+ uint32_t resv0;
+ uint32_t rsp[3][2];
+ uint64_t resv1;
+ uint32_t ist[8][2];
+ uint64_t resv2;
+ uint16_t resv3;
+ uint16_t iobp;
+};
+
+void tss_set_rsp(struct TSS *tss, uint8_t dpl, uintptr_t rsp);
+
+#endif
diff --git a/include/assert.h b/include/assert.h
new file mode 100644
index 0000000..f208235
--- /dev/null
+++ b/include/assert.h
@@ -0,0 +1,10 @@
+#ifndef JOVE_LIB_ASSERT_H
+#define JOVE_LIB_ASSERT_H 1
+
+#include "jove.h"
+
+#define assert(cond) \
+ if(!(cond)) \
+ kpanic("Assert failure : %s\n", #cond)
+
+#endif
diff --git a/include/boot.h b/include/boot.h
new file mode 100644
index 0000000..c4aa541
--- /dev/null
+++ b/include/boot.h
@@ -0,0 +1,38 @@
+#ifndef JOVE_BOOT_H
+#define JOVE_BOOT_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+struct MemoryMapEntry {
+ uintptr_t base;
+ size_t length;
+ bool usable;
+};
+
+#define MEMORY_MAP_MAX_ENTRIES 128
+struct MemoryMap {
+ size_t count;
+ struct MemoryMapEntry entries[MEMORY_MAP_MAX_ENTRIES];
+};
+
+#define BOOT_MODULE_MAX_ENTRIES 4
+struct BootModule {
+ char *path;
+ char *cmdline;
+ size_t size;
+ uintptr_t addr;
+};
+
+#define KERNEL_INITIAL_STACK_WIDTH (0x1000 * 4)
+extern void *boot_kernel_initial_stack_base;
+extern uintptr_t boot_kernel_physical_address;
+extern const char *boot_kernel_cmdline;
+
+extern struct MemoryMap boot_memorymap;
+
+extern struct BootModule boot_modules[BOOT_MODULE_MAX_ENTRIES];
+extern size_t boot_module_count;
+
+#endif
diff --git a/include/commandline.h b/include/commandline.h
new file mode 100644
index 0000000..5c66cd3
--- /dev/null
+++ b/include/commandline.h
@@ -0,0 +1,8 @@
+#ifndef _JOVE_COMMANDLINE_H
+#define _JOVE_COMMANDLINE_H 1
+
+const char *cmdline_get(const char *key);
+
+void cmdline_kernel_setup(void);
+
+#endif
diff --git a/include/device/serial.h b/include/device/serial.h
new file mode 100644
index 0000000..d59b00f
--- /dev/null
+++ b/include/device/serial.h
@@ -0,0 +1,48 @@
+#ifndef _JOVE_DEVICE_SERIAL_H
+#define _JOVE_DEVICE_SERIAL_H 1
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "klib/spinlock.h"
+
+#define SERIAL_UART_COM1 0x3F8
+#define SERIAL_UART_COM2 0x2F8
+
+#define SERIAL_UART_COM_THR(COM) COM
+#define SERIAL_UART_COM_RBR(COM) COM
+#define SERIAL_UART_COM_DLAB_DLL(COM) COM
+#define SERIAL_UART_COM_IER(COM) (COM + 1)
+#define SERIAL_UART_COM_DLAB_DLH(COM) (COM + 1)
+#define SERIAL_UART_COM_IIR(COM) (COM + 2)
+#define SERIAL_UART_COM_FCR(COM) (COM + 2)
+#define SERIAL_UART_COM_LCR(COM) (COM + 3)
+#define SERIAL_UART_COM_MCR(COM) (COM + 4)
+#define SERIAL_UART_COM_LSR(COM) (COM + 5)
+#define SERIAL_UART_COM_MSR(COM) (COM + 6)
+#define SERIAL_UART_COM_SR(COM) (COM + 7)
+
+typedef struct serial_device
+{
+ uint16_t com;
+ spinlock_t lock;
+} serial_dev_t;
+
+extern serial_dev_t COM1;
+
+void serial_setup(void);
+serial_dev_t serial_new(uint16_t com);
+
+void serial_set_int(serial_dev_t *dev, bool enable);
+void serial_set_baud(serial_dev_t *dev, uint16_t baud);
+
+void serial_set_fcr(serial_dev_t *dev, uint16_t flg);
+void serial_set_lcr(serial_dev_t *dev, uint16_t flg);
+void serial_set_mcr(serial_dev_t *dev, uint16_t flg);
+void serial_set_lsr(serial_dev_t *dev, uint16_t flg);
+void serial_set_msr(serial_dev_t *dev, uint16_t flg);
+
+uint8_t serial_line_status(serial_dev_t *dev);
+void serial_write(serial_dev_t *dev, const char *s, size_t len);
+
+#endif
diff --git a/include/device/uart.h b/include/device/uart.h
new file mode 100644
index 0000000..1724eb5
--- /dev/null
+++ b/include/device/uart.h
@@ -0,0 +1,19 @@
+#ifndef JOVE_KERNEL_ARCH_x86_64_UART_H
+#define JOVE_KERNEL_ARCH_x86_64_UART_H 1
+
+#include "jove.h"
+#include <stdint.h>
+
+ALWAYS_INLINE uint8_t pinb(uint16_t port)
+{
+ uint8_t v;
+ __asm__ volatile("inb %1, %0": "=a"(v): "Nd"(port));
+ return v;
+}
+
+ALWAYS_INLINE void poutb(uint16_t port, uint8_t b)
+{
+ __asm__ volatile("outb %0, %1":: "a"(b), "Nd"(port));
+}
+
+#endif
diff --git a/include/initrd.h b/include/initrd.h
new file mode 100644
index 0000000..7e7fe1e
--- /dev/null
+++ b/include/initrd.h
@@ -0,0 +1,17 @@
+#ifndef _JOVE_INITRD_H
+#define _JOVE_INITRD_H 1
+
+#include <stddef.h>
+
+typedef struct initrd_file {
+ void *header;
+ const char *name;
+ const void *data;
+ size_t size;
+} initrd_file_t;
+
+void initrd_setup(void);
+
+initrd_file_t *ird_getfile(const char *path);
+
+#endif
diff --git a/include/jove.h b/include/jove.h
new file mode 100644
index 0000000..2330492
--- /dev/null
+++ b/include/jove.h
@@ -0,0 +1,13 @@
+#ifndef JOVE_LIB_JOVE_H
+#define JOVE_LIB_JOVE_H 1
+
+#define ALWAYS_INLINE inline __attribute__((always_inline))
+#define PAGEALIGN __attribute__((aligned(0x1000)))
+
+extern void *_kernel_start;
+extern void *_kernel_end;
+
+__attribute__((noreturn)) void _kpanic(const char *file, int line, const char *fmt, ...);
+#define kpanic(...) _kpanic(__FILE__, __LINE__, __VA_ARGS__)
+
+#endif
diff --git a/include/memory.h b/include/memory.h
new file mode 100644
index 0000000..35198e6
--- /dev/null
+++ b/include/memory.h
@@ -0,0 +1,49 @@
+#ifndef _JOVE_MEMORY_H
+#define _JOVE_MEMORY_H 1
+
+#define KiB 1024ULL
+#define MiB (KiB * KiB)
+#define GiB (MiB * KiB)
+#define TiB (GiB * KiB)
+
+#include <stdbool.h>
+#include <stddef.h>
+#include "arch/page.h"
+
+typedef uintptr_t physptr_t;
+
+extern const uintptr_t USERLAND_MEMORY_BASE;
+extern const uintptr_t USERLAND_MEMORY_LIMIT;
+extern const uintptr_t PHYSMAP_MEMORY_BASE;
+extern const uintptr_t PHYSMAP_MEMORY_LIMIT;
+extern const uintptr_t KERNEL_MEMORY_BASE;
+extern const uintptr_t KERNEL_MEMORY_LIMIT;
+
+page_mapping_t vm_pd_mapping_get(page_directory_t *pd, uintptr_t addr);
+void vm_pd_mapping_set(page_directory_t *pd, page_mapping_t mapping, uintptr_t addr);
+void vm_pd_ensure(page_directory_t *pd, uintptr_t from, uintptr_t to, page_flags_t flg);
+
+page_mapping_t vm_mapping_get(uintptr_t addr);
+void vm_mapping_set(page_mapping_t mapping, uintptr_t virt);
+void vm_ensure(uintptr_t from, uintptr_t to, page_flags_t flg);
+
+physptr_t vm_tophys(uintptr_t virt);
+physptr_t vm_tophys_koff(uintptr_t virt);
+
+uintptr_t pm_tovirt(physptr_t phys);
+
+physptr_t pm_alloc(size_t pages);
+void pm_reserve(physptr_t start, physptr_t end);
+void pm_release(physptr_t start, physptr_t end);
+
+void mm_setup_early(void);
+void vm_setup_early(void);
+
+void mm_setup(void);
+void vm_setup(void);
+
+void* kmalloc(size_t width);
+void *krealloc(void *ptr, size_t width);
+void kfree(void *ptr);
+
+#endif
diff --git a/include/print.h b/include/print.h
new file mode 100644
index 0000000..38a1dbc
--- /dev/null
+++ b/include/print.h
@@ -0,0 +1,25 @@
+#ifndef _JOVE_PRINT_H
+#define _JOVE_PRINT_H 1
+
+#include <stdarg.h>
+
+enum {
+ PRINT_DEBUG = 0,
+ PRINT_LOG,
+ PRINT_WARN,
+ PRINT_ERROR
+};
+
+#define PRINT_BUFFERW 512
+
+void prawf(const char *fmt, ...);
+
+void _plogvf(const char *file, const char *func, int line, int lvl, const char *fmt, va_list ap);
+void _plogf(const char *file, const char *func, int line, int lvl, const char *fmt, ...);
+
+#define kdbgf(...) _plogf(__FILE__, __FUNCTION__, __LINE__, PRINT_DEBUG, __VA_ARGS__)
+#define klogf(...) _plogf(__FILE__, __FUNCTION__, __LINE__, PRINT_LOG , __VA_ARGS__)
+#define kwarnf(...) _plogf(__FILE__, __FUNCTION__, __LINE__, PRINT_WARN, __VA_ARGS__)
+#define kerrf(...) _plogf(__FILE__, __FUNCTION__, __LINE__, PRINT_ERROR, __VA_ARGS__)
+
+#endif
diff --git a/include/slab.h b/include/slab.h
new file mode 100644
index 0000000..04d42e4
--- /dev/null
+++ b/include/slab.h
@@ -0,0 +1,44 @@
+#ifndef JOVE_MEMORY_SLAB_H
+#define JOVE_MEMORY_SLAB_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#define SLABCACHE_NAME_LIMIT 32
+typedef struct slab_cache
+{
+ char name[SLABCACHE_NAME_LIMIT];
+
+ struct slab *list_free;
+ struct slab *list_partial;
+ struct slab *list_full;
+
+ size_t obj_count;
+ size_t obj_size;
+ size_t obj_capacity;
+
+ size_t slab_pages;
+} slab_cache_t;
+
+typedef struct slab
+{
+ struct slab *prev;
+ struct slab *next;
+ void *slab_base;
+ void *obj_base;
+
+ size_t free_count;
+ int free_index;
+ uintptr_t free[];
+} slab_t;
+
+void slabcache_new(slab_cache_t *cache, char *name, size_t objsize);
+
+void* slab_alloc(slab_cache_t *cache);
+void slab_free(slab_cache_t *cache, void *ptr);
+
+void* slab_get(slab_cache_t *cache, size_t index);
+void slab_set(slab_cache_t *cache, size_t index, void *data);
+
+#endif
diff --git a/include/string.h b/include/string.h
new file mode 100644
index 0000000..a91ec94
--- /dev/null
+++ b/include/string.h
@@ -0,0 +1,18 @@
+#ifndef JOVE_LIB_STRING_H
+#define JOVE_LIB_STRING_H 1
+
+#include <stddef.h>
+
+int toupper(int c);
+char *stoupper(char *s);
+char *sntoupper(char *s, size_t limit);
+
+size_t strlen(const char *s);
+
+void *memset(void *dest, int c, size_t n);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+int memcmp(const void *a, const void *b, size_t n);
+int strcmp(const char *a, const char *b);
+
+#endif
diff --git a/include/tasking.h b/include/tasking.h
new file mode 100644
index 0000000..04118a9
--- /dev/null
+++ b/include/tasking.h
@@ -0,0 +1,44 @@
+#ifndef _JOVE_TASKING_H
+#define _JOVE_TASKING_H 1
+
+#include "arch/page.h"
+#include <stddef.h>
+#include <stdbool.h>
+
+#define KERNEL_STACKW 4096
+
+typedef intmax_t tcbid_t;
+
+typedef enum
+{
+ TCB_RUNNING,
+ TCB_PAUSED,
+ TCB_DEAD
+} tcb_state_t;
+
+typedef struct task_control_block
+{
+ tcbid_t id;
+ void *stack;
+ uintptr_t sp, ksp;
+ page_directory_t *pd;
+ tcb_state_t state;
+
+ int exit_code;
+} tcb_t;
+
+void tasking_setup(void);
+
+tcb_t *tcb_new(void *ip, page_directory_t *pd);
+void tcb_prepare(tcb_t *tcb, void *ip);
+void tcb_kill(tcb_t *tcb, int code);
+
+void tcb_switch(tcb_t *to);
+
+void tcb_stack_push(tcb_t *tcb, void *data, size_t len);
+
+void kexec(void *ip, int kargc, char **kargv, int kenvc, char **kenvp);
+
+void *umode_stack_new(void);
+
+#endif
diff --git a/include/umode_vma.h b/include/umode_vma.h
new file mode 100644
index 0000000..23619be
--- /dev/null
+++ b/include/umode_vma.h
@@ -0,0 +1,10 @@
+#ifndef _JOVE_UMODE_VMA_H
+#define _JOVE_UMODE_VMA_H 1
+
+#include <stdbool.h>
+#include <stddef.h>
+
+int user_vma_read(void *dest, const void *src, size_t w);
+int user_vma_write(void *dest, const void *src, size_t w);
+
+#endif
diff --git a/include/zone.h b/include/zone.h
new file mode 100644
index 0000000..002d1fc
--- /dev/null
+++ b/include/zone.h
@@ -0,0 +1,38 @@
+#ifndef JOVE_MEM_ZONE_H
+#define JOVE_MEM_ZONE_H 1
+
+#include <stdint.h>
+#include "klib/buddymap.h"
+
+enum {
+ MEM_ZONE_STANDARD = 0, /* First GiB of physical memory. */
+ MEM_ZONE_HIGHER,
+ MEM_ZONE_COUNT
+};
+
+#define MEM_ZONE_STANDARD_BASE 0
+#define MEM_ZONE_STANDARD_LIMIT (1 * GiB)
+#define MEM_ZONE_HIGHER_BASE MEM_ZONE_STANDARD_LIMIT
+
+#define MEM_BUDDY_ORDERS 12
+struct PhysicalMemoryZone
+{
+ const char *name;
+
+ uintptr_t base;
+ uintptr_t limit;
+
+ struct BuddyMap freemap;
+};
+
+int pm_zone_for(uintptr_t addr);
+uintptr_t pm_zone_bound_lower(size_t zone);
+uintptr_t pm_zone_bound_upper(size_t zone);
+size_t pm_zone_pages_free(size_t zone);
+int pm_zone_resv(size_t zone, uintptr_t base, uintptr_t limit);
+int pm_zone_free(size_t zone, uintptr_t base, uintptr_t limit);
+uintptr_t pm_zone_alloc(size_t zone, size_t pages);
+
+void pm_zone_setup(void);
+
+#endif