aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-02-01 11:33:16 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-02-01 11:33:16 -0500
commit439d724ce5939cab7a5c858d1829f212e01e0402 (patch)
tree154afa843a96e4cebd4d4f4f480f36415668d620 /kernel
parent1d7843c2b6d746376f87c2634c92cd93d8cdb728 (diff)
downloadkappa-439d724ce5939cab7a5c858d1829f212e01e0402.zip
kappa-439d724ce5939cab7a5c858d1829f212e01e0402.tar.gz
kappa-439d724ce5939cab7a5c858d1829f212e01e0402.tar.bz2
kappa-439d724ce5939cab7a5c858d1829f212e01e0402.tar.xz
first real commit
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gdt-as.S16
-rw-r--r--kernel/gdt.c33
-rw-r--r--kernel/include/gdt.h23
-rw-r--r--kernel/include/io.h4
-rw-r--r--kernel/io.c19
-rw-r--r--kernel/linker.ld44
-rw-r--r--kernel/main.c14
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/ssp.c19
9 files changed, 174 insertions, 0 deletions
diff --git a/kernel/gdt-as.S b/kernel/gdt-as.S
new file mode 100644
index 0000000..7283dc8
--- /dev/null
+++ b/kernel/gdt-as.S
@@ -0,0 +1,16 @@
+ .global gdt_flush
+ .type gdt_flush, @function
+gdt_flush: # prototype: void gdt_flush(uint32_t addr)
+ cli
+ movl 4(%esp), %eax # load the address off the stack (first param)
+ lgdt (%eax)
+ mov $0x10, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+ sti
+ jmp .flush
+.flush:
+ ret
diff --git a/kernel/gdt.c b/kernel/gdt.c
new file mode 100644
index 0000000..f9b2d86
--- /dev/null
+++ b/kernel/gdt.c
@@ -0,0 +1,33 @@
+#include "gdt.h"
+
+static void gdt_set_gate(int idx, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran)
+{
+ /* Setup the descriptor base address */
+ gdt[idx].base_low = (base & 0xFFFF);
+ gdt[idx].base_middle = (base >> 16) & 0xFF;
+ gdt[idx].base_high = (base >> 24) & 0xFF;
+
+ /* Setup the descriptor limits */
+ gdt[idx].limit_low = (limit & 0xFFFF);
+ gdt[idx].granularity = ((limit >> 16) & 0x0F);
+
+ /* Finally, set up the granularity and access flags */
+ gdt[idx].granularity |= (gran & 0xF0);
+ gdt[idx].access = access;
+}
+
+void gdt_init(void)
+{
+ gp.limit = (sizeof(struct gdt_entry) * sizeof(gdt)/sizeof(gdt[0])) - 1;
+ gp.base = (uint32_t)&gdt;
+
+ gdt_set_gate(0, 0, 0, 0, 0);
+
+ /* code segment */
+ gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
+
+ /* data segment */
+ gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
+
+ gdt_flush((uint32_t)&gp);
+}
diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h
new file mode 100644
index 0000000..e93c92a
--- /dev/null
+++ b/kernel/include/gdt.h
@@ -0,0 +1,23 @@
+#include <stdint.h>
+
+struct gdt_entry {
+ uint16_t limit_low;
+ uint16_t base_low;
+ uint8_t base_middle;
+ uint8_t access;
+ uint8_t granularity;
+ uint8_t base_high;
+} __attribute__((packed));
+
+struct gdt_ptr {
+ uint8_t limit;
+ uint32_t base;
+} __attribute__((packed));
+
+struct gdt_entry gdt[3];
+struct gdt_ptr gp;
+
+/* assembly */
+extern void gdt_flush(struct gdt_ptr*);
+
+void gdt_init(void);
diff --git a/kernel/include/io.h b/kernel/include/io.h
new file mode 100644
index 0000000..c3c735b
--- /dev/null
+++ b/kernel/include/io.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+void outb(uint16_t port, uint8_t val);
+uint8_t inb(uint16_t port);
+uint16_t inw(uint16_t port);
diff --git a/kernel/io.c b/kernel/io.c
new file mode 100644
index 0000000..9b56b5d
--- /dev/null
+++ b/kernel/io.c
@@ -0,0 +1,19 @@
+#include <stdint.h>
+#include "io.h"
+
+void outb(uint16_t port, uint8_t val)
+{
+ asm volatile ("outb %1, %0": :"dN" (port), "a" (val));
+}
+uint8_t inb(uint16_t port)
+{
+ uint8_t ret;
+ asm volatile ("inb %1, %0" : "=a" (ret) : "dN" (port));
+ return ret;
+}
+uint16_t inw(uint16_t port)
+{
+ uint16_t ret;
+ asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
+ return ret;
+}
diff --git a/kernel/linker.ld b/kernel/linker.ld
new file mode 100644
index 0000000..9b47325
--- /dev/null
+++ b/kernel/linker.ld
@@ -0,0 +1,44 @@
+/* The bootloader will look at this image and start execution at the symbol
+ designated as the entry point. */
+ENTRY(_start)
+
+/* Tell where the various sections of the object files will be put in the final
+ kernel image. */
+SECTIONS
+{
+ /* Begin putting sections at 1 MiB, a conventional place for kernels to be
+ loaded at by the bootloader. */
+ . = 1M;
+
+ /* First put the multiboot header, as it is required to be put very early
+ early in the image or the bootloader won't recognize the file format.
+ Next we'll put the .text section. */
+ .text BLOCK(4K) : ALIGN(4K)
+ {
+ *(.multiboot)
+ *(.text)
+ }
+
+ /* Read-only data. */
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.rodata)
+ }
+
+ /* Read-write data (initialized) */
+ .data BLOCK(4K) : ALIGN(4K)
+ {
+ *(.data)
+ }
+
+ /* Read-write data (uninitialized) and stack */
+ .bss BLOCK(4K) : ALIGN(4K)
+ {
+ *(COMMON)
+ *(.bss)
+ *(.bootstrap_stack)
+ }
+
+ /* The compiler may produce other sections, by default it will put them in
+ a segment with the same name. Simply add stuff here as needed. */
+}
diff --git a/kernel/main.c b/kernel/main.c
new file mode 100644
index 0000000..219e3ee
--- /dev/null
+++ b/kernel/main.c
@@ -0,0 +1,14 @@
+#include "string.h"
+#include "tty.h"
+#include "vga.h"
+
+void main(void)
+{
+ tty_init();
+ gdt_init();
+ tty_puts("GDT initialized\n");
+ tty_set_color(VGA_MAKE_COLOR(VGA_LIGHT_GRAY, VGA_BLACK));
+ tty_puts("Hello, world!\n");
+ while(1)
+ ;
+}
diff --git a/kernel/panic.c b/kernel/panic.c
new file mode 100644
index 0000000..106141b
--- /dev/null
+++ b/kernel/panic.c
@@ -0,0 +1,2 @@
+#include "panic.h"
+#include "
diff --git a/kernel/ssp.c b/kernel/ssp.c
new file mode 100644
index 0000000..ad47bb4
--- /dev/null
+++ b/kernel/ssp.c
@@ -0,0 +1,19 @@
+#include <stdint.h>
+#include "panic.h"
+
+#if UINT32_MAX == UINTPTR_MAX
+#define STACK_CHK_GUARD 0xdeadbeef
+#else
+#define STACK_CHK_GUARD 0x0ddc0ffeebadf00d
+#endif
+
+uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
+
+__attribute__((noreturn)) void __stack_chk_fail(void)
+{
+#if __STDC_HOSTED__
+ abort();
+#else
+ panic("Stack smashing detected");
+#endif
+}