From 439d724ce5939cab7a5c858d1829f212e01e0402 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 1 Feb 2015 11:33:16 -0500 Subject: first real commit --- kernel/gdt-as.S | 16 ++++++++++++++++ kernel/gdt.c | 33 +++++++++++++++++++++++++++++++++ kernel/include/gdt.h | 23 +++++++++++++++++++++++ kernel/include/io.h | 4 ++++ kernel/io.c | 19 +++++++++++++++++++ kernel/linker.ld | 44 ++++++++++++++++++++++++++++++++++++++++++++ kernel/main.c | 14 ++++++++++++++ kernel/panic.c | 2 ++ kernel/ssp.c | 19 +++++++++++++++++++ 9 files changed, 174 insertions(+) create mode 100644 kernel/gdt-as.S create mode 100644 kernel/gdt.c create mode 100644 kernel/include/gdt.h create mode 100644 kernel/include/io.h create mode 100644 kernel/io.c create mode 100644 kernel/linker.ld create mode 100644 kernel/main.c create mode 100644 kernel/panic.c create mode 100644 kernel/ssp.c (limited to 'kernel') 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 + +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 +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 +#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 +#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 +} -- cgit v1.1