summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2021-07-10 17:41:32 +0200
committerdzwdz2021-07-10 17:41:32 +0200
commit1bf5e324005ce7122a195af106cec656960648dc (patch)
tree7a8394a5243ad50d1e8d5574d94908461fe96cc6 /src/kernel
parent6cbdc62b5cbe34d7355047722d6d483a4d25c7f3 (diff)
a sensible source structure
The idea is that src/kernel/ is only allowed to interface with the hardware using whatever's defined in src/arch/generic.h. I'll probably write a small script for checking this later on. This is a giant commit so I've probably fucked something up. It boots fine on Bochs and QEMU, so at least there's that.
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/gdt.c121
-rw-r--r--src/kernel/gdt.h15
-rw-r--r--src/kernel/idt.c75
-rw-r--r--src/kernel/idt.h3
-rw-r--r--src/kernel/isr.c24
-rw-r--r--src/kernel/isr.h15
-rw-r--r--src/kernel/main.c15
-rw-r--r--src/kernel/main.h3
-rw-r--r--src/kernel/mem.c1
-rw-r--r--src/kernel/mem.h2
-rw-r--r--src/kernel/panic.h4
-rw-r--r--src/kernel/proc.c2
-rw-r--r--src/kernel/tty.c38
-rw-r--r--src/kernel/tty.h8
14 files changed, 9 insertions, 317 deletions
diff --git a/src/kernel/gdt.c b/src/kernel/gdt.c
deleted file mode 100644
index b0d6320..0000000
--- a/src/kernel/gdt.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <kernel/gdt.h>
-#include <kernel/util.h>
-#include <stdint.h>
-
-extern void stack_top; // platform/boot.s
-
-struct gdt_entry {
- uint64_t limit_low : 16;
- uint64_t base_low : 24;
- uint64_t accessed : 1; // set by the processor
- // CODE | DATA
- uint64_t rw : 1; // readable? | writeable?
- uint64_t conforming : 1; // conforming? | expands down?
- uint64_t code : 1; // 1 | 0
-
- uint64_t codeordata : 1; // 1 for everything other than TSS and LDT
- uint64_t ring : 2;
- uint64_t present : 1; // always 1
- uint64_t limit_high : 4;
- uint64_t available : 1; // ???
- uint64_t long_mode : 1;
- uint64_t x32 : 1;
- uint64_t gran : 1; // 1 - 4kb, 0 - 1b
- uint64_t base_high : 8;
-} __attribute__((packed));
-
-struct tss_entry {
- uint32_t prev_tss; // unused
- uint32_t esp0; // kernel mode stack pointer
- uint32_t ss0; // kernel mode stack segment
- // total size = 0x68 (?) - 3 * sizeof(uint32_t) = 5c
- uint8_t _unused[0x5c];
-} __attribute__((packed));
-
-struct lgdt_arg {
- uint16_t limit;
- uint32_t base;
-} __attribute__((packed));
-
-static struct gdt_entry GDT[SEG_end];
-static struct tss_entry TSS;
-static struct lgdt_arg lgdt_arg; // probably doesn't need to be global
-
-static void gdt_prepare();
-static void gdt_load();
-
-
-static void gdt_prepare() {
- GDT[SEG_null].present = 0;
-
- GDT[SEG_r0data].limit_low = 0xFFFF;
- GDT[SEG_r0data].limit_high = 0xF;
- GDT[SEG_r0data].gran = 1; // 4KB * 0xFFFFF = (almost) 4GB
- GDT[SEG_r0data].base_low = 0;
- GDT[SEG_r0data].base_high = 0;
- GDT[SEG_r0data].accessed = 0;
- GDT[SEG_r0data].rw = 1;
- GDT[SEG_r0data].conforming = 0;
- GDT[SEG_r0data].code = 0;
- GDT[SEG_r0data].codeordata = 1;
- GDT[SEG_r0data].ring = 0;
- GDT[SEG_r0data].present = 1;
- GDT[SEG_r0data].long_mode = 0; // ???
- GDT[SEG_r0data].available = 1; // ???
- GDT[SEG_r0data].x32 = 1;
-
- // copy to r0 code
- GDT[SEG_r0code] = GDT[SEG_r0data];
- GDT[SEG_r0code].code = 1;
-
- GDT[SEG_r3data] = GDT[SEG_r0data];
- GDT[SEG_r3data].ring = 3;
- GDT[SEG_r3code] = GDT[SEG_r0code];
- GDT[SEG_r3code].ring = 3;
-
- // tss
- memset(&TSS, 0, sizeof(TSS));
- TSS.ss0 = SEG_r0data << 3; // kernel data segment
- TSS.esp0 = (uint32_t) &stack_top;
-
- GDT[SEG_TSS].limit_low = sizeof(TSS);
- GDT[SEG_TSS].base_low = (uint32_t) &TSS;
- GDT[SEG_TSS].accessed = 1; // 1 for TSS
- GDT[SEG_TSS].rw = 0; // 1 busy / 0 not busy
- GDT[SEG_TSS].conforming = 0; // 0 for TSS
- GDT[SEG_TSS].code = 1; // 32bit
- GDT[SEG_TSS].codeordata = 0; // is a system entry
- GDT[SEG_TSS].ring = 3;
- GDT[SEG_TSS].present = 1;
- GDT[SEG_TSS].limit_high = (sizeof(TSS) >> 16) & 0xf;
- GDT[SEG_TSS].available = 0; // 0 for TSS
- GDT[SEG_TSS].long_mode = 0;
- GDT[SEG_TSS].x32 = 0; // idk
- GDT[SEG_TSS].gran = 0;
- GDT[SEG_TSS].base_high = (((uint32_t) &TSS) >> 24) & 0xff;
-}
-
-void change_cs(int seg); // temporary
-
-static void gdt_load() {
- lgdt_arg.limit = sizeof(GDT) - 1;
- lgdt_arg.base = (uint32_t) &GDT;
- asm("lgdt (%0)"
- : : "r" (&lgdt_arg) : "memory");
- asm("ltr %%ax"
- : : "a" (SEG_TSS << 3 | 3) : "memory");
-
- // update all segment registers
- change_cs(SEG_r0code << 3);
- asm("mov %0, %%ds;"
- "mov %0, %%ss;"
- "mov %0, %%es;"
- "mov %0, %%fs;"
- "mov %0, %%gs;"
- : : "r" (SEG_r0data << 3) : "memory");
-}
-
-void gdt_init() {
- gdt_prepare();
- gdt_load();
-}
diff --git a/src/kernel/gdt.h b/src/kernel/gdt.h
deleted file mode 100644
index 9e5a6a5..0000000
--- a/src/kernel/gdt.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-enum {
- SEG_null,
- // order dictated by SYSENTER
- SEG_r0code,
- SEG_r0data,
- SEG_r3code,
- SEG_r3data,
- SEG_TSS,
-
- SEG_end
-};
-
-void gdt_init();
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
deleted file mode 100644
index 65f511f..0000000
--- a/src/kernel/idt.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <kernel/gdt.h>
-#include <kernel/idt.h>
-#include <kernel/isr.h>
-#include <kernel/panic.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-struct idt_entry {
- uint16_t offset_low ;
- uint16_t code_seg ;
- uint8_t zero ; // unused, has to be 0
- uint8_t type : 4; // 16/32 bit, task/interrupt/task gate
- uint8_t storage : 1; // 0 for interrupt/trap gates
- uint8_t ring : 2;
- uint8_t present : 1;
- uint16_t offset_high ;
-} __attribute__((packed));
-
-// is exactly the same as lgdt_arg, i should combine them into a single struct
-// later
-struct lidt_arg {
- uint16_t limit;
- uint32_t base;
-} __attribute__((packed));
-
-
-static struct idt_entry IDT[256];
-static struct lidt_arg lidt_arg;
-
-static inline void idt_add(uint8_t num, bool user, void (*isr));
-static void idt_prepare();
-static void idt_load();
-static void idt_test();
-
-
-static inline void idt_add(uint8_t num, bool user, void (*isr)) {
- uintptr_t offset = (uintptr_t) isr;
-
- IDT[num] = (struct idt_entry) {
- .offset_low = offset,
- .offset_high = offset >> 16,
- .code_seg = SEG_r0code << 3,
- .zero = 0,
- .present = 1,
- .ring = user ? 3 : 0,
- .storage = 0,
- .type = 0xE, // 32-bit interrupt gate
- };
-}
-
-static void idt_prepare() {
- for (int i = 0; i < 256; i++)
- IDT[i].present = 0;
-
- idt_add(0x08, false, isr_double_fault);
- idt_add(0x0d, false, isr_general_protection_fault);
- idt_add(0x34, false, isr_test_interrupt);
-}
-
-static void idt_load() {
- lidt_arg.limit = sizeof(IDT) - 1;
- lidt_arg.base = (uintptr_t) &IDT;
- asm("lidt (%0)" : : "r" (&lidt_arg) : "memory");
-}
-
-static void idt_test() {
- asm("int $0x34" : : : "memory");
- if (!isr_test_interrupt_called) panic();
-}
-
-void idt_init() {
- idt_prepare();
- idt_load();
- idt_test();
-}
diff --git a/src/kernel/idt.h b/src/kernel/idt.h
deleted file mode 100644
index 5627657..0000000
--- a/src/kernel/idt.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-void idt_init();
diff --git a/src/kernel/isr.c b/src/kernel/isr.c
deleted file mode 100644
index b715de0..0000000
--- a/src/kernel/isr.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <kernel/isr.h>
-#include <kernel/panic.h>
-#include <kernel/tty.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-bool isr_test_interrupt_called = false;
-
-__attribute__((interrupt))
-void isr_double_fault(struct interrupt_frame *frame) {
- tty_const("#DF");
- panic();
-}
-
-__attribute__((interrupt))
-void isr_general_protection_fault(struct interrupt_frame *frame) {
- tty_const("#GP");
- panic();
-}
-
-__attribute__((interrupt))
-void isr_test_interrupt(struct interrupt_frame *frame) {
- isr_test_interrupt_called = true;
-}
diff --git a/src/kernel/isr.h b/src/kernel/isr.h
deleted file mode 100644
index 150fc46..0000000
--- a/src/kernel/isr.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-#include <stdbool.h>
-
-struct interrupt_frame;
-
-extern bool isr_test_interrupt_called; // used in the self-test in idt.c
-
-__attribute__((interrupt))
-void isr_double_fault(struct interrupt_frame *frame);
-
-__attribute__((interrupt))
-void isr_general_protection_fault(struct interrupt_frame *frame);
-
-__attribute__((interrupt))
-void isr_test_interrupt(struct interrupt_frame *frame);
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 0193514..aa67d7c 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -1,22 +1,11 @@
-#include <kernel/gdt.h>
-#include <kernel/idt.h>
+#include <arch/generic.h>
#include <kernel/mem.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
-#include <kernel/tty.h>
-#include <platform/asm.h>
void r3_test();
-void kmain()
-{
- tty_clear();
- tty_const("gdt...");
- gdt_init();
- tty_const("idt...");
- idt_init();
- tty_const("sysenter...");
- sysenter_setup();
+void kmain() {
tty_const("mem...");
mem_init();
diff --git a/src/kernel/main.h b/src/kernel/main.h
new file mode 100644
index 0000000..6f27386
--- /dev/null
+++ b/src/kernel/main.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void kmain();
diff --git a/src/kernel/mem.c b/src/kernel/mem.c
index 08eb285..f383e8b 100644
--- a/src/kernel/mem.c
+++ b/src/kernel/mem.c
@@ -1,3 +1,4 @@
+#include <arch/generic.h>
#include <kernel/mem.h>
extern void *_kernel_end;
diff --git a/src/kernel/mem.h b/src/kernel/mem.h
index e8e6a4f..efa65d6 100644
--- a/src/kernel/mem.h
+++ b/src/kernel/mem.h
@@ -1,8 +1,6 @@
#pragma once
#include <stddef.h>
-#define PAGE_SIZE 4096
-
void mem_init();
// allocates `pages` consecutive pages
diff --git a/src/kernel/panic.h b/src/kernel/panic.h
index 7d2ea5f..54a0b8b 100644
--- a/src/kernel/panic.h
+++ b/src/kernel/panic.h
@@ -1,6 +1,6 @@
#pragma once
-#include <kernel/tty.h>
-#include <platform/asm.h>
+#include <arch/generic.h>
+#include <arch/i386/tty.h> // TODO abstract away
// dumb c shit
#define panic_tostr2(x) #x
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 776238c..7d42bce 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -1,6 +1,6 @@
+#include <arch/generic.h>
#include <kernel/mem.h>
#include <kernel/proc.h>
-#include <platform/asm.h>
struct process *process_current;
diff --git a/src/kernel/tty.c b/src/kernel/tty.c
deleted file mode 100644
index 5c4c47d..0000000
--- a/src/kernel/tty.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* will be moved to userspace later on */
-
-#include <kernel/tty.h>
-
-struct vga_cell {
- unsigned char c;
- unsigned char style;
-} __attribute__((__packed__));
-
-static const size_t vga_len = 80 * 25;
-static struct vga_cell *vga = (void*) 0xB8000;
-static size_t vga_pos = 0;
-
-static void tty_scroll() {
- for (int i = 0; i < vga_len - 80; i++) {
- vga[i] = vga[i + 80];
- }
- vga_pos -= 80;
-}
-
-void tty_putchar(char c)
-{
- if (vga_pos >= vga_len - 80) tty_scroll();
- vga[vga_pos++].c = c;
-}
-
-void tty_write(const char *buf, size_t len)
-{
- for (size_t i = 0; i < len; i++) {
- tty_putchar(buf[i]);
- }
-}
-
-void tty_clear() {
- for (size_t i = 0; i < vga_len; i++)
- vga[i].c = ' ';
- vga_pos = 0;
-}
diff --git a/src/kernel/tty.h b/src/kernel/tty.h
deleted file mode 100644
index 3dc1525..0000000
--- a/src/kernel/tty.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-#include <stddef.h>
-
-void tty_putchar(char c);
-void tty_write(const char *buf, size_t len);
-void tty_clear();
-
-#define tty_const(str) tty_write(str, sizeof(str) - 1)