x86_64 port
This commit is contained in:
parent
fddedb4448
commit
75e498aeaf
54 changed files with 2001 additions and 3648 deletions
1
Makefile
1
Makefile
|
@ -12,5 +12,6 @@ user:
|
|||
clean:
|
||||
make -C kernel clean
|
||||
rm -rf mtgos
|
||||
find . -name '*.o' -delete
|
||||
|
||||
.PHONY: all mtgos user clean
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
arch = x86_64
|
||||
arch = x86
|
||||
#MODE = debug
|
||||
MODE = release # enables optimization
|
||||
|
||||
export PATH := $(HOME)/opt/bin:$(PATH)
|
||||
ARCHFLAGS =
|
||||
ifeq ($(arch),x86)
|
||||
PREFIX = i686-elf-
|
||||
else
|
||||
ifeq ($(arch),x86_64)
|
||||
PREFIX = x86_64-elf-
|
||||
ARCHFLAGS =
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MODE),debug)
|
||||
CFLAGS += -g3 -DDEBUG
|
||||
CFLAGS += -g3 -DDEBUG
|
||||
CPPFLAGS += -g3 -DDEBUG
|
||||
else
|
||||
CFLAGS += -O2
|
||||
|
|
|
@ -4,10 +4,8 @@ KERNSRCS = $(shell find kernel -name '*.cpp' -o -name '*.c')
|
|||
OBJS = $(addsuffix .o,$(basename $(SRCS)))
|
||||
OBJS += $(addsuffix .o,$(basename $(KERNSRCS)))
|
||||
LD = $(PREFIX)g++
|
||||
LDFLAGS = -nostdlib -nodefaultlibs -nostdlib -fno-builtin
|
||||
ifeq ($(arch),x86)
|
||||
LDFLAGS += -m32 -T kernel-$(arch).ld
|
||||
endif
|
||||
LDFLAGS = -nostdlib -nodefaultlibs -nostdlib -fno-builtin $(ARCHFLAGS) -T kernel-$(arch).ld
|
||||
|
||||
all: hal kernel
|
||||
$(LD) $(LDFLAGS) -o mtgos $(OBJS)
|
||||
hal:
|
||||
|
|
|
@ -321,9 +321,31 @@ intr_common_handler:
|
|||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov $8, %ecx
|
||||
mov $fld_hi, %ebx
|
||||
mov $fld_lo, %edx
|
||||
.storeloop:
|
||||
fstpl (%edx)
|
||||
mov (%edx), %eax
|
||||
push %eax
|
||||
mov (%ebx), %eax
|
||||
push %eax
|
||||
loop .storeloop
|
||||
|
||||
push %esp
|
||||
call handleINT
|
||||
mov %eax, %esp
|
||||
mov $8, %ecx
|
||||
mov $fld_hi, %ebx
|
||||
mov $fld_lo, %edx
|
||||
.loadloop:
|
||||
pop %eax
|
||||
mov %eax, (%ebx)
|
||||
pop %eax
|
||||
mov %eax, (%edx)
|
||||
fldl (%ebx)
|
||||
loop .loadloop
|
||||
|
||||
//Load user datasegs
|
||||
mov $0x23, %ax
|
||||
mov %ax, %ds
|
||||
|
@ -339,3 +361,9 @@ intr_common_handler:
|
|||
add $8, %esp
|
||||
// Exit interrupt
|
||||
iret
|
||||
|
||||
.section .data
|
||||
fld_lo:
|
||||
.space 4
|
||||
fld_hi:
|
||||
.space 4
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
.extern init
|
||||
.global _start
|
||||
_start:
|
||||
finit
|
||||
mov $kernel_stack, %esp
|
||||
push %ebx
|
||||
push %eax
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,2 +0,0 @@
|
|||
#define MIN(a,b) ((a)>(b))?(b):(a)
|
||||
#define MAX(a,b) ((a)<(b))?(b):(a)
|
|
@ -1,10 +0,0 @@
|
|||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed long long int int64_t;
|
||||
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;
|
||||
typedef unsigned long int size_t;
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef _STRING_H
|
||||
#define _STRING_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
void memmove(void* dst, void* src, uint32_t size);
|
||||
uint32_t strlen(const char* str);
|
||||
int strcmp(const char* str1, const char* str2);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -4,14 +4,15 @@
|
|||
#define GDT_FLAG_DATASEG 0x02
|
||||
#define GDT_FLAG_CODESEG 0x0a
|
||||
#define GDT_FLAG_TSS 0x09
|
||||
|
||||
|
||||
#define GDT_FLAG_SEGMENT 0x10
|
||||
#define GDT_FLAG_RING0 0x00
|
||||
#define GDT_FLAG_RING3 0x60
|
||||
#define GDT_FLAG_PRESENT 0x80
|
||||
|
||||
|
||||
#define GDT_FLAG_4K_GRAN 0x800
|
||||
#define GDT_FLAG_32_BIT 0x400
|
||||
#define GDT_FLAG_64_BIT 0x200
|
||||
extern "C" void loadGDT(void * gdtpr);
|
||||
namespace MTGosHAL {
|
||||
class GDT {
|
||||
|
|
|
@ -17,6 +17,14 @@ extern "C" {
|
|||
|
||||
namespace MTGosHAL {
|
||||
struct cpu_state {
|
||||
double st7;
|
||||
double st6;
|
||||
double st5;
|
||||
double st4;
|
||||
double st3;
|
||||
double st2;
|
||||
double st1;
|
||||
double st0;
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef _KEYBOARD_HPP
|
||||
#ifndef _KEYBOARD_HPP
|
||||
#define _KEYBOARD_HPP
|
||||
#include <stdint.h>
|
||||
#include <input.hpp>
|
||||
|
|
|
@ -15,8 +15,9 @@ private:
|
|||
PMM2 pmm2;
|
||||
public:
|
||||
PMM();
|
||||
PMM(struct multiboot_info* mb_info): PMM() {init(mb_info);}
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
auto alloc(uint32_t length) -> void *;
|
||||
auto alloc(size_t length) -> void *;
|
||||
auto free(void* ptr) -> bool;
|
||||
auto markUsed(const void * addr, uint32_t length) -> bool;
|
||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace MTGosHAL {
|
|||
public:
|
||||
Screen(): fg(FG_color::WHITE), bg(BG_color::BLACK) {
|
||||
}
|
||||
Screen(struct multiboot_info* mb_info): Screen() {init(mb_info);}
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
template <typename T>
|
||||
auto operator<< (T output) -> Screen & {
|
||||
|
|
|
@ -31,6 +31,14 @@ auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
|||
mm >> tmp1 >> tmp2;
|
||||
uint8_t *stack=(uint8_t*)tmp1, *user_stack=(uint8_t*)tmp2;
|
||||
struct cpu_state new_state = {
|
||||
0.0, //ST0
|
||||
0.0, //ST1
|
||||
0.0, //ST2
|
||||
0.0, //ST3
|
||||
0.0, //ST4
|
||||
0.0, //ST5
|
||||
0.0, //ST6
|
||||
0.0, //ST7
|
||||
0, //EAX
|
||||
0, //EBX
|
||||
0, //ECX
|
||||
|
|
|
@ -8,29 +8,28 @@
|
|||
#include <Multitasking.hpp>
|
||||
#include <multiboot.h>
|
||||
#include <blockdev.hpp>
|
||||
#include <vmm3.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" void intr_stub_0(void);
|
||||
void main(void ** programs);
|
||||
void** progs;
|
||||
namespace MTGosHAL {
|
||||
Serial debug;
|
||||
GDT gdt;
|
||||
IDT idt;
|
||||
PMM mm;
|
||||
Screen out;
|
||||
Screen err;
|
||||
Keyboard in;
|
||||
IDT idt;
|
||||
GDT gdt;
|
||||
Multitasking tasks;
|
||||
BlockDevice disk;
|
||||
PMM mm;
|
||||
void main(int eax, struct multiboot_info* ebx) {
|
||||
out.init(ebx);
|
||||
err.init(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
if(eax!=0x2BADB002)
|
||||
err << "System wasn't loaded by a Multiboot-conformant launcher!\n";
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
//Init debug output
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
gdt.setEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
||||
|
@ -38,15 +37,37 @@ namespace MTGosHAL {
|
|||
gdt.setEntry(5, (uint32_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.apply();
|
||||
asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
debug << "We are now creating the IDT.\n";
|
||||
for(int i=0;i<256;i++) {
|
||||
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
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_3 | 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();
|
||||
mm.init(ebx);
|
||||
asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
debug << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
|
||||
debug << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
|
||||
debug << "Init Multitasking\n";
|
||||
new (&tasks) Multitasking();
|
||||
|
||||
debug << "Init Disk\n";
|
||||
new (&disk) BlockDevice();
|
||||
|
||||
debug << "Kernel initialized\n";
|
||||
if(eax!=0x2BADB002)
|
||||
err << "System wasn't loaded by a Multiboot-conformant launcher!\n";
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
||||
progs=(void**)mm.alloc(4096);
|
||||
for(int i=0;i<1024;i++) {
|
||||
|
@ -57,19 +78,18 @@ namespace MTGosHAL {
|
|||
debug << "Found module!\n";
|
||||
}
|
||||
::main(progs);
|
||||
uint8_t buf[512];
|
||||
disk.readSector(disk.getDriveNumByName("ATA0m1"),0,buf);
|
||||
out << (char*)buf;
|
||||
sti();
|
||||
for(;;);
|
||||
}
|
||||
}
|
||||
typedef void (*constructor)();
|
||||
typedef void (*destructor)();
|
||||
extern "C" constructor start_ctors;
|
||||
extern "C" constructor end_ctors;
|
||||
extern "C" destructor start_dtors;
|
||||
extern "C" destructor end_dtors;
|
||||
extern "C" void init(int eax, struct multiboot_info* ebx) {
|
||||
for(constructor* i = &start_ctors; i != &end_ctors; ++i)
|
||||
(*i)();
|
||||
MTGosHAL::main(eax, ebx);
|
||||
for(destructor* i = &start_dtors; i != &end_dtors; i++)
|
||||
(*i)();
|
||||
|
|
26
kernel/hal/x86_64/Makefile
Normal file
26
kernel/hal/x86_64/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
include ../../../kernel.settings
|
||||
SRCS = $(shell find -name '*.cpp' -o -name '*.[cS]')
|
||||
OBJS = $(addsuffix .o,$(basename $(SRCS)))
|
||||
|
||||
CPP = $(PREFIX)g++
|
||||
CC = $(PREFIX)gcc
|
||||
ASFLAGS = -m64
|
||||
CFLAGS = -m64 -Wall -fno-stack-protector -nostdinc -Ic_include/ -I../../kernel/c_include -ffreestanding -std=c11 -fno-builtin -Werror -nostdlib -g -fpie
|
||||
CPPFLAGS = -m64 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -I../../kernel/c_include -I../../kernel/include -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fno-pie -Wno-reorder
|
||||
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CPP) $(CPPFLAGS) -c -o $@ $^
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
%.o: $.S
|
||||
$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS)
|
||||
|
||||
.PHONY: clean all
|
381
kernel/hal/x86_64/asm/snippets.S
Normal file
381
kernel/hal/x86_64/asm/snippets.S
Normal file
|
@ -0,0 +1,381 @@
|
|||
.global loadGDT
|
||||
//void _stdcall loadGDT(struct gdtp* ptr);
|
||||
loadGDT:
|
||||
mov 0x8(%rsp), %rax // Load argument
|
||||
lgdt (%rax)
|
||||
//GDT is loaded now
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss
|
||||
mov $0x10, %rax
|
||||
.code32
|
||||
ljmp $8, $.1 //Hacky hack
|
||||
.code64
|
||||
.1:
|
||||
ret
|
||||
.global loadIDT
|
||||
//void _stdcall loadIDT(struct idtp* ptr);
|
||||
loadIDT:
|
||||
mov 0x8(%rsp), %rax
|
||||
lidt (%rax)
|
||||
ret
|
||||
.global enterPaging
|
||||
//void _stdcall enterPaging(uint32** pd);
|
||||
enterPaging:
|
||||
mov 0x8(%rsp), %rax
|
||||
mov %rax, %cr3
|
||||
mov %cr4, %rax
|
||||
or $0x10, %rax
|
||||
mov %rax, %cr4
|
||||
mov %cr0, %rax
|
||||
push %rbx
|
||||
mov $0x80000000,%rbx
|
||||
or %rbx, %rax
|
||||
pop %rbx
|
||||
mov %rax, %cr0
|
||||
mov (%rsp), %rax
|
||||
ret
|
||||
|
||||
//Handle interrupts
|
||||
.macro intr_stub nr
|
||||
.global intr_stub_\nr
|
||||
.align 32
|
||||
intr_stub_\nr:
|
||||
pushq $0
|
||||
pushq $\nr
|
||||
jmp intr_common_handler
|
||||
.endm
|
||||
.macro intr_stub_error_code nr
|
||||
.global intr_stub_\nr
|
||||
.align 32
|
||||
intr_stub_\nr:
|
||||
pushq $\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:
|
||||
cli
|
||||
push %r15
|
||||
push %r14
|
||||
push %r13
|
||||
push %r12
|
||||
push %r11
|
||||
push %r10
|
||||
push %r9
|
||||
push %r8
|
||||
push %rbp
|
||||
push %rdi
|
||||
push %rsi
|
||||
push %rdx
|
||||
push %rcx
|
||||
push %rbx
|
||||
push %rax
|
||||
mov $8, %rcx
|
||||
mov $fldval, %rbx
|
||||
.storeloop:
|
||||
fstpl (%rbx)
|
||||
mov (%rbx), %rax
|
||||
push %rax
|
||||
loop .storeloop
|
||||
|
||||
//Load kernel datasegs
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
push %rsp
|
||||
call handleINT
|
||||
mov %rax, %rsp
|
||||
mov $8, %rcx
|
||||
mov $fldval, %rbx
|
||||
.loadloop:
|
||||
pop %rax
|
||||
mov %rax, (%rbx)
|
||||
fldl (%rbx)
|
||||
loop .loadloop
|
||||
|
||||
//Load user datasegs
|
||||
mov $0x23, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
pop %rax
|
||||
pop %rbx
|
||||
pop %rcx
|
||||
pop %rdx
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
pop %rbp
|
||||
pop %r8
|
||||
pop %r9
|
||||
pop %r10
|
||||
pop %r11
|
||||
pop %r12
|
||||
pop %r13
|
||||
pop %r14
|
||||
pop %r15
|
||||
// Take error code and interrupt number from stack
|
||||
add $16, %rsp
|
||||
// Exit interrupt
|
||||
iret
|
||||
.section .data
|
||||
fldval:
|
|
@ -1,16 +1,20 @@
|
|||
.code32
|
||||
.section multiboot
|
||||
#define MB_MAGIC 0x1BADB002
|
||||
#define MB_FLAGS 0x0
|
||||
#define MB_FLAGS 0x7
|
||||
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
|
||||
.align 4
|
||||
.int MB_MAGIC
|
||||
.int MB_FLAGS
|
||||
.int MB_CHECKSUM
|
||||
.int 0,0,0,0,0
|
||||
.int 0
|
||||
.int 1024, 768, 32
|
||||
.section .text
|
||||
.extern init
|
||||
.global _start
|
||||
_start:
|
||||
finit
|
||||
mov $mb_ptr, %edi
|
||||
stosl
|
||||
mov %ebx, %eax
|
||||
|
|
43
kernel/hal/x86_64/c_include/io.h
Normal file
43
kernel/hal/x86_64/c_include/io.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef _IO_H
|
||||
#define _IO_H
|
||||
#include <stdint.h>
|
||||
static inline void outb(uint16_t port, uint8_t val) {
|
||||
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline void outw(uint16_t port, uint16_t val) {
|
||||
asm volatile("outw %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline void outl(uint16_t port, uint32_t val) {
|
||||
asm volatile("outl %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint16_t ret;
|
||||
asm volatile("inw %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
static inline uint32_t inl(uint16_t port) {
|
||||
uint32_t ret;
|
||||
asm volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
static inline void io_wait() {
|
||||
asm volatile("outb %%al, $0x80" : : "a"(0));
|
||||
}
|
||||
static inline void cli() {
|
||||
asm volatile("cli");
|
||||
}
|
||||
static inline void sti() {
|
||||
asm volatile("sti");
|
||||
}
|
||||
static inline uint64_t rdtsc()
|
||||
{
|
||||
uint64_t ret;
|
||||
asm volatile ( "rdtsc" : "=A"(ret) );
|
||||
return ret;
|
||||
}
|
||||
#endif
|
309
kernel/hal/x86_64/c_include/multiboot.h
Normal file
309
kernel/hal/x86_64/c_include/multiboot.h
Normal file
|
@ -0,0 +1,309 @@
|
|||
/* multiboot.h - Multiboot header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
/* Flags to be set in the 'flags' member of the multiboot info structure. */
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
multiboot_uint32_t entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
multiboot_uint32_t mode_type;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
struct multiboot_aout_symbol_table
|
||||
{
|
||||
multiboot_uint32_t tabsize;
|
||||
multiboot_uint32_t strsize;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t reserved;
|
||||
};
|
||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
struct multiboot_elf_section_header_table
|
||||
{
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t shndx;
|
||||
};
|
||||
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
|
||||
|
||||
struct multiboot_info
|
||||
{
|
||||
/* Multiboot info version number */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
multiboot_uint32_t boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
multiboot_uint32_t mods_count;
|
||||
multiboot_uint32_t mods_addr;
|
||||
|
||||
union
|
||||
{
|
||||
multiboot_aout_symbol_table_t aout_sym;
|
||||
multiboot_elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
multiboot_uint32_t mmap_length;
|
||||
multiboot_uint32_t mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
multiboot_uint32_t drives_length;
|
||||
multiboot_uint32_t drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
multiboot_uint32_t config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
multiboot_uint32_t boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
multiboot_uint32_t apm_table;
|
||||
|
||||
/* Video */
|
||||
multiboot_uint32_t vbe_control_info;
|
||||
multiboot_uint32_t vbe_mode_info;
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
multiboot_uint32_t framebuffer_palette_addr;
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
};
|
||||
struct
|
||||
{
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
} __attribute__((packed));
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_mod_list
|
||||
{
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
|
||||
/* Module command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
multiboot_uint32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info
|
||||
{
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
struct MODE_INFO
|
||||
{
|
||||
unsigned short ModeAttributes ;
|
||||
unsigned char WinAAttributes ;
|
||||
unsigned char WinBAttributes ;
|
||||
unsigned short WinGranularity ;
|
||||
unsigned short WinSize ;
|
||||
unsigned short WinASegment ;
|
||||
unsigned short WinBSegment ;
|
||||
unsigned int WinFuncPtr ;
|
||||
unsigned short BytesPerScanLine ;
|
||||
unsigned short XResolution ;
|
||||
unsigned short YResolution ;
|
||||
unsigned char XCharSize ;
|
||||
unsigned char YCharSize ;
|
||||
unsigned char NumberOfPlanes ;
|
||||
unsigned char BitsPerPixel ;
|
||||
unsigned char NumberOfBanks ;
|
||||
unsigned char MemoryModel ;
|
||||
unsigned char BankSize ;
|
||||
unsigned char NumberOfImagePages ;
|
||||
unsigned char Reserved_page ;
|
||||
unsigned char RedMaskSize ;
|
||||
unsigned char RedMaskPos ;
|
||||
unsigned char GreenMaskSize ;
|
||||
unsigned char GreenMaskPos ;
|
||||
unsigned char BlueMaskSize ;
|
||||
unsigned char BlueMaskPos ;
|
||||
unsigned char ReservedMaskSize ;
|
||||
unsigned char ReservedMaskPos ;
|
||||
unsigned char DirectColorModeInfo ;
|
||||
unsigned int PhysBasePtr ;
|
||||
unsigned int OffScreenMemOffset ;
|
||||
unsigned short OffScreenMemSize ;
|
||||
unsigned char Reserved[206] ;
|
||||
}__attribute__ ((packed));
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
32
kernel/hal/x86_64/include/Multitasking.hpp
Normal file
32
kernel/hal/x86_64/include/Multitasking.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef MULTITASKING_H
|
||||
#define MULTITASKING_H
|
||||
namespace MTGosHAL {
|
||||
|
||||
class Multitasking
|
||||
{
|
||||
public:
|
||||
Multitasking();
|
||||
auto schedule(struct cpu_state* cpu) -> struct cpu_state*;
|
||||
auto initTask(void(*entry)()) -> struct cpu_state*;
|
||||
uint32_t tss[32];
|
||||
protected:
|
||||
private:
|
||||
Task* first_task;
|
||||
Task* curr_task;
|
||||
};
|
||||
class Task
|
||||
{
|
||||
private:
|
||||
struct cpu_state* cpu_state;
|
||||
Task* next;
|
||||
public:
|
||||
Task(struct cpu_state*);
|
||||
auto unpause() -> struct cpu_state*;
|
||||
auto pause(struct cpu_state*) -> Task *;
|
||||
auto addTask(Task*) -> void;
|
||||
auto hasNext() -> bool;
|
||||
};
|
||||
|
||||
} // namespace MTGosHAL
|
||||
|
||||
#endif // MULTITASKING_H
|
32
kernel/hal/x86_64/include/gdt.hpp
Normal file
32
kernel/hal/x86_64/include/gdt.hpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef _GDT_HPP
|
||||
#define _GDT_HPP
|
||||
#include <stdint.h>
|
||||
#define GDT_FLAG_DATASEG 0x02
|
||||
#define GDT_FLAG_CODESEG 0x0a
|
||||
#define GDT_FLAG_TSS 0x09
|
||||
|
||||
#define GDT_FLAG_SEGMENT 0x10
|
||||
#define GDT_FLAG_RING0 0x00
|
||||
#define GDT_FLAG_RING3 0x60
|
||||
#define GDT_FLAG_PRESENT 0x80
|
||||
|
||||
#define GDT_FLAG_4K_GRAN 0x800
|
||||
#define GDT_FLAG_32_BIT 0x400
|
||||
#define GDT_FLAG_64_BIT 0x200
|
||||
extern "C" void loadGDT(void * gdtpr);
|
||||
namespace MTGosHAL {
|
||||
class GDT {
|
||||
private:
|
||||
uint64_t gdt[7];
|
||||
struct gdtp {
|
||||
uint16_t limit;
|
||||
void* pointer;
|
||||
} __attribute__((packed));
|
||||
struct gdtp fin;
|
||||
public:
|
||||
GDT();
|
||||
auto setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void;
|
||||
auto apply() -> void;
|
||||
};
|
||||
}
|
||||
#endif
|
70
kernel/hal/x86_64/include/idt.hpp
Normal file
70
kernel/hal/x86_64/include/idt.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
namespace MTGosHAL {
|
||||
struct cpu_state {
|
||||
double st7;
|
||||
double st6;
|
||||
double st5;
|
||||
double st4;
|
||||
double st3;
|
||||
double st2;
|
||||
double st1;
|
||||
double st0;
|
||||
uint64_t rax;
|
||||
uint64_t rbx;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
uint64_t rsi;
|
||||
uint64_t rdi;
|
||||
uint64_t rbp;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r12;
|
||||
uint64_t r13;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
|
||||
uint64_t intr;
|
||||
uint64_t error;
|
||||
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
};
|
||||
class IDT {
|
||||
private:
|
||||
unsigned __int128 idt[256];
|
||||
struct cpu_state* (*ivt[256][16])(struct cpu_state *);
|
||||
struct idtp {
|
||||
uint16_t limit;
|
||||
unsigned __int128* 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) -> struct cpu_state*;
|
||||
auto request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool;
|
||||
};
|
||||
}
|
||||
#endif
|
23
kernel/hal/x86_64/include/keyboard.hpp
Normal file
23
kernel/hal/x86_64/include/keyboard.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _KEYBOARD_HPP
|
||||
#define _KEYBOARD_HPP
|
||||
#include <stdint.h>
|
||||
#include <input.hpp>
|
||||
#include <io.h>
|
||||
#include <idt.hpp>
|
||||
namespace MTGosHAL {
|
||||
|
||||
class Keyboard: public Input {
|
||||
private:
|
||||
|
||||
//This kernel has a buffer of 16 chars
|
||||
char buf[16];
|
||||
int len;
|
||||
auto getChar() -> char;
|
||||
auto sendCommand(uint8_t command) -> void;
|
||||
bool numlock, capslock, scrolllock, response;
|
||||
public:
|
||||
auto handleIRQ1(struct cpu_state* cpu) -> struct cpu_state*;
|
||||
Keyboard();
|
||||
};
|
||||
}
|
||||
#endif // -Wno-pmf-conversions
|
28
kernel/hal/x86_64/include/pmm.hpp
Normal file
28
kernel/hal/x86_64/include/pmm.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _PMM_HPP
|
||||
#define _PMM_HPP
|
||||
#include <pmm2.hpp>
|
||||
#include <stdint.h>
|
||||
#include <multiboot.h>
|
||||
namespace MTGosHAL {
|
||||
struct malloc_t {
|
||||
size_t len;
|
||||
malloc_t *last;
|
||||
malloc_t *next;
|
||||
};
|
||||
class PMM {
|
||||
private:
|
||||
malloc_t *head;
|
||||
PMM2 pmm2;
|
||||
public:
|
||||
PMM();
|
||||
PMM(struct multiboot_info* mb_info): PMM() {init(mb_info);}
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
auto alloc(size_t length) -> void *;
|
||||
auto free(void* ptr) -> bool;
|
||||
auto markUsed(const void * addr, uint64_t length) -> bool;
|
||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
||||
auto operator << (const void * addr) -> PMM &; //free
|
||||
auto operator()(int pages) -> void*; //alloc_multipage
|
||||
};
|
||||
}
|
||||
#endif
|
20
kernel/hal/x86_64/include/pmm2.hpp
Normal file
20
kernel/hal/x86_64/include/pmm2.hpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef _PMM2_HPP
|
||||
#define _PMM2_HPP
|
||||
#include <pmm3.hpp>
|
||||
#include <stdint.h>
|
||||
#include <multiboot.h>
|
||||
namespace MTGosHAL {
|
||||
class PMM2 {
|
||||
private:
|
||||
uint64_t *pageTable;
|
||||
PMM3 pmm3;
|
||||
public:
|
||||
PMM2();
|
||||
auto markUsed(const void * addr, uint32_t length) -> bool;
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
auto operator >> (void * &addr) -> PMM2 &; //alloc
|
||||
auto operator << (const void * addr) -> PMM2 &; //free
|
||||
auto operator()(int pages) -> void*; //alloc_multipage
|
||||
};
|
||||
}
|
||||
#endif
|
18
kernel/hal/x86_64/include/pmm3.hpp
Normal file
18
kernel/hal/x86_64/include/pmm3.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef _PMM3_HPP
|
||||
#define _PMM3_HPP
|
||||
#include <stdint.h>
|
||||
#include <multiboot.h>
|
||||
namespace MTGosHAL {
|
||||
class PMM3 {
|
||||
private:
|
||||
uint32_t bitmap[0x8000]; //Enough for 512 GB (2MB pages)
|
||||
protected:
|
||||
public:
|
||||
PMM3();
|
||||
auto markUsed(const void * addr) -> void;
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
auto operator >> (void * &addr) -> PMM3 &; //alloc
|
||||
auto operator << (const void * addr) -> PMM3 &; //free
|
||||
};
|
||||
}
|
||||
#endif
|
31
kernel/hal/x86_64/include/serial.hpp
Normal file
31
kernel/hal/x86_64/include/serial.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _SERIAL_HPP
|
||||
#define _SERIAL_HPP
|
||||
#include <output.hpp>
|
||||
#include <input.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <io.h>
|
||||
#define SERIAL_IER 1
|
||||
#define SERIAL_IIR 2
|
||||
#define SERIAL_FCR 2
|
||||
#define SERIAL_LCR 3
|
||||
#define SERIAL_MCR 4
|
||||
#define SERIAL_LSR 5
|
||||
#define SERIAL_MSR 6
|
||||
namespace MTGosHAL {
|
||||
class Serial: public Output, public Input {
|
||||
private:
|
||||
uint16_t port;
|
||||
uint64_t waittimes;
|
||||
uint64_t transmits;
|
||||
bool works;
|
||||
auto isTransmitEmpty() -> int;
|
||||
auto putChar(char chr) -> void;
|
||||
auto serial_received() -> int;
|
||||
auto getChar() -> char;
|
||||
public:
|
||||
Serial();
|
||||
auto debug() -> void;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
73
kernel/hal/x86_64/include/textDISP.hpp
Normal file
73
kernel/hal/x86_64/include/textDISP.hpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
#ifndef _TEXTDISP_H
|
||||
#define _TEXTDISP_H
|
||||
#include <base.hpp>
|
||||
#include <stdint.h>
|
||||
#include <output.hpp>
|
||||
#include <multiboot.h>
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 96
|
||||
namespace MTGosHAL {
|
||||
enum class BG_color : uint32_t {
|
||||
BLACK=0x000000,
|
||||
BLUE=0x0000AA,
|
||||
GREEN=0x00AA00,
|
||||
CYAN=0x00AAAA,
|
||||
RED=0xAA0000,
|
||||
MAGENTA=0xAA00AA,
|
||||
BROWN=0xAA5500,
|
||||
LIGHT_GREY=0xAAAAAA,
|
||||
GREY=0x555555,
|
||||
LIGHT_BLUE=0x5555FF,
|
||||
LIGHT_GREEN=0x55FF55,
|
||||
LIGHT_CYAN=0x55FFFF,
|
||||
LIGHT_RED=0xFF5555,
|
||||
LIGHT_MAGENTA=0xFF55FF,
|
||||
YELLOW=0xFFFF55,
|
||||
WHITE=0xFFFFFF
|
||||
};
|
||||
enum class FG_color : uint32_t {
|
||||
BLACK=0x000000,
|
||||
BLUE=0x0000AA,
|
||||
GREEN=0x00AA00,
|
||||
CYAN=0x00AAAA,
|
||||
RED=0xAA0000,
|
||||
MAGENTA=0xAA00AA,
|
||||
BROWN=0xAA5500,
|
||||
LIGHT_GREY=0xAAAAAA,
|
||||
GREY=0x555555,
|
||||
LIGHT_BLUE=0x5555FF,
|
||||
LIGHT_GREEN=0x55FF55,
|
||||
LIGHT_CYAN=0x55FFFF,
|
||||
LIGHT_RED=0xFF5555,
|
||||
LIGHT_MAGENTA=0xFF55FF,
|
||||
YELLOW=0xFFFF55,
|
||||
WHITE=0xFFFFFF
|
||||
};
|
||||
class Screen: public Output {
|
||||
private:
|
||||
FG_color fg;
|
||||
BG_color bg;
|
||||
uint32_t* lfb;
|
||||
auto putChar(char c) -> void;
|
||||
public:
|
||||
Screen(): fg(FG_color::WHITE), bg(BG_color::BLACK) {
|
||||
}
|
||||
Screen(struct multiboot_info* mb_info): Screen() {init(mb_info);}
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
template <typename T>
|
||||
auto operator<< (T output) -> Screen & {
|
||||
Output::operator<<<T>(output);
|
||||
return *this;
|
||||
}
|
||||
auto clrscr() -> void;
|
||||
auto scroll() -> void;
|
||||
auto setColor(FG_color fg) -> Screen &;
|
||||
auto setColor(BG_color bg) -> Screen &;
|
||||
auto setColor(FG_color fg, BG_color bg) -> Screen &;
|
||||
};
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &;
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &;
|
||||
}
|
||||
#endif
|
90
kernel/hal/x86_64/init/Multitasking.cpp
Normal file
90
kernel/hal/x86_64/init/Multitasking.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <base.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <Multitasking.hpp>
|
||||
#include <serial.hpp>
|
||||
#include <blockdev.hpp>
|
||||
#include <idt.hpp>
|
||||
#include <pmm.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return MTGosHAL::tasks.schedule(cpu);
|
||||
}
|
||||
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
|
||||
{
|
||||
for(int i=0;i<32;i++) {
|
||||
if(i==2)
|
||||
continue;
|
||||
tss[i]=0;
|
||||
}
|
||||
tss[2]=0x10;
|
||||
//task_states[0] = initTask(stack_a, user_stack_a, task_a);
|
||||
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
|
||||
if(!idt.request(0x20,MTGosHAL::schedule)) {
|
||||
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
|
||||
while(true)
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
||||
{
|
||||
void* tmp1, *tmp2;
|
||||
mm >> tmp1 >> tmp2;
|
||||
uint8_t *stack=(uint8_t*)tmp1, *user_stack=(uint8_t*)tmp2;
|
||||
struct cpu_state new_state = {
|
||||
0.0, //ST0
|
||||
0.0, //ST1
|
||||
0.0, //ST2
|
||||
0.0, //ST3
|
||||
0.0, //ST4
|
||||
0.0, //ST5
|
||||
0.0, //ST6
|
||||
0.0, //ST7
|
||||
0, //RAX
|
||||
0, //RBX
|
||||
0, //RCX
|
||||
0, //RDX
|
||||
0, //RSI
|
||||
0, //RDI
|
||||
0, //RBP
|
||||
0, //R8
|
||||
0, //R9
|
||||
0, //r10
|
||||
0, //r11
|
||||
0, //r12
|
||||
0, //r13
|
||||
0, //r14
|
||||
0, //r15
|
||||
0, //INTR
|
||||
0, //ERROR
|
||||
(uint64_t) entry, //RIP
|
||||
0x18 | 0x03, //CS
|
||||
0x202, // RFLAGS
|
||||
(uint64_t) user_stack+0x200000, //RSP
|
||||
0x20 | 0x03 //SS
|
||||
};
|
||||
struct cpu_state* state = (struct cpu_state*)(stack+0x200000-sizeof(new_state));
|
||||
*state = new_state;
|
||||
//Create new task class
|
||||
Task* task = new Task(state);
|
||||
if(first_task)
|
||||
first_task->addTask(task);
|
||||
else {
|
||||
first_task=task;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
|
||||
{
|
||||
Task* next=nullptr;
|
||||
if(curr_task) {
|
||||
next=curr_task->pause(cpu);
|
||||
}
|
||||
if (!next) {
|
||||
next=first_task;
|
||||
}
|
||||
curr_task=next;
|
||||
struct cpu_state* cpu_state=next->unpause();
|
||||
MTGosHAL::tasks.tss[1] = (uint32_t) (uint64_t)(cpu_state + 1);
|
||||
return cpu_state;
|
||||
}
|
||||
} // namespace MTGosHAL
|
21
kernel/hal/x86_64/init/gdt.cpp
Normal file
21
kernel/hal/x86_64/init/gdt.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <base.hpp>
|
||||
#include <gdt.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
GDT::GDT() {
|
||||
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
|
||||
}
|
||||
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
|
||||
gdt[i] = limit & 0xffffLL;
|
||||
gdt[i] |= (base & 0xffffffLL) << 16;
|
||||
gdt[i] |= (flags & 0xffLL) << 40;
|
||||
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
||||
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
||||
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
||||
}
|
||||
auto GDT::apply() -> void {
|
||||
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
|
||||
fin={(uint16_t)7*8-1, (void*)gdt};
|
||||
loadGDT((void*)(&fin));
|
||||
};
|
||||
}
|
91
kernel/hal/x86_64/init/idt.cpp
Normal file
91
kernel/hal/x86_64/init/idt.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <base.hpp>
|
||||
#include <io.h>
|
||||
#include <idt.hpp>
|
||||
#include <serial.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <pmm.hpp>
|
||||
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void*;
|
||||
extern void** progs;
|
||||
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)((uint64_t)offset);
|
||||
idt[i]|=(unsigned __int128)(((uint64_t)offset)>>16)<<48;
|
||||
idt[i]|=((unsigned __int128)seg)<<16;
|
||||
idt[i]|=((unsigned __int128)flags)<<40;
|
||||
}
|
||||
auto IDT::apply() -> void {
|
||||
debug << "Now trying to load the IDT.\n";
|
||||
idtptr.limit=(uint16_t)(256*8-1);
|
||||
idtptr.pointer=(unsigned __int128*)&idt;
|
||||
loadIDT((void*)&idtptr);
|
||||
}
|
||||
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
struct cpu_state* new_cpu=cpu;
|
||||
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
|
||||
if(cpu->intr<=0x1F) {
|
||||
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
|
||||
err << "EAX = 0x" << (int)cpu->rax << " - EBX = 0x" << (int)cpu->rbx << "\n";
|
||||
err << "ECX = 0x" << (int)cpu->rcx << " - EDX = 0x" << (int)cpu->rdx << "\n";
|
||||
err << "ESI = 0x" << (int)cpu->rsi << " - EDI = 0x" << (int)cpu->rdi << "\n";
|
||||
err << "SS:ESP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rsp << " - SS:EBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rbp << "\n";
|
||||
err << "CS:EIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->rip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
|
||||
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
|
||||
for(int i=0;i<1024;i++) {
|
||||
if(!progs[i])
|
||||
break;
|
||||
err << "0x" << (int)((uint64_t)progs[i]) << "; ";
|
||||
}
|
||||
err << "\n";
|
||||
uint16_t counter = 1193180 / 220; //Make an annoying beep
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, (uint8_t)counter);
|
||||
outb(0x42, (uint8_t)(counter>>8));
|
||||
outb(0x61, inb(0x61) | 3);
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
|
||||
if(cpu->intr >= 0x28) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
|
||||
if(cpu->intr==0x20) {
|
||||
debug.debug();
|
||||
}
|
||||
}
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[cpu->intr][i])
|
||||
new_cpu=ivt[cpu->intr][i](new_cpu);
|
||||
}
|
||||
if(cpu->intr>=48)
|
||||
new_cpu->rax=(uint64_t)(::syscall(cpu->rax, (void*)(cpu->rbx), (void*)(cpu->rsp)));
|
||||
return new_cpu;
|
||||
}
|
||||
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[intr][i])
|
||||
continue;
|
||||
ivt[intr][i]=handler;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
extern "C" void* handleINT(void* cpu) {
|
||||
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
|
||||
}
|
73
kernel/hal/x86_64/init/init.cpp
Normal file
73
kernel/hal/x86_64/init/init.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
#include <base.hpp>
|
||||
#include <output.hpp>
|
||||
#include <serial.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <keyboard.hpp>
|
||||
#include <Multitasking.hpp>
|
||||
#include <multiboot.h>
|
||||
#include <blockdev.hpp>
|
||||
#include <gdt.hpp>
|
||||
#include <idt.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" void intr_stub_0(void);
|
||||
void main(void ** programs);
|
||||
void** progs;
|
||||
namespace MTGosHAL {
|
||||
Serial debug;
|
||||
GDT gdt;
|
||||
IDT idt;
|
||||
PMM mm;
|
||||
Screen out;
|
||||
Screen err;
|
||||
Keyboard in;
|
||||
Multitasking tasks;
|
||||
void main(long eax, struct multiboot_info* ebx, uint64_t**** pt) {
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
gdt.setEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_64_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_64_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_64_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
||||
gdt.setEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_64_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
||||
gdt.setEntry(5, (uint64_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.apply();
|
||||
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
for(int i=0;i<256;i++) {
|
||||
idt.setEntry(i, (void *)((uint64_t)&intr_stub_0+i*32), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
}
|
||||
idt.setEntry(48, (void *)((uint64_t)&intr_stub_0+768*2), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
|
||||
idt.setEntry(8, (void *)((uint64_t)&intr_stub_0+128*2), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.apply();
|
||||
asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
|
||||
debug << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
|
||||
debug << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
}
|
||||
}
|
||||
typedef void (*constructor)();
|
||||
typedef void (*destructor)();
|
||||
extern "C" destructor start_dtors;
|
||||
extern "C" destructor end_dtors;
|
||||
extern "C" void init(int eax, struct multiboot_info* ebx, uint64_t**** ecx) {
|
||||
MTGosHAL::main(eax, ebx,ecx);
|
||||
for(destructor* i = &start_dtors; i != &end_dtors; i++)
|
||||
(*i)();
|
||||
}
|
||||
extern "C" void __cxa_pure_virtual() {
|
||||
MTGosHAL::debug << "A pure virtual function just got called.\n";
|
||||
}
|
128
kernel/hal/x86_64/io/keyboard.cpp
Normal file
128
kernel/hal/x86_64/io/keyboard.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include <base.hpp>
|
||||
#include <output.hpp>
|
||||
#include <serial.hpp>
|
||||
#include <keyboard.hpp>
|
||||
#include <keymap_DE.hpp>
|
||||
|
||||
namespace MTGosHAL {
|
||||
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return in.handleIRQ1(cpu);
|
||||
}
|
||||
auto Keyboard::getChar() -> char {
|
||||
char chr=buf[0];
|
||||
for(int i=0;i<15;i++) {
|
||||
buf[i]=buf[i+1];
|
||||
}
|
||||
buf[15]='\0';
|
||||
if(len)
|
||||
len--;
|
||||
return chr;
|
||||
}
|
||||
auto Keyboard::sendCommand(uint8_t command) -> void {
|
||||
while((inb(0x64) & 0x2));
|
||||
outb(0x60, command);
|
||||
}
|
||||
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
uint8_t keycode=0,scancode=inb(0x60);
|
||||
if(scancode==0xFA) {
|
||||
response=false;
|
||||
return cpu;
|
||||
} else if(response && scancode == 0xFE) {
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
return cpu;
|
||||
}
|
||||
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
|
||||
bool break_code=false;
|
||||
static bool e0_code=false;
|
||||
static int e1_code=0;
|
||||
static uint16_t e1_prev=0;
|
||||
uint8_t tableID=0;
|
||||
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
|
||||
break_code = true;
|
||||
scancode &= ~0x80;
|
||||
}
|
||||
if(e0_code) {
|
||||
if((scancode==0x2A) || (scancode = 0x36)) {
|
||||
e0_code = false;
|
||||
return cpu;
|
||||
}
|
||||
keycode=keyboardKeycodes[1][scancode];
|
||||
e0_code=false;
|
||||
} else if (e1_code == 2) {
|
||||
e1_prev |= ((uint16_t) scancode << 8);
|
||||
//TODO. translate it, although I might not even use this code
|
||||
return cpu;
|
||||
} else if (e1_code) {
|
||||
e1_prev = scancode;
|
||||
e1_code++;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE0) {
|
||||
e0_code = true;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE1) {
|
||||
e1_code = true;
|
||||
return cpu;
|
||||
} else {
|
||||
keycode=keyboardKeycodes[0][scancode];
|
||||
}
|
||||
//Now put it into the keystate array
|
||||
if(break_code)
|
||||
keydowns[keycode]=false;
|
||||
else
|
||||
keydowns[keycode]=true;
|
||||
//0x2A 0x36 = Shift
|
||||
if(keydowns[0x2A] || keydowns[0x36])
|
||||
tableID^=1;
|
||||
//0x1D = Ctrl
|
||||
if(keydowns[0x1D])
|
||||
tableID^=2;
|
||||
//0x38 = Alt
|
||||
if(keydowns[0x38])
|
||||
tableID^=4;
|
||||
|
||||
//0x45 = Numlock
|
||||
if(keycode==0x45)
|
||||
numlock=!numlock;
|
||||
//0x3A = CAPS
|
||||
if(keycode==0x3A)
|
||||
capslock=!capslock;
|
||||
//0x46 = Scrolllock
|
||||
if(keycode==0x46)
|
||||
scrolllock=!scrolllock;
|
||||
|
||||
if(capslock)
|
||||
tableID^=1;
|
||||
//Correct the LEDs
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
response=true;
|
||||
//Convert it into a char
|
||||
if(!break_code)
|
||||
out << keymap[tableID][keycode];
|
||||
debug << " -> 0x" << (int)keycode << ".\n";
|
||||
return cpu;
|
||||
}
|
||||
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
|
||||
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
|
||||
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
|
||||
return;
|
||||
}
|
||||
//Clear keyboard buffer
|
||||
while(inb(0x64) & 0x1) {
|
||||
inb(0x60);
|
||||
}
|
||||
sendCommand(0xF4); //Activate keyboard
|
||||
//Check for self-test being passed
|
||||
sendCommand(0x20);
|
||||
uint8_t ccb=inb(0x60);
|
||||
if((ccb&4)) {
|
||||
ccb &= ~1;
|
||||
} else {
|
||||
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
|
||||
ccb |= 1;
|
||||
}
|
||||
sendCommand(0x60);
|
||||
outb(0x64, ccb);
|
||||
}
|
||||
}
|
78
kernel/hal/x86_64/io/serial.cpp
Normal file
78
kernel/hal/x86_64/io/serial.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <base.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto Serial::isTransmitEmpty() -> int {
|
||||
return inb(port+SERIAL_LSR)&0x20;
|
||||
}
|
||||
auto Serial::putChar(char chr) -> void {
|
||||
// if(!works)
|
||||
return;
|
||||
int tries=65535;
|
||||
while(!isTransmitEmpty()) {
|
||||
waittimes++;
|
||||
tries--;
|
||||
if(!tries){
|
||||
works=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
outb(port, chr);
|
||||
transmits++;
|
||||
}
|
||||
auto Serial::serial_received() -> int {
|
||||
return inb(port+SERIAL_LSR)&1;
|
||||
}
|
||||
auto Serial::getChar() -> char {
|
||||
//We try 500 times to get a character
|
||||
int tries=500;
|
||||
while(!serial_received()) {
|
||||
tries--;
|
||||
waittimes++;
|
||||
if(!tries) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
transmits++;
|
||||
char chr = inb(port);
|
||||
if(chr!='\r')
|
||||
*this << chr;
|
||||
else
|
||||
*this << '\n';
|
||||
return chr;
|
||||
}
|
||||
Serial::Serial(): works(true) {
|
||||
uint32_t baud=115200;
|
||||
port=*((uint16_t*)0x0400);
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200/baud;
|
||||
//Turn off interrupts
|
||||
outb(port+SERIAL_IER, 0x00);
|
||||
//Set DLAB-bit
|
||||
outb(port+SERIAL_LCR, 0x80);
|
||||
//Set baud divisor
|
||||
outb(port, divisor.b[0]);
|
||||
outb(port+1, divisor.b[1]);
|
||||
//Set bit count, parity and reset DLAB
|
||||
outb(port+SERIAL_LCR, 3);
|
||||
//Finish init
|
||||
outb(port+SERIAL_FCR, 0xC7);
|
||||
outb(port+SERIAL_MCR, 0x0B);
|
||||
}
|
||||
auto Serial::debug() -> void {
|
||||
if(getChar()) {
|
||||
*this << "The interactive debug shell was started.\n> ";
|
||||
out << "The debug shell was started.\n";
|
||||
char buf[256];
|
||||
*this >> buf;
|
||||
out << buf << "\nDebug shell closed.\n";
|
||||
*this << "Unknown command. TODO\n";
|
||||
}
|
||||
uint64_t wt = waittimes;
|
||||
uint64_t tm = transmits;
|
||||
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
|
||||
waittimes=transmits=0;
|
||||
}
|
||||
}
|
21
kernel/hal/x86_64/io/textDISP.cpp
Normal file
21
kernel/hal/x86_64/io/textDISP.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <base.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <string.h>
|
||||
#include <stdfnt.h>
|
||||
namespace MTGosHAL {
|
||||
auto Screen::init(struct multiboot_info* mb_info) -> void {
|
||||
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
|
||||
//clrscr();
|
||||
//Render '\001' character
|
||||
for(int tx=0;tx<16;tx++) {
|
||||
for(int ty=0;ty<16;ty++) {
|
||||
for(int x=0;x<8;x++) {
|
||||
for(int y=0;y<8;y++) {
|
||||
if(font[tx+ty*16][y]&(1<<x))
|
||||
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
kernel/hal/x86_64/mm/pmm.cpp
Normal file
24
kernel/hal/x86_64/mm/pmm.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <base.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" const int kernel_start;
|
||||
extern "C" const int kernel_end; //those are voids actually
|
||||
namespace MTGosHAL {
|
||||
PMM::PMM(): head(nullptr), pmm2() {}
|
||||
auto PMM::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm2.init(mb_info);
|
||||
}
|
||||
auto PMM::markUsed(const void * addr, uint64_t length) -> bool {
|
||||
return pmm2.markUsed(addr, length);
|
||||
}
|
||||
auto PMM::operator >> (void * &addr) -> PMM & {
|
||||
pmm2>>addr;
|
||||
return *this;
|
||||
} //alloc
|
||||
auto PMM::operator << (const void * addr) -> PMM & {
|
||||
pmm2<<addr;
|
||||
return *this;
|
||||
} //free
|
||||
auto PMM::operator()(int pages) -> void*{
|
||||
return pmm2(pages);
|
||||
} //alloc_multipage
|
||||
}
|
83
kernel/hal/x86_64/mm/pmm2.cpp
Normal file
83
kernel/hal/x86_64/mm/pmm2.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include <pmm2.hpp>
|
||||
#include <base.hpp>
|
||||
//In this part, please remember that the address is split into 2 parts. Bitmap:
|
||||
// AAA AAAA AAAA AAAA AAAB BBBB BBBB BBBB BBBB BBBB
|
||||
#define SPLIT1_FLAG 0x3ffff00000ull
|
||||
#define SPLIT1_SHIFT(a) ((a)<<20)
|
||||
#define SPLIT1_UNSHIFT(a) ((a)>>20)
|
||||
#define SPLIT2_FLAG 0xFFFFFull
|
||||
#define SPLIT2_SHIFT(a) ((a))
|
||||
#define SPLIT2_UNSHIFT(a) ((a)&SPLIT2_FLAG)
|
||||
|
||||
extern "C" const int kernel_start;
|
||||
extern "C" const int kernel_end; //those are voids actually
|
||||
|
||||
namespace MTGosHAL {
|
||||
PMM2::PMM2(): pmm3() {
|
||||
}
|
||||
auto PMM2::markUsed(const void * addr, uint32_t length) -> bool {
|
||||
uintptr_t add=(uintptr_t)addr;
|
||||
uint32_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
|
||||
//Check if used
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x200000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint64_t counter=1;
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x200000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)]=counter++;
|
||||
pmm3.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
auto PMM2::operator >> (void * &addr) -> PMM2 & {
|
||||
pmm3 >> addr;
|
||||
markUsed(addr,0x200000);
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator << (const void *addr) -> PMM2 & {
|
||||
uint64_t add=(uint64_t)addr;
|
||||
for(uint64_t i=0;i<pageTable[SPLIT1_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*0x200000)]=0;
|
||||
pmm3 << (void*)(add+i*0x200000);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator()(int pages) -> void* {
|
||||
//I want to get this working so:
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
for(uint64_t i=0;i<(uint64_t)(-(pages*0x200000));i+=0x200000) {
|
||||
if(markUsed((void*)i,pages*0x200000))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
auto PMM2::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm3.init(mb_info);
|
||||
void *temp;
|
||||
pmm3 >> temp;
|
||||
pageTable=(uint64_t*)temp;
|
||||
for(int i=0;i<0x80000;i++)
|
||||
pageTable[i]=0;
|
||||
markUsed(pageTable,0x200000);
|
||||
markUsed((void*)nullptr,0x200000);
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
markUsed(&kernel_start,((uintptr_t)&kernel_end)-((uintptr_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uintptr_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)(uintptr_t)(mods[i].mod_start),mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
}
|
||||
}
|
71
kernel/hal/x86_64/mm/pmm3.cpp
Normal file
71
kernel/hal/x86_64/mm/pmm3.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <stdint.h>
|
||||
#include <base.hpp>
|
||||
#include <pmm3.hpp>
|
||||
#include <multiboot.h>
|
||||
extern "C" const int kernel_start;
|
||||
extern "C" const int kernel_end; //those are voids actually
|
||||
namespace MTGosHAL {
|
||||
PMM3::PMM3() {}
|
||||
auto PMM3::init(struct multiboot_info * mb_info) -> void {
|
||||
for(int i=0;i<0x8000;i++)
|
||||
bitmap[i]=0;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while (mmap < mmap_end) {
|
||||
if (mmap->type == 1) {
|
||||
// Memory is free
|
||||
uintptr_t addr = mmap->addr;
|
||||
uintptr_t end_addr = addr + mmap->len;
|
||||
while (addr < end_addr) {
|
||||
*this << (void*) addr;
|
||||
addr += 0x200000;
|
||||
}
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
uintptr_t addr = (uintptr_t) &kernel_start;
|
||||
while(addr < (uintptr_t) &kernel_end) {
|
||||
markUsed((void*)addr);
|
||||
addr+=0x200000;
|
||||
}
|
||||
markUsed((void*)0);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint64_t)(&mods[i])&(~0x1FFFFF))); //Mark all of the module table as used
|
||||
for(uint64_t start=(uint64_t)(mods[i].mod_start)&(~0x1FFFFF);start<(uint32_t)(mods[i].mod_end);start+=0x200000) {
|
||||
markUsed((void*)start); //Protect all multiboot modules
|
||||
}
|
||||
}
|
||||
}
|
||||
auto PMM3::markUsed(const void * addr) -> void {
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
}
|
||||
auto PMM3::operator >> (void * &addr) -> PMM3 & {
|
||||
for(uintptr_t i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
for(uintptr_t j=0;j<32;j++) {
|
||||
if(bitmap[i]&(1<<j)) {
|
||||
//We found a free page!
|
||||
bitmap[i]&=~(1<<j);
|
||||
addr=(void*)(((i<<5)+j)<<21);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
addr=nullptr;
|
||||
return *this;
|
||||
}
|
||||
auto PMM3::operator << (const void * addr) -> PMM3 & {
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]|=bit;
|
||||
return *this;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ SECTIONS
|
|||
*(multiboot)
|
||||
*(.text)
|
||||
}
|
||||
.data ALIGN(4096) : {
|
||||
.data ALIGN(0x200000) : {
|
||||
start_ctors = .;
|
||||
KEEP(*( .init_array ));
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
|
||||
|
@ -20,12 +20,12 @@ SECTIONS
|
|||
end_dtors = .;
|
||||
*(.data)
|
||||
}
|
||||
.rodata ALIGN(4096) : {
|
||||
.rodata ALIGN(0x200000) : {
|
||||
*(.rodata)
|
||||
}
|
||||
.bss ALIGN(4096) : {
|
||||
.bss ALIGN(0x200000) : {
|
||||
*(.bss)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(0x200000);
|
||||
kernel_end = .;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ SRCS = $(shell find -name '*.cpp' -o -name '*.c')
|
|||
OBJS = $(addsuffix .o,$(basename $(SRCS)))
|
||||
CPP = $(PREFIX)g++
|
||||
CC = $(PREFIX)gcc
|
||||
ASFLAGS = -m32
|
||||
CFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -std=c11 -fno-builtin -Werror -nostdlib -g -fpie
|
||||
CPPFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fpie
|
||||
ASFLAGS = $(ARCHFLAGS)
|
||||
CFLAGS = $(ARCHFLAGS) -Wall -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -std=c11 -fno-builtin -Werror -nostdlib -g -fpie
|
||||
CPPFLAGS = $(ARCHFLAGS) -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fpie
|
||||
all: $(OBJS)
|
||||
|
||||
%.o: %.cpp
|
||||
|
|
|
@ -11,7 +11,7 @@ auto load(Elf32_Ehdr* file) -> void* {
|
|||
return nullptr;
|
||||
debug << "File is not a valid ELF file!\n";
|
||||
}
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr*)((uint32_t)(file->e_phoff)+(uint32_t)file);
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
|
||||
debug << "entry=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)file->e_entry;
|
||||
|
@ -27,8 +27,8 @@ auto load(Elf32_Ehdr* file) -> void* {
|
|||
if((start <= file->e_entry) && (file->e_entry < end)) {
|
||||
debug << "start=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uint32_t)file);
|
||||
return (void*) (file->e_entry-start+phdr[i].p_offset+(uint32_t)file); //Calculate _start address
|
||||
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uintptr_t)file);
|
||||
return (void*) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _BASE_HPP
|
||||
#define _BASE_HPP
|
||||
#include <stdint.h>
|
||||
void * operator new (size_t, void * p);
|
||||
void * operator new[] (size_t, void * p);
|
||||
void operator delete (void *, void *);
|
||||
void operator delete[] (void *, void *);
|
||||
namespace MTGosHAL {
|
||||
class Output;
|
||||
class Input;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <stdint.h>
|
||||
namespace MTGosHAL {
|
||||
struct malloc_t {
|
||||
uint32_t len;
|
||||
size_t len;
|
||||
malloc_t *last;
|
||||
malloc_t *next;
|
||||
};
|
||||
|
@ -12,7 +12,7 @@ private:
|
|||
malloc_t *head;
|
||||
public:
|
||||
PMM();
|
||||
auto alloc(uint32_t length) -> void *;
|
||||
auto alloc(size_t length) -> void *;
|
||||
auto free(void* ptr) -> bool;
|
||||
auto markUsed(const void * addr, uint32_t length) -> bool;
|
||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <Multitasking.hpp>
|
||||
#include <blockdev.hpp>
|
||||
#include <elf.hpp>
|
||||
void * operator new (size_t, void * p) { return p ; }
|
||||
void * operator new[] (size_t, void * p) { return p ; }
|
||||
void operator delete (void *, void *) { }
|
||||
void operator delete[] (void *, void *) { }
|
||||
using namespace MTGosHAL;
|
||||
void pid_null() {
|
||||
for(;;);
|
||||
|
|
|
@ -21,7 +21,7 @@ void operator delete[](void* p, size_t size) {
|
|||
}
|
||||
namespace MTGosHAL {
|
||||
|
||||
auto PMM::alloc(uint32_t length) -> void * {
|
||||
auto PMM::alloc(size_t length) -> void * {
|
||||
if(!head) {
|
||||
//Alloc space for head
|
||||
if(length+sizeof(malloc_t)<=4096) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
|
@ -41,9 +41,9 @@ namespace MTGosHAL {
|
|||
malloc_t* curr=head;
|
||||
malloc_t* last=nullptr;
|
||||
do {
|
||||
uint32_t loc=(uint32_t)curr+sizeof(malloc_t)+curr->len;
|
||||
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
|
||||
if((loc+length+sizeof(malloc_t))<((loc&(~0xFFF))+4096) &&
|
||||
((!curr->next) || (loc+length+sizeof(malloc_t))<((uint32_t)(curr->next)))) {
|
||||
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
|
||||
malloc_t *allocd=(malloc_t *)loc;
|
||||
allocd->len=length;
|
||||
allocd->last=curr;
|
||||
|
@ -83,9 +83,9 @@ namespace MTGosHAL {
|
|||
chk--;
|
||||
do {
|
||||
if(curr==chk) {
|
||||
uint32_t start=((uint32_t)chk)&(~0xFFF);
|
||||
uint32_t end=start+0x1000;
|
||||
if((((uint32_t)(curr->last)<start)||((uint32_t)(curr->last)>=end))&&(((uint32_t)(curr->next)>=end)||((uint32_t)(curr->next)<start))) {
|
||||
uintptr_t start=((uintptr_t)chk)&(~0xFFF);
|
||||
uintptr_t end=start+0x1000;
|
||||
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
|
||||
*this << (void*)start;
|
||||
}
|
||||
if(curr->last)
|
||||
|
|
|
@ -15,7 +15,7 @@ void memmove(void* dst, void* src, uint32_t size) {
|
|||
}
|
||||
uint32_t strlen(const char* str) {
|
||||
uint32_t i=0;
|
||||
char* str2=(char*)((int)str);
|
||||
char* str2=(char*)((uintptr_t)str);
|
||||
while(*str2) {
|
||||
i++;
|
||||
str2++;
|
||||
|
|
BIN
test.elf
BIN
test.elf
Binary file not shown.
|
@ -4,9 +4,9 @@ OBJS = $(addsuffix .o,$(basename $(SRCS)))
|
|||
AS = $(PREFIX)gcc
|
||||
CPP = $(PREFIX)g++
|
||||
LD = $(PREFIX)ld
|
||||
ASFLAGS = -m32
|
||||
CPPFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fpie
|
||||
LDFLAGS = -melf_i386 -Ttest.ld
|
||||
ASFLAGS = $(ARCHFLAGS)
|
||||
CPPFLAGS = $(ARCHFLAGS) -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fpie
|
||||
LDFLAGS = -Ttest-$(arch).ld
|
||||
test.elf: $(OBJS) $(arch)/syscall.o
|
||||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
|
||||
|
|
30
user/test-x86_64.ld
Normal file
30
user/test-x86_64.ld
Normal file
|
@ -0,0 +1,30 @@
|
|||
ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x400000;
|
||||
.text : {
|
||||
|
||||
*(.text)
|
||||
}
|
||||
.data ALIGN(0x200000) : {
|
||||
start_ctors = .;
|
||||
KEEP(*( .init_array ));
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
|
||||
*(.ctors)
|
||||
end_ctors = .;
|
||||
start_dtors = .;
|
||||
*(.dtors)
|
||||
end_dtors = .;
|
||||
*(.data)
|
||||
*(.got)
|
||||
}
|
||||
.rodata ALIGN(0x200000) : {
|
||||
*(.rodata)
|
||||
}
|
||||
.bss ALIGN(0x200000) : {
|
||||
*(.bss)
|
||||
}
|
||||
. = ALIGN(0x200000);
|
||||
}
|
|
@ -13,6 +13,14 @@ void main()
|
|||
int i;
|
||||
out.setColor(BGColor::BLUE, FGColor::YELLOW);
|
||||
for(;;) {
|
||||
out << arr;
|
||||
long double a;
|
||||
long double b=a;
|
||||
out << a;
|
||||
a+=0.5;
|
||||
if(a!=b+0.5)
|
||||
out << " ";
|
||||
else
|
||||
out << "=";
|
||||
out << a;
|
||||
}
|
||||
}
|
||||
|
|
62
user/x86_64/syscall.S
Normal file
62
user/x86_64/syscall.S
Normal file
|
@ -0,0 +1,62 @@
|
|||
.global screenout_init
|
||||
// void * screenout_init(int err);
|
||||
screenout_init:
|
||||
mov %rdi, %rax
|
||||
push %rax
|
||||
xor %rax, %rax
|
||||
int $0x30
|
||||
pop %rcx
|
||||
ret
|
||||
|
||||
.global screenout_out
|
||||
// void * screenout_out(void* handle, char *str);
|
||||
screenout_out:
|
||||
push %rbx
|
||||
mov %rsi, %rax
|
||||
mov %rdi, %rbx
|
||||
push %rax
|
||||
xor %rax, %rax
|
||||
inc %rax
|
||||
int $0x30
|
||||
pop %rbx
|
||||
pop %rbx
|
||||
ret
|
||||
|
||||
.global screenout_clear
|
||||
// void * screenout_clear(void* handle);
|
||||
screenout_clear:
|
||||
push %rbx
|
||||
mov %rdi, %rbx
|
||||
xor %rax, %rax
|
||||
inc %rax
|
||||
inc %rax
|
||||
int $0x30
|
||||
pop %rbx
|
||||
ret
|
||||
|
||||
.global screenout_setcolor
|
||||
// void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG)
|
||||
screenout_setcolor:
|
||||
push %rbx
|
||||
mov %rdi, %rbx
|
||||
mov %rsi, %rax
|
||||
mov %rdx, %rcx
|
||||
push %rcx
|
||||
push %rax
|
||||
mov $3, %rax
|
||||
int $0x30
|
||||
pop %rbx
|
||||
pop %rbx
|
||||
pop %rbx
|
||||
ret
|
||||
|
||||
.global screenout_destroy
|
||||
// void * screenout_destroy(void * handle)
|
||||
screenout_destroy:
|
||||
push %rbx
|
||||
mov %rdi, %rbx
|
||||
xor %rax, %rax
|
||||
dec %ax
|
||||
int $0x30
|
||||
pop %rbx
|
||||
ret
|
Loading…
Reference in a new issue