summaryrefslogtreecommitdiff
path: root/src/kernel/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/core')
-rw-r--r--src/kernel/core/kmain.c63
-rw-r--r--src/kernel/core/loader_.asm57
-rw-r--r--src/kernel/core/monitor.c90
-rw-r--r--src/kernel/core/monitor.h12
-rw-r--r--src/kernel/core/multiboot.h64
-rw-r--r--src/kernel/core/sys.c41
-rw-r--r--src/kernel/core/sys.h17
7 files changed, 344 insertions, 0 deletions
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
new file mode 100644
index 0000000..ef92dff
--- /dev/null
+++ b/src/kernel/core/kmain.c
@@ -0,0 +1,63 @@
+#include <types.h>
+#include "multiboot.h"
+#include "monitor.h"
+#include "sys.h"
+#include <task/idt.h>
+#include <task/timer.h>
+#include <task/task.h>
+#include <mem/gdt.h>
+#include <mem/paging.h>
+#include <mem/mem.h>
+#include <linker/elf.h>
+
+void kmain(struct multiboot_info_t* mbd, int32_t magic) {
+ size_t totalRam = 0;
+ uint32_t i;
+
+ mem_placementAddr = (size_t)&end;
+ mbd->cmdline += 0xE0000000; mbd->mods_addr += 0xE0000000;
+ struct module_t *mods = (struct module_t*)mbd->mods_addr;
+ for (i = 0; i < mbd->mods_count; i++) {
+ mods[i].mod_start += 0xE0000000;
+ mods[i].mod_end += 0xE0000000;
+ mods[i].string += 0xE0000000;
+ if (mods[i].mod_end > mem_placementAddr)
+ mem_placementAddr = (mods[i].mod_end & 0xFFFFF000) + 0x1000;
+ }
+
+ monitor_clear();
+
+ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
+ PANIC("wrong multiboot magic number.");
+ }
+
+ monitor_write("Grapes kernel booting ...\n");
+
+ idt_init();
+
+ totalRam = ((mbd->mem_upper + mbd->mem_lower) * 1024);
+ paging_init(totalRam);
+ gdt_init();
+ paging_cleanup();
+ kheap_init();
+ timer_init(20);
+ tasking_init();
+
+ monitor_write("Loading modules...\n");
+ for (i = 0; i < mbd->mods_count; i++) {
+ monitor_write((char*)mods[i].string);
+ if (elf_check((uint8_t*)mods[i].mod_start)) {
+ monitor_write(" : Invalid ELF file\n");
+ } else {
+ if (elf_exec((uint8_t*)mods[i].mod_start) == 0) {
+ monitor_write(" : Error loading\n");
+ } else {
+ monitor_write(" : OK\n");
+ }
+ }
+ }
+
+ monitor_write("Passing control to loaded modules...\n");
+ sti();
+ tasking_switch();
+}
diff --git a/src/kernel/core/loader_.asm b/src/kernel/core/loader_.asm
new file mode 100644
index 0000000..d3b92cf
--- /dev/null
+++ b/src/kernel/core/loader_.asm
@@ -0,0 +1,57 @@
+[GLOBAL loader] ; making entry point visible to linker
+[EXTERN kmain] ; kmain is defined in kmain.c
+[EXTERN tasking_tmpStack] ; a temporary 4k stack used by tasking, and used when setting up kernel stuff
+
+; setting up the Multiboot header - see GRUB docs for details
+MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
+MEMINFO equ 1<<1 ; provide memory map
+FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
+MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
+CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
+
+section .text
+align 4
+MultiBootHeader:
+ dd MAGIC
+ dd FLAGS
+ dd CHECKSUM
+
+section .setup
+loader: ;here, we load our false GDT, used for having the kernel in higher half
+ lgdt [trickgdt]
+ mov cx, 0x10;
+ mov ds, cx;
+ mov es, cx;
+ mov fs, cx;
+ mov gs, cx;
+ mov ss, cx;
+
+ jmp 0x08:higherhalf
+
+section .text
+higherhalf: ; now we're running in higher half
+
+ mov esp, tasking_tmpStack+0x4000 ; set up the stack
+ push eax ; pass Multiboot magic number
+ add ebx, 0xE0000000 ; update the MB info structure so that it is in the new seg
+ push ebx ; pass Multiboot info structure
+
+ call kmain ; call kernel proper
+
+ cli ; disable interupts
+hang:
+ hlt ; halt machine should kernel return
+ jmp hang
+
+[section .setup] ; this is included in the .setup section, so that it thinks it is at 0x00100000
+
+trickgdt: ; our false GDT
+ dw gdt_end - gdt - 1 ; gdt limit
+ dd gdt ; gdt base
+
+gdt:
+ dd 0, 0 ; null GDT entry
+ db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x20 ; kernel code segment
+ db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x20 ; kernel data segment
+
+gdt_end:
diff --git a/src/kernel/core/monitor.c b/src/kernel/core/monitor.c
new file mode 100644
index 0000000..8c4744a
--- /dev/null
+++ b/src/kernel/core/monitor.c
@@ -0,0 +1,90 @@
+#include "monitor.h"
+#include "sys.h"
+
+static int cursor_x = 0, cursor_y = 0;
+static uint16_t *video_memory = (uint16_t*)0xE00B8000;
+
+static void move_cursor() {
+ uint16_t cursor_location = cursor_y * 80 + cursor_x;
+ outb(0x3D4, 14); //Sending high cursor byte
+ outb(0x3D5, cursor_location >> 8);
+ outb(0x3D4, 15); //Sending high cursor byte
+ outb(0x3D5, cursor_location);
+}
+
+static void scroll() {
+ uint8_t attribute_byte = (0 /* black */ << 4) | (7/* white */ & 0x0F);
+ uint16_t blank = (attribute_byte << 8) | 0x20;
+
+ if (cursor_y >= 25) {
+ int i;
+ for (i = 0; i < 80*24; i++) {
+ video_memory[i] = video_memory[i+80];
+ }
+ for (i = 80*24; i < 80*25; i++) {
+ video_memory[i] = blank;
+ }
+ cursor_y = 24;
+ }
+}
+
+void monitor_put(char c) {
+ uint8_t fg = 7; //White
+ uint8_t bg = 0; //Black
+
+ uint16_t attribute = (fg & 0x0F) | (bg << 4);
+ attribute = attribute << 8;
+
+ if (c == 0x08 && cursor_x) { //Backspace
+ cursor_x--;
+ } else if (c == 0x09) { //Tab
+ cursor_x = (cursor_x + 8) & ~(8 - 1);
+ } else if (c == '\r') { //Carriage return
+ cursor_x = 0;
+ } else if (c == '\n') { //New line
+ cursor_x = 0;
+ cursor_y++;
+ } else if (c >= ' ') { //Any printable character
+ video_memory[cursor_y * 80 + cursor_x] = c | attribute;
+ cursor_x++;
+ }
+ if (cursor_x >= 80) {
+ cursor_x = 0;
+ cursor_y++;
+ }
+
+ scroll();
+ move_cursor();
+}
+
+void monitor_clear() {
+ uint8_t attribute_byte = (0 /* black */ << 4) | (15 /* white */ & 0x0F);
+ uint16_t blank = (attribute_byte << 8) | 0x20;
+
+ int i;
+
+ for (i = 0; i < 80*25; i++) {
+ video_memory[i] = blank;
+ }
+
+ cursor_x = 0; cursor_y = 0;
+ move_cursor();
+}
+
+void monitor_write(char *s) {
+ while (*s) {
+ monitor_put(*(s++));
+ }
+}
+
+void monitor_writeHex(uint32_t v) {
+ int i;
+
+ monitor_put('0'); monitor_put('x');
+ char hexdigits[] = "0123456789abcdef";
+
+ for (i = 0; i < 8; i++) {
+ monitor_put(hexdigits[v >> 28]);
+ v = v << 4;
+ }
+}
diff --git a/src/kernel/core/monitor.h b/src/kernel/core/monitor.h
new file mode 100644
index 0000000..3abe072
--- /dev/null
+++ b/src/kernel/core/monitor.h
@@ -0,0 +1,12 @@
+#ifndef DEF_MONITOR_H
+#define DEF_MONITOR_H
+
+#include "types.h"
+
+void monitor_put(char c);
+void monitor_clear();
+void monitor_write(char *s);
+void monitor_writeHex(uint32_t v);
+
+#endif
+
diff --git a/src/kernel/core/multiboot.h b/src/kernel/core/multiboot.h
new file mode 100644
index 0000000..908274c
--- /dev/null
+++ b/src/kernel/core/multiboot.h
@@ -0,0 +1,64 @@
+#ifndef HDR_MULTIBOOT
+#define HDR_MULTIBOOT
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+struct multiboot_header_t{
+ unsigned long magic;
+ unsigned long flags;
+ unsigned long checksum;
+ unsigned long header_addr;
+ unsigned long load_addr;
+ unsigned long load_end_addr;
+ unsigned long bss_end_addr;
+ unsigned long entry_addr;
+};
+
+struct aout_symbol_table_t {
+ unsigned long tabsize;
+ unsigned long strsize;
+ unsigned long addr;
+ unsigned long reserved;
+};
+
+struct elf_section_header_table_t {
+ unsigned long num;
+ unsigned long size;
+ unsigned long addr;
+ unsigned long shndx;
+};
+
+struct multiboot_info_t {
+ unsigned long flags;
+ unsigned long mem_lower;
+ unsigned long mem_upper;
+ unsigned long boot_device;
+ unsigned long cmdline;
+ unsigned long mods_count;
+ unsigned long mods_addr;
+ union {
+ struct aout_symbol_table_t aout_sym;
+ struct elf_section_header_table_t elf_sec;
+ } u;
+ unsigned long mmap_length;
+ unsigned long mmap_addr;
+};
+
+struct module_t {
+ unsigned long mod_start;
+ unsigned long mod_end;
+ unsigned long string;
+ unsigned long reserved;
+};
+
+struct memory_map_t {
+ unsigned long size;
+ unsigned long base_addr_low;
+ unsigned long base_addr_high;
+ unsigned long length_low;
+ unsigned long length_high;
+ unsigned long type;
+};
+
+#endif
+
diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.c
new file mode 100644
index 0000000..d31c20e
--- /dev/null
+++ b/src/kernel/core/sys.c
@@ -0,0 +1,41 @@
+#include "sys.h"
+#include "monitor.h"
+
+void outb(uint16_t port, uint8_t value) {
+ asm volatile("outb %1, %0" : : "dN"(port), "a"(value));
+}
+
+void outw(uint16_t port, uint16_t value) {
+ asm volatile("outw %1, %0" : : "dN"(port), "a"(value));
+}
+
+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;
+}
+
+void panic(char* message, char* file, int line) {
+ monitor_write("\n>> PANIC: >>");
+ monitor_write(message); monitor_write("<< in file "); monitor_write(file);
+ monitor_write("\nSystem halted T_T");
+ asm volatile("cli; hlt");
+}
+
+static uint32_t if_locks = 1;
+
+void cli() {
+ asm volatile("cli");
+ if_locks++;
+}
+
+void sti() {
+ if (if_locks > 0) if_locks--;
+ if (if_locks == 0) asm volatile("sti");
+}
diff --git a/src/kernel/core/sys.h b/src/kernel/core/sys.h
new file mode 100644
index 0000000..76e3560
--- /dev/null
+++ b/src/kernel/core/sys.h
@@ -0,0 +1,17 @@
+#ifndef DEF_SYS_H
+#define DEF_SYS_H
+
+#include "types.h"
+
+void outb(uint16_t port, uint8_t value);
+void outw(uint16_t port, uint16_t value);
+uint8_t inb(uint16_t port);
+uint16_t inw(uint16_t port);
+
+#define PANIC(s) panic(s, __FILE__, __LINE__);
+void panic(char* message, char* file, int line);
+
+void sti(); //GLOBAL SYSTEM MUTEX
+void cli();
+
+#endif