summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2021-12-19 22:41:15 +0000
committerAda Christine <adachristine18@gmail.com>2021-12-19 22:41:15 +0000
commite303a03e7c96bc5bf7fa93f7b46ce63196893d7a (patch)
treef187b374feec85015d6df1f94db618a3f5cc893f /kernel
parentbff63a4337eb3388617d230970c5eb2684d6a215 (diff)
moving files around
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile39
-rw-r--r--kernel/cpu.c225
-rw-r--r--kernel/cpu.h9
-rw-r--r--kernel/entry.c69
-rw-r--r--kernel/exceptions.S54
-rw-r--r--kernel/exceptions.h7
-rw-r--r--kernel/kernel.ld33
-rw-r--r--kernel/kprint.c18
-rw-r--r--kernel/kprint.h5
-rw-r--r--kernel/main.c4
-rw-r--r--kernel/memory.c534
-rw-r--r--kernel/memory.h53
-rw-r--r--kernel/panic.c25
-rw-r--r--kernel/panic.h13
-rw-r--r--kernel/port.c14
-rw-r--r--kernel/port.h5
-rw-r--r--kernel/serial.c41
-rw-r--r--kernel/serial.h5
18 files changed, 0 insertions, 1153 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
deleted file mode 100644
index 407c4bb..0000000
--- a/kernel/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-include ../defaults.mk
-
-VPATH := ../lib
-
-TARGET := kernel.os
-.DEFAULT: $(TARGET)
-
-CFLAGS += -Wno-unused-const-variable -Wno-unused-function -fvisibility=hidden -g
-
-LIBDIRS += -L$(dir $(shell $(CC) -print-libgcc-file-name))
-LDSCRIPT := kernel.ld
-LDFLAGS += -z max-page-size=4096 --export-dynamic
-LOADLIBES := -lgcc
-
-SOBJS :=
-GOBJS := entry.o kprint.o serial.o port.o main.o memory.o \
- memset.o memcpy.o memmove.o memcmp.o cpu.o exceptions.o \
- panic.o
-IOBJS :=
-
-$(SOBJS): CFLAGS += -fPIC
-# __attribute__((interrupt)) requires -mgeneral-regs-only
-$(IOBJS): CFLAGS += -mgeneral-regs-only
-$(IOBJS) $(GOBJS): CFLAGS += -mcmodel=kernel
-
-OBJS := $(SOBJS) $(GOBJS) $(IOBJS)
-DEPS := $(patsubst %.o,%.d,$(OBJS))
-
-$(TARGET): $(LDSCRIPT) $(MAKEFILE_LIST)
-$(TARGET): $(OBJS)
-
-CLEANLIST := $(wildcard $(OBJS) $(TARGET))
-DCLEANLIST := $(wildcard $(DEPS))
-
-include ../rules.mk
--include $(DEPS)
-
-.DEFAULT: $(TARGET)
-
diff --git a/kernel/cpu.c b/kernel/cpu.c
deleted file mode 100644
index ed1a04e..0000000
--- a/kernel/cpu.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "cpu.h"
-#include "exceptions.h"
-
-#include <stdint.h>
-
-#define GDT_ENTRIES 16
-#define IDT_ENTRIES 256
-
-#define CODE_SEG_INDEX 1
-#define DATA_SEG_INDEX 2
-#define TASK_SEG_INDEX 3
-
-struct dtr64
-{
- uint16_t limit;
- uint64_t base;
-} __attribute__((packed));
-
-struct segment_descriptor
-{
- uint16_t limit0;
- uint16_t base0;
- uint8_t base16;
- uint8_t access;
- uint8_t flags_limit16;
- uint8_t base24;
-} __attribute__((packed));
-
-enum segment_descriptor_type
-{
- CODE64_SEG,
- DATA_SEG,
- TASK64_SEG,
-};
-
-struct gate_descriptor
-{
- uint16_t offset0;
- uint16_t selector;
- uint8_t ist;
- uint8_t access;
- uint16_t offset16;
- uint64_t offset32;
-} __attribute__((packed));
-
-enum gate_descriptor_type
-{
- INT64_GATE,
- TRAP64_GATE,
-};
-
-struct task64_segment
-{
- uint32_t reserved0;
- uint64_t rsp0;
- uint64_t rsp1;
- uint64_t rsp2;
- uint64_t reserved1;
- uint64_t ist[7];
- uint16_t reserved2;
- uint16_t iomap_base;
-};
-
-static struct segment_descriptor gdt[GDT_ENTRIES];
-static struct gate_descriptor idt[IDT_ENTRIES];
-static struct task64_segment tss;
-
-static void set_gdt(int index,
- uint64_t base,
- uint64_t limit,
- enum segment_descriptor_type type)
-{
- gdt[index].limit0 = limit & 0xffff;
- gdt[index].base0 = base & 0xffff;
- gdt[index].base16 = (base >> 16) & 0xff;
- gdt[index].flags_limit16 = (limit >> 16) & 0xf;
- gdt[index].base24 = (base >> 24) & 0xff;
-
- switch (type)
- {
- case CODE64_SEG:
- gdt[index].access = 0x9a;
- gdt[index].flags_limit16 |= 0xa0;
- break;
- case DATA_SEG:
- gdt[index].access = 0x92;
- gdt[index].flags_limit16 |= 0xc0;
- break;
- case TASK64_SEG:
- gdt[index].access = 0x89;
- //TODO: make this cleaner i don't like it
- gdt[index+1].limit0 = (base >> 32) & 0xffff;
- gdt[index+1].base0 = (base >> 48) & 0xffff;
- break;
- };
-}
-
-static void set_idt(int vec,
- uint16_t selector,
- uint64_t offset,
- enum gate_descriptor_type type)
-{
- idt[vec].offset0 = offset & 0xffff;
- idt[vec].selector = selector;
- idt[vec].offset16 = (offset >> 16) & 0xffff;
- idt[vec].offset32 = (offset >> 32) & 0xffffffff;
-
- switch (type)
- {
- case INT64_GATE:
- idt[vec].access = 0x8e;
- break;
- case TRAP64_GATE:
- idt[vec].access = 0x8f;
- break;
- }
-}
-
-void set_ist(int vec, int ist_index)
-{
- // non-destructively set the ist index.
- idt[vec].access |= ist_index & 0x7;
-}
-
-static void gdt_init(void)
-{
- set_gdt(CODE_SEG_INDEX, 0, (uint64_t)-1, CODE64_SEG);
- set_gdt(DATA_SEG_INDEX, 0, (uint64_t)-1, DATA_SEG);
- set_gdt(TASK_SEG_INDEX, (uint64_t)&tss, sizeof(tss) - 1, TASK64_SEG);
-
- struct dtr64 gdtr = {sizeof(gdt) - 1, (uint64_t)&gdt};
-
- __asm__ volatile
- (
- // can't have interrupts during GDT reload
- // but don't re-enable interrupts if they were already disabled
- "pushf\n"
- "cli\n"
- "lgdt %0\n"
- "mov %w2, %%ds\n"
- "mov %w2, %%es\n"
- "mov %w2, %%fs\n"
- "mov %w2, %%gs\n"
- "mov %w2, %%ss\n"
- // make a far return frame on the stack
- // [ss] @rsp+8
- // [rip] @rsp
- "pushq %1\n"
- "lea .Lflush(%%rip), %%rax\n"
- "push %%rax\n"
- // far return, now we're in the code segment
- // defined here.
- "lretq\n"
- ".Lflush:\n"
- "ltr %w3\n"
- "popf\n"
- // dependency on pre-boot GDT is now gone
- :
- : "m"(gdtr),
- "i"(CODE_SEG_INDEX << 3),
- "r"(DATA_SEG_INDEX << 3),
- "r"(TASK_SEG_INDEX << 3)
- );
-}
-
-static void idt_init(void)
-{
- struct dtr64 idtr = {sizeof(idt) - 1, (uint64_t)&idt};
-
- __asm__ volatile
- (
- // can't have interrupts enabled during IDT reload--obviously.
- // as with GDT don't re-enable interrupts if they were already
- // disabled.
- "pushf\n"
- "cli\n"
- "lidt %0\n"
- "popf\n"
- // much more straightforward than the gdt code.
- :: "m"(idtr)
- );
-}
-
-void cpu_init(void)
-{
- gdt_init();
- idt_init();
- exceptions_init();
-}
-
-void exceptions_init(void)
-{
- isr_install(PAGE_FAULT_VECTOR, &page_fault_isr, 0, 0);
-}
-
-void isr_install(int vec, void (*isr)(void), int trap, int ist)
-{
- enum gate_descriptor_type type = INT64_GATE;
-
- if (trap)
- {
- type = TRAP64_GATE;
- }
-
- set_idt(vec, CODE_SEG_INDEX << 3, (uint64_t)isr, type);
- if (ist)
- {
- set_ist(vec, ist);
- }
-}
-
-void ist_install(int ist, void *stack)
-{
- tss.ist[ist] = (uint64_t)stack;
-}
-
-void int_enable(void)
-{
- __asm__ ("sti");
-}
-
-void int_disable(void)
-{
- __asm__ ("cli");
-}
diff --git a/kernel/cpu.h b/kernel/cpu.h
deleted file mode 100644
index 56a4073..0000000
--- a/kernel/cpu.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-void cpu_init(void);
-
-void isr_install(int vec, void (*isr)(void), int ist, int trap);
-void ist_install(int ist, void *stack);
-
-void int_enable(void);
-void int_disable(void);
diff --git a/kernel/entry.c b/kernel/entry.c
deleted file mode 100644
index 5eecaf2..0000000
--- a/kernel/entry.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "cpu.h"
-#include "serial.h"
-#include "kprint.h"
-#include "memory.h"
-#include "panic.h"
-
-#include <loader/data_efi.h>
-
-#include <kernel/entry.h>
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdnoreturn.h>
-
-static void efi_memory_init(struct efi_memory_map_data *map)
-{
- // FIXME: bad girl shit: overwriting on aliased pointers.
- // this is a temporary solution to shortcomings with
- // loader boot data. it's sort-of OK because the memory_range struct
- // is smaller than EFI_MEMORY_DESCRIPTOR. it's still not good.
- struct memory_range *ranges = (struct memory_range *)map->data;
- int entries = map->size / map->descsize;
-
- for (int i = 0; i < entries; i++)
- {
- EFI_MEMORY_DESCRIPTOR *desc;
- desc = (EFI_MEMORY_DESCRIPTOR *)((char *)map->data + i * map->descsize);
-
- enum memory_range_type type;
- phys_addr_t base;
- size_t size;
-
- base = desc->PhysicalStart;
- size = desc->NumberOfPages * EFI_PAGE_SIZE;
-
- switch (desc->Type)
- {
- case EfiConventionalMemory:
- case EfiBootServicesData:
- case EfiBootServicesCode:
- case EfiLoaderData:
- case EfiLoaderCode:
- type = AVAILABLE_MEMORY;
- break;
- case SystemMemoryType:
- type = SYSTEM_MEMORY;
- break;
- default:
- type = RESERVED_MEMORY;
- }
-
- ranges[i].type = type;
- ranges[i].base = base;
- ranges[i].size = size;
- }
-
- memory_init(ranges, entries);
-}
-
-noreturn void kernel_entry(struct efi_boot_data *data)
-{
- (void)data;
- cpu_init();
- serial_init();
- kputs("<hacker voice> i'm in\r\n");
- efi_memory_init(data->memory_map);
- halt();
-}
diff --git a/kernel/exceptions.S b/kernel/exceptions.S
deleted file mode 100644
index 80d49ee..0000000
--- a/kernel/exceptions.S
+++ /dev/null
@@ -1,54 +0,0 @@
-.extern page_fault_handler
-
-.global page_fault_isr
-.type page_fault_isr, @function
-page_fault_isr:
- /* just in case something tried to be clever before */
- cld
- /* push param registers */
- push %rdi
- push %rsi
- push %rdx
- push %rcx
- push %r8
- push %r9
- /* collect parameters for page fault handler */
- mov 48(%rsp), %rdi /* error code is first parameter */
- mov %cr2, %rsi /* PFLA is next parameter */
- /* caller-saved registers */
- push %rax
- push %r10
- push %r11
- /* callee-saved registers */
- push %rbx
- push %rbp
- push %r12
- push %r13
- push %r14
- push %r15
- /* stack has to be aligned */
- mov %rsp, %rbp
- and $-16, %rsp
- call page_fault_handler
- mov %rbp, %rsp
- /* TODO: test for error code here and panic() */
- pop %r15
- pop %r14
- pop %r13
- pop %r12
- pop %rbp
- pop %rbx
- pop %r11
- pop %r10
- pop %rax
- pop %r9
- pop %r8
- pop %rcx
- pop %rdx
- pop %rsi
- pop %rdi
- /* unwind the error code from the stack */
- add $8, %rsp
- /* leave the isr */
- iretq
-.size page_fault_isr, . - page_fault_isr
diff --git a/kernel/exceptions.h b/kernel/exceptions.h
deleted file mode 100644
index 5d22284..0000000
--- a/kernel/exceptions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-extern void page_fault_isr(void);
-
-#define PAGE_FAULT_VECTOR 0xe
-
-void exceptions_init(void);
diff --git a/kernel/kernel.ld b/kernel/kernel.ld
deleted file mode 100644
index 47dcf3b..0000000
--- a/kernel/kernel.ld
+++ /dev/null
@@ -1,33 +0,0 @@
-ENTRY(kernel_entry)
-
-PROVIDE(k_virt_base = 0xffffffff80000000);
-
-SECTIONS
-{
- .text k_virt_base : AT(ADDR(.text) - k_virt_base)
- {
- PROVIDE(k_text_begin = .);
- *(.text)
- . = ALIGN(4K);
- PROVIDE(k_text_end = .);
- } =0xcc
-
- .data ALIGN(4K) : AT(ADDR(.data) - k_virt_base)
- {
- PROVIDE(k_data_begin = .);
- *(.rodata)
- *(.data)
- }
-
- .bss :
- {
- *(.bss)
- PROVIDE(k_data_end = .);
- }
-
- /DISCARD/ :
- {
- *(.eh_frame)
- }
-}
-
diff --git a/kernel/kprint.c b/kernel/kprint.c
deleted file mode 100644
index 0a15efd..0000000
--- a/kernel/kprint.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "kprint.h"
-#include "serial.h"
-
-int kputchar(int c)
-{
- return serial_putchar(c);
-}
-
-int kputs(const char *s)
-{
- while (*s)
- {
- kputchar(*s++);
- }
-
- return 0;
-}
-
diff --git a/kernel/kprint.h b/kernel/kprint.h
deleted file mode 100644
index 5b307a2..0000000
--- a/kernel/kprint.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-int kputchar(int c);
-int kputs(const char *s);
-
diff --git a/kernel/main.c b/kernel/main.c
deleted file mode 100644
index 2fb2e3e..0000000
--- a/kernel/main.c
+++ /dev/null
@@ -1,4 +0,0 @@
-void kernel_main(void)
-{
-}
-
diff --git a/kernel/memory.c b/kernel/memory.c
deleted file mode 100644
index 62f3a38..0000000
--- a/kernel/memory.c
+++ /dev/null
@@ -1,534 +0,0 @@
-#include "memory.h"
-#include "kprint.h"
-#include "panic.h"
-
-#include <stdint.h>
-
-#include <kernel/entry.h>
-#include <kernel/memory/paging.h>
-
-/* kernel virtual space guarantees
- *
- * the loader must set up the address space as follows
- * 1. kernel virtual space is 2GiB in size on 2GiB alignment.
- * 2. mappings begin at +0x7fc00000. this mapping space is sparse and its
- * own mapping tables begin at +0x7fffe000.
- */
-
-#define kpm1_index(v) (((uint64_t)v >> pte_index_bits(1)) & 0x7ffff)
-#define kpm2_index(v) (((uint64_t)v >> pte_index_bits(2)) & 0x3ff)
-
-#define align_next(v, a) (((uint64_t)v + a - 1) & ~(a - 1))
-
-// a conservative 128MB for kernel heap
-#define KERNEL_HEAP_SPACE_SIZE (128 << 20)
-
-typedef int (*page_fault_handler_func)(uint32_t code, void *address);
-
-enum memory_space_flags
-{
- SYSTEM_MEMORY_SPACE, // memory that cannot fault
- ANONYMOUS_MEMORY_SPACE, // memory that can fault
-};
-
-struct memory_space
-{
- enum memory_space_flags flags;
- page_fault_handler_func handler;
- void *base;
- void *head;
- struct memory_space *next;
- struct memory_space *prev;
-};
-
-struct page
-{
- uint32_t next: 31;
- uint32_t used: 1;
-};
-
-extern char k_virt_base;
-extern char k_text_begin;
-extern char k_text_end;
-extern char k_data_begin;
-extern char k_data_end;
-
-static struct page *const page_array = (struct page *)0xffffffd800000000;
-static int first_free_page_index = -1;
-static size_t page_array_entries = 0;
-static size_t free_pages = 0;
-
-// the temporary mapping place. never use this permanently.
-static void *const temp = (void *)0xffffffffffa00000;
-static uint64_t *const kernel_pm1 = (uint64_t *)0xffffffffffc00000;
-static uint64_t *const kernel_pm2 = (uint64_t *)0xffffffffffffe000;
-
-static uint64_t *get_kernel_pm1e(void *vaddr);
-static uint64_t *get_kernel_pm2e(void *vaddr);
-static void *get_virtual_page(enum page_map_flags flags);
-static void *page_map_at(void *vaddr, phys_addr_t paddr, enum page_map_flags flags);
-
-// handlers for memory space types
-int anonymous_page_handler(uint32_t code, void *address);
-
-// the system memory_space's that are always present
-static struct memory_space kernel_image_space;
-static struct memory_space kernel_stack_space;
-static struct memory_space kernel_pagemap_space;
-// the kernel's own heap space
-static struct memory_space kernel_heap_space;
-
-// NULL if the system address spaces are not set up
-static struct memory_space *root_memory_space;
-
-static struct memory_range init_grab_pages(struct memory_range *ranges,
- int count,
- size_t size)
-{
- struct memory_range request = {SYSTEM_MEMORY,
- 0,
- align_next(size, PAGE_SIZE)};
-
- for (int i = 0; i < count; i++)
- {
- if (ranges[i].type != AVAILABLE_MEMORY ||
- ranges[i].base < (1 << 20)) // leave pages below 1MiB alone.
- {
- continue;
- }
- else if (ranges[i].size > request.size)
- {
- request.base = ranges[i].base;
- ranges[i].base += request.size;
- ranges[i].size -= request.size;
- return request;
- }
- }
-
- request.type = INVALID_MEMORY;
- return request;
-}
-
-static size_t init_get_max_paddr(struct memory_range *ranges, int count)
-{
- phys_addr_t max_paddr = 0;
-
- // get the highest usable physical address in all memory ranges.
- for (int i = 0; i < count; i++)
- {
- if (ranges[i].type != AVAILABLE_MEMORY)
- {
- continue;
- }
-
- if ((ranges[i].base + ranges[i].size - 1) > max_paddr)
- {
- max_paddr = ranges[i].base + ranges[i].size - 1;
- }
- }
-
- return max_paddr;
-}
-
-static phys_addr_t get_kernel_pm4_phys(void)
-{
- phys_addr_t pm4_phys;
- __asm__ (
- "mov %%cr3, %0\n\t"
- : "=r"(pm4_phys)
- );
-
- return page_address(pm4_phys, 1);
-}
-
-static phys_addr_t get_kernel_pm3_phys(void)
-{
- phys_addr_t pm3_phys;
- // make a temporary mapping to read pm4
- uint64_t *pm4 = page_map_at(temp,
- get_kernel_pm4_phys(),
- CONTENT_RODATA|SIZE_2M);
-
- // pm3_phys is in pm4.
- pm3_phys = page_address(pm4[pte_index(&k_virt_base, 4)], 1);
- // never leave a temporary mapping
- page_unmap(pm4);
-
- return pm3_phys;
-}
-
-static void init_map_page_array_pm2(struct memory_range *pm2_pages)
-{
- // now we need to write the physical address of each pm2 page for the
- // page_array in the kernel's pm3.
- uint64_t *pm3 = page_map_at(temp,
- get_kernel_pm3_phys(),
- CONTENT_RWDATA|SIZE_2M);
-
- // the first index is NOT zero!
- for (size_t i = 0; i < (pm2_pages->size / PAGE_SIZE); i++)
- {
- pm3[pte_index(page_array, 3) + i] = (pm2_pages->base + i *
- PAGE_SIZE)|PAGE_NX|PAGE_WR|PAGE_PR;
- }
- // never forget to unmap temporary mappings.
- page_unmap(pm3);
-}
-
-static void init_create_page_array_map(struct memory_range *pages,
- struct memory_range *maps)
-{
- // indices for page_array always start at 0
- size_t entry_count = pages->size / PAGE_SIZE;
-
- // every 512 entries we need to re-map and clean.
- for (size_t i = 0; i < entry_count; i += PAGE_TABLE_INDEX_MASK)
- {
- uint64_t *pm1 = page_map_at(temp,
- maps->base + i * PAGE_SIZE,
- CONTENT_RWDATA|SIZE_2M);
- memset(pm1, 0, PAGE_SIZE);
- for (size_t j = 0;
- (j < PAGE_TABLE_INDEX_MASK) && ((j + i) < entry_count);
- j++)
- {
- pm1[j] = (pages->base + (i + j) * PAGE_SIZE)|
- PAGE_NX|PAGE_WR|PAGE_PR;
- }
-
- page_unmap(pm1);
- }
-}
-
-static void init_set_memory_range(struct memory_range *range)
-{
- for (size_t i = 0; i < range->size / PAGE_SIZE; i++)
- {
- if (range->base / PAGE_SIZE + i > page_array_entries)
- {
- return;
- }
-
- if (range->type == AVAILABLE_MEMORY)
- {
- page_free(range->base + PAGE_SIZE * i);
- }
- else
- {
- struct page *page = &page_array[range->base / PAGE_SIZE + i];
- page->used = 1;
- }
- }
-}
-
-static void init_populate_page_array(struct memory_range *ranges, int count)
-{
- for (int i = 0; i < count; i++)
- {
- init_set_memory_range(&ranges[i]);
- }
-}
-
-static void init_create_page_array(struct memory_range *ranges, int count)
-{
- // the highest actual physical memory address.
- size_t max_paddr = init_get_max_paddr(ranges, count);
- page_array_entries = max_paddr / page_size(1);
- size_t page_array_size = page_array_entries * sizeof(struct page);
-
- // the physical pages that will contain page_array
- struct memory_range pa_pages = init_grab_pages(ranges, count, page_array_size);
-
- // the number of page tables needed to map pa_pages
- // this will be 1 on systems with less than 2GB of memory.
- size_t pm1_count = page_count(pa_pages.size, 2);
- struct memory_range pm1_pages = init_grab_pages(ranges,
- count,
- pm1_count * page_size(1));
-
- init_create_page_array_map(&pa_pages, &pm1_pages);
-
- // the number of page directories needed to map pa_pages
- // this will be 1 on systems with less than 1TB of memory.
- // who the fuck has 1TB of memory lol
- size_t pm2_count = page_count(pa_pages.size, 3);
- struct memory_range pm2_pages = init_grab_pages(ranges,
- count,
- pm2_count * page_size(1));
-
- init_create_page_array_map(&pm1_pages, &pm2_pages);
-
- // ok here goes
- init_map_page_array_pm2(&pm2_pages);
-
- memset(page_array, 0, page_array_size);
-
- init_populate_page_array(ranges, count);
- init_populate_page_array(&pa_pages, 1);
- init_populate_page_array(&pm1_pages, 1);
- init_populate_page_array(&pm2_pages, 1);
-}
-
-static struct memory_space init_system_space(void *base, void *head)
-{
- struct memory_space space = {SYSTEM_MEMORY_SPACE, NULL, base, head, NULL, NULL};
- return space;
-}
-
-static struct memory_space init_anonymous_space(void *base, void *head)
-{
- struct memory_space space = {ANONYMOUS_MEMORY_SPACE,
- &anonymous_page_handler,
- base,
- head,
- NULL,
- NULL};
-
- return space;
-}
-
-void memory_init(struct memory_range *ranges, int count)
-{
- init_create_page_array(ranges, count);
- // initialize always-present memory spaces for the vmm
- kernel_image_space = init_system_space((void *)&k_text_begin,
- (void *)align_next(&k_data_end, PAGE_SIZE));
- kernel_stack_space = init_system_space((void *)KERNEL_ENTRY_STACK_BASE,
- (void *)KERNEL_ENTRY_STACK_HEAD);
- kernel_pagemap_space = init_system_space(kernel_pm1, (void *)-1LL);
-
- // initialize the kernel heap space
- kernel_heap_space = init_anonymous_space(kernel_image_space.head,
- (char *)kernel_image_space.head +
- KERNEL_HEAP_SPACE_SIZE);
-
- // set up the list links
- kernel_image_space.next = &kernel_heap_space;
- kernel_heap_space.prev = &kernel_image_space;
- kernel_heap_space.next = &kernel_stack_space;
- kernel_stack_space.prev = &kernel_heap_space;
- kernel_stack_space.next = &kernel_pagemap_space;
- kernel_pagemap_space.prev = &kernel_stack_space;
-
- root_memory_space = &kernel_image_space;
-}
-
-static void *page_map_at(void *vaddr,
- phys_addr_t paddr,
- enum page_map_flags flags)
-{
- uint64_t entry = PAGE_PR;
-
- switch (flags & CONTENT_MASK)
- {
- case CONTENT_RODATA:
- entry |= PAGE_NX;
- break;
- case CONTENT_RWDATA:
- entry |= PAGE_NX|PAGE_WR;
- break;
- default:
- break;
- }
-
- size_t offset;
- uint64_t *pte;
-
- switch (flags & SIZE_MASK)
- {
- case SIZE_2M:
- entry |= page_address(paddr, 2)|PAGE_LG;
- offset = page_offset(paddr, 2);
- pte = get_kernel_pm2e(vaddr);
- break;
- case SIZE_4K:
- entry |= page_address(paddr, 1);
- offset = page_offset(paddr, 1);
- pte = get_kernel_pm1e(vaddr);
- break;
- default:
- offset = 0;
- pte = NULL;
- }
-
- if (!pte)
- {
- return NULL;
- }
-
- *pte = entry;
- return (char *)vaddr + offset;
-}
-
-void *page_map(phys_addr_t paddr, enum page_map_flags flags)
-{
- return page_map_at(get_virtual_page(flags), paddr, flags);
-}
-
-void page_unmap(void *vaddr)
-{
- uint64_t *pte = get_kernel_pm2e(vaddr);
-
- if (pte && !(*pte & PAGE_LG))
- {
- pte = get_kernel_pm1e(vaddr);
- }
-
- if (pte)
- {
- *pte = 0;
- }
- __asm__ ("invlpg (%0)" :: "r"(vaddr));
-}
-
-phys_addr_t page_alloc(void)
-{
- int index = first_free_page_index;
-
- if (index > 0)
- {
- page_array[index].used = 1;
- first_free_page_index = page_array[index].next;
- free_pages--;
- }
-
- return (phys_addr_t)index * page_size(1);
-}
-
-void page_free(phys_addr_t paddr)
-{
- int index = paddr / page_size(1);
-
- if ((size_t)index > page_array_entries)
- {
- return;
- }
-
- page_array[index].used = 0;
- page_array[index].next = first_free_page_index;
- first_free_page_index = index;
- free_pages++;
-}
-
-void *heap_alloc(size_t size)
-{
- (void)size;
- return NULL;
-}
-
-void heap_free(void *block)
-{
- (void)block;
-}
-
-void *memory_alloc(size_t size)
-{
- (void)size;
- return NULL;
-}
-
-void memory_free(void *block)
-{
- (void)block;
-}
-
-static uint64_t *get_kernel_pm1e(void *vaddr)
-{
- return &kernel_pm1[kpm1_index(vaddr)];
-}
-
-static uint64_t *get_kernel_pm2e(void *vaddr)
-{
- return &kernel_pm2[kpm2_index(vaddr)];
-}
-
-static void *get_virtual_page(enum page_map_flags flags)
-{
- (void)flags;
- return NULL;
-}
-
-static struct memory_space *get_memory_space(void *address)
-{
- // walk the memory space list
- struct memory_space *space = root_memory_space;
-
- while (space)
- {
- if (space->base >= address && address <= space->head)
- {
- return space;
- }
- space = space->next;
- }
-
- return NULL;
-}
-
-int anonymous_page_handler(uint32_t code, void *address)
-{
- if (code & PAGE_PR)
- {
- // there's no reason a protection violation should happen
- // in anonymous space
- panic(UNHANDLED_FAULT);
- }
- kputs("anonymous fault\n");
- // kernel page mappings are built different
- if (address >= (void *)&k_virt_base)
- {
- uint64_t *pm2e = get_kernel_pm2e(address);
-
- if (!page_address(*pm2e, 1))
- {
- // create a page table and install it
- phys_addr_t pm1_phys = page_alloc();
- if (pm1_phys)
- {
- uint64_t *pm1;
- pm1 = page_map_at(temp, pm1_phys, CONTENT_RWDATA|SIZE_2M);
- // zero the page
- memset(pm1, 0, PAGE_SIZE);
- // put the table where it goes
- *pm2e = page_address(pm1_phys, 1)|PAGE_WR|PAGE_PR;
- page_unmap(pm1);
- }
- else
- {
- panic(OUT_OF_MEMORY);
- }
- }
-
- uint64_t *pm1e = get_kernel_pm1e(address);
-
- if (pm1e)
- {
- phys_addr_t page_phys = page_alloc();
- if (page_phys)
- {
- *pm1e = page_address(page_phys, 1)|PAGE_WR|PAGE_PR;
- // clear a potentially dirty page.
- memset((void *)page_address(address, 1), 0, page_size(1));
- }
- }
- }
-
- return 0;
-}
-
-int page_fault_handler(uint32_t code, void *address)
-{
- kputs("page faulmt\n");
- struct memory_space *space = get_memory_space(address);
- if (space && space->handler)
- {
- int result = space->handler(code, address);
-
- if (result)
- {
- panic(UNHANDLED_FAULT);
- }
- }
-
- return 0;
-}
diff --git a/kernel/memory.h b/kernel/memory.h
deleted file mode 100644
index 67b0648..0000000
--- a/kernel/memory.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <kernel/memory/paging.h>
-#include <kernel/memory/range.h>
-
-#include <stddef.h>
-
-typdef int (*memory_space_handler_func)(uint32_t code, void *vaddr);
-
-enum page_map_flags
-{
- CONTENT_CODE = 0x1,
- CONTENT_RODATA = 0x2,
- CONTENT_RWDATA = 0x3,
- CONTENT_MASK = 0x3,
-
- SIZE_4K = 0x4,
- SIZE_2M = 0x8,
- SIZE_1G = 0xc,
- SIZE_MASK = 0xc,
-};
-
-enum memory_space_flags
-{
- SYSTEM_SPACE = 0x1, // memory cannot be swapped
-};
-
-struct memory_space
-{
- enum memory_space_flags flags;
- memory_space_handler_func handler;
- void *base;
- void *head;
-};
-
-void memory_init(struct memory_range *ranges, int count);
-
-void *memcpy(void *dest, const void *src, size_t size);
-void *memmove(void *dest, const void *src, size_t size);
-void *memset(void *dest, int val, size_t size);
-int memcmp(const void *str1, const void *str2, size_t count);
-
-void *page_map(phys_addr_t paddr, enum page_map_flags flags);
-void page_unmap(void *vaddr);
-
-phys_addr_t page_alloc(void);
-void page_free(phys_addr_t paddr);
-
-void *heap_alloc(size_t size);
-void heap_free(void *block);
-
-void *memory_alloc(size_t size);
-void memory_free(void *block);
diff --git a/kernel/panic.c b/kernel/panic.c
deleted file mode 100644
index b0d9daf..0000000
--- a/kernel/panic.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "panic.h"
-#include "kprint.h"
-
-#include <stdbool.h>
-
-static char const *reason_strings[] = {
- "general panic",
- "unhandled fault",
- "out of memory"
-};
-
-noreturn void panic(enum panic_reason reason)
-{
- // TODO: kprintf() and friends
- kputs("kernel panic: ");
- kputs(reason_strings[reason]);
- kputs("\n");
- halt();
-}
-
-noreturn void halt(void)
-{
- __asm__ ("cli\n\t");
- while (true) __asm__ ("hlt\n\t");
-}
diff --git a/kernel/panic.h b/kernel/panic.h
deleted file mode 100644
index 0cfd7c2..0000000
--- a/kernel/panic.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <stdnoreturn.h>
-
-enum panic_reason
-{
- GENERAL_PANIC,
- UNHANDLED_FAULT,
- OUT_OF_MEMORY,
-};
-
-noreturn void panic(enum panic_reason reason);
-noreturn void halt(void);
diff --git a/kernel/port.c b/kernel/port.c
deleted file mode 100644
index 17af396..0000000
--- a/kernel/port.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "port.h"
-
-uint8_t inb(uint16_t port)
-{
- uint8_t data;
- __asm__ ("inb %1, %0" : "=a"(data) : "d"(port));
- return data;
-}
-
-void outb(uint16_t port, uint8_t data)
-{
- __asm__ ("outb %0, %1" :: "a"(data), "d"(port));
-}
-
diff --git a/kernel/port.h b/kernel/port.h
deleted file mode 100644
index cc71973..0000000
--- a/kernel/port.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <stdint.h>
-
-uint8_t inb(uint16_t port);
-void outb(uint16_t port, uint8_t data);
-
diff --git a/kernel/serial.c b/kernel/serial.c
deleted file mode 100644
index 77f453d..0000000
--- a/kernel/serial.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "serial.h"
-#include "port.h"
-
-#define PORT 0x3f8 // COM1
-
-static int is_transmit_empty(void);
-
-int serial_init(void) {
- outb(PORT + 0, 0x00); // Disable all interrupts
- outb(PORT + 2, 0x80); // Enable DLAB (set baud rate divisor)
- outb(PORT + -1, 0x03); // Set divisor to 3 (lo byte) 38400 baud
- outb(PORT + 0, 0x00); // (hi byte)
- outb(PORT + 2, 0x03); // 8 bits, no parity, one stop bit
- outb(PORT + 1, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
- outb(PORT + 3, 0x0B); // IRQs enabled, RTS/DSR set
- outb(PORT + 3, 0x1E); // Set in loopback mode, test the serial chip
- outb(PORT + -1, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
-
- // Check if serial is faulty (i.e: not same byte as sent)
- if(inb(PORT + -1) != 0xAE) {
- return 0;
- }
-
- // If serial is not faulty set it in normal operation mode
- // (not-loopback with IRQs enabled and OUT#0 and OUT#2 bits enabled)
- outb(PORT + 3, 0x0F);
- return -1;
-}
-
-int serial_putchar(int c)
-{
- while (is_transmit_empty() == 0);
- outb(PORT,(char)c);
- return c;
-}
-
-static int is_transmit_empty(void)
-{
- return inb(PORT + 5) & 0x20;
-}
-
diff --git a/kernel/serial.h b/kernel/serial.h
deleted file mode 100644
index 2e22fa6..0000000
--- a/kernel/serial.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-int serial_init(void);
-int serial_putchar(int c);
-