diff --git a/kernel.settings b/kernel.settings new file mode 100644 index 0000000..f63e43d --- /dev/null +++ b/kernel.settings @@ -0,0 +1,10 @@ +MODE = debug +#MODE = release # enables optimization + +ifeq ($(MODE),debug) + CFLAGS += -g3 -DDEBUG + CPPFLAGS += -g3 -DDEBUG +else + CFLAGS += -O9 + CPPFLAGS += -O9 +endif diff --git a/kernel/hal/x86/Makefile b/kernel/hal/x86/Makefile index fbd29a8..709828f 100644 --- a/kernel/hal/x86/Makefile +++ b/kernel/hal/x86/Makefile @@ -5,10 +5,12 @@ CPP = g++ CC = gcc LD = ld ASFLAGS = -m32 -CFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -fbuiltin -march=native -CPPFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fbuiltin -march=native +CFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -fbuiltin -march=native -std=c11 -fno-builtin +CPPFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fbuiltin -march=native -fno-builtin LDFLAGS = -r -melf_i386 +include ../../../kernel.settings + hal.o: $(OBJS) $(LD) $(LDFLAGS) -o $@ $^ diff --git a/kernel/hal/x86/asm/snippets.S b/kernel/hal/x86/asm/snippets.S index 301d377..24b5ab2 100644 --- a/kernel/hal/x86/asm/snippets.S +++ b/kernel/hal/x86/asm/snippets.S @@ -12,3 +12,308 @@ loadGDT: mov %ax, %ss ljmp $0x8, $.1 .1: + ret +.global loadIDT +//void _stdcall loadIDT(struct idtp* ptr); +loadIDT: + mov 0x4(%esp), %eax + lidt (%eax) + ret + +//Handle interrupts +.macro intr_stub nr +.global intr_stub_\nr +.align 16 +intr_stub_\nr: + pushl $0 + pushl $\nr + jmp intr_common_handler +.endm +.macro intr_stub_error_code nr +.global intr_stub_\nr +.align 16 +intr_stub_\nr: + pushl $\nr + jmp intr_common_handler +.endm +intr_stub 0 +intr_stub 1 +intr_stub 2 +intr_stub 3 +intr_stub 4 +intr_stub 5 +intr_stub 6 +intr_stub 7 +intr_stub_error_code 8 +intr_stub 9 +intr_stub_error_code 10 +intr_stub_error_code 11 +intr_stub_error_code 12 +intr_stub_error_code 13 +intr_stub_error_code 14 +intr_stub 15 +intr_stub 16 +intr_stub_error_code 17 +intr_stub 18 +intr_stub 19 +intr_stub 20 +intr_stub 21 +intr_stub 22 +intr_stub 23 +intr_stub 24 +intr_stub 25 +intr_stub 26 +intr_stub 27 +intr_stub 28 +intr_stub 29 +intr_stub 30 +intr_stub 31 +intr_stub 32 +intr_stub 33 +intr_stub 34 +intr_stub 35 +intr_stub 36 +intr_stub 37 +intr_stub 38 +intr_stub 39 +intr_stub 40 +intr_stub 41 +intr_stub 42 +intr_stub 43 +intr_stub 44 +intr_stub 45 +intr_stub 46 +intr_stub 47 +intr_stub 48 +intr_stub 49 +intr_stub 50 +intr_stub 51 +intr_stub 52 +intr_stub 53 +intr_stub 54 +intr_stub 55 +intr_stub 56 +intr_stub 57 +intr_stub 58 +intr_stub 59 +intr_stub 60 +intr_stub 61 +intr_stub 62 +intr_stub 63 +intr_stub 64 +intr_stub 65 +intr_stub 66 +intr_stub 67 +intr_stub 68 +intr_stub 69 +intr_stub 70 +intr_stub 71 +intr_stub 72 +intr_stub 73 +intr_stub 74 +intr_stub 75 +intr_stub 76 +intr_stub 77 +intr_stub 78 +intr_stub 79 +intr_stub 80 +intr_stub 81 +intr_stub 82 +intr_stub 83 +intr_stub 84 +intr_stub 85 +intr_stub 86 +intr_stub 87 +intr_stub 88 +intr_stub 89 +intr_stub 90 +intr_stub 91 +intr_stub 92 +intr_stub 93 +intr_stub 94 +intr_stub 95 +intr_stub 96 +intr_stub 97 +intr_stub 98 +intr_stub 99 +intr_stub 100 +intr_stub 101 +intr_stub 102 +intr_stub 103 +intr_stub 104 +intr_stub 105 +intr_stub 106 +intr_stub 107 +intr_stub 108 +intr_stub 109 +intr_stub 110 +intr_stub 111 +intr_stub 112 +intr_stub 113 +intr_stub 114 +intr_stub 115 +intr_stub 116 +intr_stub 117 +intr_stub 118 +intr_stub 119 +intr_stub 120 +intr_stub 121 +intr_stub 122 +intr_stub 123 +intr_stub 124 +intr_stub 125 +intr_stub 126 +intr_stub 127 +intr_stub 128 +intr_stub 129 +intr_stub 130 +intr_stub 131 +intr_stub 132 +intr_stub 133 +intr_stub 134 +intr_stub 135 +intr_stub 136 +intr_stub 137 +intr_stub 138 +intr_stub 139 +intr_stub 140 +intr_stub 141 +intr_stub 142 +intr_stub 143 +intr_stub 144 +intr_stub 145 +intr_stub 146 +intr_stub 147 +intr_stub 148 +intr_stub 149 +intr_stub 150 +intr_stub 151 +intr_stub 152 +intr_stub 153 +intr_stub 154 +intr_stub 155 +intr_stub 156 +intr_stub 157 +intr_stub 158 +intr_stub 159 +intr_stub 160 +intr_stub 161 +intr_stub 162 +intr_stub 163 +intr_stub 164 +intr_stub 165 +intr_stub 166 +intr_stub 167 +intr_stub 168 +intr_stub 169 +intr_stub 170 +intr_stub 171 +intr_stub 172 +intr_stub 173 +intr_stub 174 +intr_stub 175 +intr_stub 176 +intr_stub 177 +intr_stub 178 +intr_stub 179 +intr_stub 180 +intr_stub 181 +intr_stub 182 +intr_stub 183 +intr_stub 184 +intr_stub 185 +intr_stub 186 +intr_stub 187 +intr_stub 188 +intr_stub 189 +intr_stub 190 +intr_stub 191 +intr_stub 192 +intr_stub 193 +intr_stub 194 +intr_stub 195 +intr_stub 196 +intr_stub 197 +intr_stub 198 +intr_stub 199 +intr_stub 200 +intr_stub 201 +intr_stub 202 +intr_stub 203 +intr_stub 204 +intr_stub 205 +intr_stub 206 +intr_stub 207 +intr_stub 208 +intr_stub 209 +intr_stub 210 +intr_stub 211 +intr_stub 212 +intr_stub 213 +intr_stub 214 +intr_stub 215 +intr_stub 216 +intr_stub 217 +intr_stub 218 +intr_stub 219 +intr_stub 220 +intr_stub 221 +intr_stub 222 +intr_stub 223 +intr_stub 224 +intr_stub 225 +intr_stub 226 +intr_stub 227 +intr_stub 228 +intr_stub 229 +intr_stub 230 +intr_stub 231 +intr_stub 232 +intr_stub 233 +intr_stub 234 +intr_stub 235 +intr_stub 236 +intr_stub 237 +intr_stub 238 +intr_stub 239 +intr_stub 240 +intr_stub 241 +intr_stub 242 +intr_stub 243 +intr_stub 244 +intr_stub 245 +intr_stub 246 +intr_stub 247 +intr_stub 248 +intr_stub 249 +intr_stub 250 +intr_stub 251 +intr_stub 252 +intr_stub 253 +intr_stub 254 +intr_stub 255 + +//This should cover everything. +.extern handleINT +intr_common_handler: + push %ebp + push %edi + push %esi + push %edx + push %ecx + push %ebx + push %eax + push %esp + call handleINT + add $4, %esp + pop %eax + pop %ebx + pop %ecx + pop %edx + pop %esi + pop %edi + pop %ebp + // Fehlercode und Interruptnummer vom Stack nehmen + add $8, %esp + // Ruecksprung zum unterbrochenen Code + iret diff --git a/kernel/hal/x86/c_include/stdint.h b/kernel/hal/x86/c_include/stdint.h index 7078146..2926bb5 100644 --- a/kernel/hal/x86/c_include/stdint.h +++ b/kernel/hal/x86/c_include/stdint.h @@ -6,3 +6,4 @@ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; +typedef unsigned int uintptr_t; diff --git a/kernel/hal/x86/c_include/string.h b/kernel/hal/x86/c_include/string.h new file mode 100644 index 0000000..f31a22e --- /dev/null +++ b/kernel/hal/x86/c_include/string.h @@ -0,0 +1,11 @@ +#ifndef _STRING_H +#define _STRING_H +#ifdef _cplusplus +extern "C" { +#endif +#include +void memmove(void* dst, void* src, uint32_t size); +#ifdef _cplusplus +} +#endif +#endif diff --git a/kernel/hal/x86/include/base.hpp b/kernel/hal/x86/include/base.hpp index aeed7b0..a562f5f 100644 --- a/kernel/hal/x86/include/base.hpp +++ b/kernel/hal/x86/include/base.hpp @@ -6,11 +6,13 @@ namespace MTGosHAL { class Serial; class Screen; class GDT; + class IDT; enum class BG_color: uint16_t; enum class FG_color: uint16_t; extern Serial* debug; extern Screen* out; extern Screen* err; extern GDT* gdt; + extern IDT* idt; } #endif diff --git a/kernel/hal/x86/include/idt.hpp b/kernel/hal/x86/include/idt.hpp new file mode 100644 index 0000000..4afc249 --- /dev/null +++ b/kernel/hal/x86/include/idt.hpp @@ -0,0 +1,52 @@ +#ifndef _IDT_HPP +#define _IDT_HPP +#include +#define IDT_INTERRUPT_GATE 0x06 +#define IDT_TRAP_GATE 0x07 +#define IDT_TASK_GATE 0x05 +#define IDT_SEG_32_BIT 0x08 +#define IDT_RING_0 0x00 +#define IDT_RING_3 0x60 +#define IDT_USED 0x80 +#define SEG_KERNEL 0x08 +#define SEG_USER 0x18 /*NEVER USE!!*/ +#define SEG_DBL_FAULT 0x28 /*Only use for double fault handler!!*/ +extern "C" { + void loadIDT(void * ptr); + struct cpu_state { + // Von Hand gesicherte Register + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t intr; + uint32_t error; + // Von der CPU gesichert + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; + }; +} +namespace MTGosHAL { + class IDT { + private: + uint64_t idt[256]; + struct idtp { + uint16_t limit; + uint64_t* pointer; + }__attribute__((packed)); + struct idtp idtptr; + public: + IDT(); + auto setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void; + auto apply() -> void; + auto handle(struct cpu_state* cpu) -> void; + }; +} +extern "C" void handleINT(struct cpu_state* cpu); +#endif diff --git a/kernel/hal/x86/init/idt.cpp b/kernel/hal/x86/init/idt.cpp new file mode 100644 index 0000000..df5c010 --- /dev/null +++ b/kernel/hal/x86/init/idt.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +namespace MTGosHAL { + IDT::IDT() { + //Init PIC + outb(0x20, 0x11); //Init Master-PIC + outb(0x21, 0x20); //Interrupt number for IRQ0 + outb(0x21, 0x04); //IRQ is the Slave + outb(0x21, 0x01); //ICW 4 + outb(0xA0, 0x11); //Init Master-PIC + outb(0xA1, 0x28); //Interrupt number for IRQ8 + outb(0xA1, 0x02); //IRQ is the Slave + outb(0xA1, 0x01); //ICW 4 + //Activate IRQ's + outb(0x21, 0x00); + outb(0xA1, 0x00); + } + auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void { + idt[i]=(uint16_t)((uint32_t)offset); + idt[i]|=(uint64_t)(((uint32_t)offset)>>16)<<48; + idt[i]|=((uint64_t)seg)<<16; + idt[i]|=((uint64_t)flags)<<40; + } + auto IDT::apply() -> void { + *debug << "Now trying to load the IDT.\n"; + idtptr.limit=(uint16_t)(256*8-1); + idtptr.pointer=(uint64_t*)&idt; + loadIDT((void*)&idtptr); + } + auto IDT::handle(struct cpu_state* cpu) -> void { + *debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n"; + if(cpu->intr<=0x1F) { + *out << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n"; + while(1) { + asm volatile("cli; hlt"); + } + } else if(cpu->intr >= 0x20 && cpu->intr <= 0x20) { + if(cpu->intr >= 0x28) { + outb(0xA0, 0x20); + } + outb(0x20, 0x20); + *debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n"; + } + } +} +extern "C" void handleINT(struct cpu_state* cpu) { + MTGosHAL::idt->handle(cpu); +} diff --git a/kernel/hal/x86/init/init.cpp b/kernel/hal/x86/init/init.cpp index dd1f110..43bdd56 100644 --- a/kernel/hal/x86/init/init.cpp +++ b/kernel/hal/x86/init/init.cpp @@ -3,17 +3,22 @@ #include #include #include +#include +extern "C" void intr_stub_0(void); namespace MTGosHAL { Serial* debug; Screen* out; Screen* err; + IDT* idt; void main() { Serial serialOUT(115200); Screen display; GDT gdt; + IDT interrupts; debug=&serialOUT; err=&display; out=&display; + idt=&interrupts; *out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n"; *debug << "Hello debugger! This is MTGos version 0.0\nThese logs are probably very long, so please redirect the output to a file.\n"; gdt.setEntry(0, 0, 0, 0); @@ -24,6 +29,14 @@ namespace MTGosHAL { gdt.setEntry(5, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); gdt.apply(); + *debug << "We are now creating the IDT.\n"; + for(int i=0;i<256;i++) { + idt->setEntry(i, (void *)((uint32_t)&intr_stub_0+i*16), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); + } + idt->setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); + idt->setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); + idt->apply(); + sti(); for(;;); } } diff --git a/kernel/hal/x86/string.c b/kernel/hal/x86/string.c new file mode 100644 index 0000000..82ca146 --- /dev/null +++ b/kernel/hal/x86/string.c @@ -0,0 +1,16 @@ +#include +//Those pragmas are used to skip optimization for this function +#pragma GCC push_options +#pragma GCC optimize ("O0") +void memmove(void* dst, void* src, uint32_t size) { + uint8_t* from=(uint8_t*)src; + uint8_t* to=(uint8_t*)dst; + if((srcdst)) { + for(int i=size-1;i>=0;i--) + to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled. + } else if(src != dst) { + for(int i=0;i