Added the IDT

+Added an additional release setting, however it does not work.
This commit is contained in:
Morten Delenk 2015-10-11 12:38:56 +02:00
parent c7b0fffe13
commit 054e1bc230
10 changed files with 465 additions and 2 deletions

10
kernel.settings Normal file
View file

@ -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

View file

@ -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 $@ $^

View file

@ -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

View file

@ -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;

View file

@ -0,0 +1,11 @@
#ifndef _STRING_H
#define _STRING_H
#ifdef _cplusplus
extern "C" {
#endif
#include <stdint.h>
void memmove(void* dst, void* src, uint32_t size);
#ifdef _cplusplus
}
#endif
#endif

View file

@ -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

View file

@ -0,0 +1,52 @@
#ifndef _IDT_HPP
#define _IDT_HPP
#include <stdint.h>
#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

View file

@ -0,0 +1,51 @@
#include <base.hpp>
#include <io.h>
#include <idt.hpp>
#include <serial.hpp>
#include <textDISP.hpp>
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);
}

View file

@ -3,17 +3,22 @@
#include <serial.hpp>
#include <textDISP.hpp>
#include <gdt.hpp>
#include <idt.hpp>
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(;;);
}
}

16
kernel/hal/x86/string.c Normal file
View file

@ -0,0 +1,16 @@
#include <string.h>
//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((src<dst)&&((src+size)>dst)) {
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<size;i++)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
}
}
#pragma GCC pop_options