diff options
Diffstat (limited to 'src/kernel/core')
-rw-r--r-- | src/kernel/core/kmain.c | 63 | ||||
-rw-r--r-- | src/kernel/core/loader_.asm | 57 | ||||
-rw-r--r-- | src/kernel/core/monitor.c | 90 | ||||
-rw-r--r-- | src/kernel/core/monitor.h | 12 | ||||
-rw-r--r-- | src/kernel/core/multiboot.h | 64 | ||||
-rw-r--r-- | src/kernel/core/sys.c | 41 | ||||
-rw-r--r-- | src/kernel/core/sys.h | 17 |
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 |