PMM should work now

This commit is contained in:
Morten Delenk 2016-04-16 19:59:17 +02:00
parent fe979e8774
commit 9a3a11d78c
12 changed files with 163 additions and 48 deletions

View file

@ -2,21 +2,31 @@
#define MULTITASKING_H
namespace MTGosHAL {
class Multitasking
{
public:
Multitasking();
auto schedule(struct cpu_state* cpu) -> struct cpu_state*;
protected:
private:
auto initTask(uint8_t* stck, void(*entry)()) -> struct cpu_state*;
static auto task_a() -> void;
static auto task_b() -> void;
uint8_t stack_a[4096];
uint8_t stack_b[4096];
struct cpu_state* task_states[2];
int current_task, num_tasks;
};
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:
static auto task_a() -> void;
static auto task_b() -> void;
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;
};
} // namespace MTGosHAL

View file

@ -9,6 +9,8 @@ namespace MTGosHAL {
class Keyboard;
class Multitasking;
class BlockDevice;
class Task;
class PMM;
enum class BG_color: uint16_t;
enum class FG_color: uint16_t;
extern Serial debug;
@ -17,5 +19,6 @@ namespace MTGosHAL {
extern Keyboard in;
extern Multitasking tasks;
extern BlockDevice disk;
extern PMM mm;
}
#endif

View file

@ -0,0 +1,17 @@
#ifndef _PMM_HPP
#define _PMM_HPP
#include <stdint.h>
namespace MTGosHAL {
class PMM {
private:
uint32_t bitmap[0x8000]; //Enough for 4 GB
auto markUsed(void * addr) -> void;
public:
PMM();
auto operator >> (void * &addr) -> PMM &; //alloc
auto operator << (const void * addr) -> PMM &; //free
auto operator()(int pages) -> void*; //alloc_multipage
};
}
#endif

View file

@ -14,10 +14,8 @@ _start:
push %ebx
push %eax
call init
_stop:
cli
hlt
jmp _stop
_exit:
int $0x1F
.section .bss
.space 8192
kernel_stack:

View file

@ -7,3 +7,4 @@ 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;

View file

@ -1,5 +1,7 @@
#ifndef MULTITASKING_H
#define MULTITASKING_H
#define PID_KERNEL 0
#define PID_INIT 1
#include <idt.hpp>
namespace MTGosHAL {
@ -8,18 +10,25 @@ namespace MTGosHAL {
public:
Multitasking();
auto schedule(struct cpu_state* cpu) -> struct cpu_state*;
auto initTask(void(*entry)()) -> struct cpu_state*;
uint32_t tss[32];
protected:
private:
auto initTask(uint8_t* stck, uint8_t* user_stck, void(*entry)()) -> struct cpu_state*;
static auto task_a() -> void;
static auto task_b() -> void;
uint8_t stack_a[4096];
uint8_t stack_b[4096];
uint8_t user_stack_a[4096];
uint8_t user_stack_b[4096];
struct cpu_state* task_states[2];
int current_task, num_tasks;
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;
};
} // namespace MTGosHAL

View file

@ -11,6 +11,8 @@ namespace MTGosHAL {
class IDT;
class Multitasking;
class BlockDevice;
class Task;
class PMM;
enum class BG_color: uint16_t;
enum class FG_color: uint16_t;
extern Serial debug;
@ -21,5 +23,6 @@ namespace MTGosHAL {
extern IDT idt;
extern Multitasking tasks;
extern BlockDevice disk;
extern PMM mm;
}
#endif

View file

@ -6,14 +6,14 @@ namespace MTGosHAL {
class PMM {
private:
uint32_t bitmap[0x8000]; //Enough for 4 GB
PMM() {}
auto markUsed(void * addr) -> void;
public:
PMM(struct multiboot_info*);
PMM();
auto init(struct multiboot_info*) -> void;
auto operator >> (void * &addr) -> PMM &; //alloc
auto operator << (const void * addr) -> PMM &; //free
auto operator()(int pages) -> void*; //alloc_multipage
};
}
#endif
#endif

View file

@ -3,12 +3,13 @@
#include <Multitasking.hpp>
#include <serial.hpp>
#include <blockdev.hpp>
#include <pmm.hpp>
auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
return MTGosHAL::tasks.schedule(cpu);
}
namespace MTGosHAL {
Multitasking::Multitasking(): current_task(-1), num_tasks(2)
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
{
for(int i=0;i<32;i++) {
if(i==2)
@ -16,16 +17,19 @@ Multitasking::Multitasking(): current_task(-1), num_tasks(2)
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);
//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,::schedule)) {
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
while(true);
asm volatile("cli; hlt");
}
}
auto Multitasking::initTask(uint8_t* stck, uint8_t* user_stck, void(* entry)()) -> struct cpu_state*
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, //EAX
0, //EBX
@ -39,11 +43,19 @@ auto Multitasking::initTask(uint8_t* stck, uint8_t* user_stck, void(* entry)())
(uint32_t) entry, //EIP
0x18 | 0x03, //CS
0x202, // EFLAGS
(uint32_t) user_stck+4096, //ESP
(uint32_t) user_stack+4096, //ESP
0x20 | 0x03 //SS
};
struct cpu_state* state = (struct cpu_state*)(stck+4096-sizeof(new_state));
struct cpu_state* state = (struct cpu_state*)(stack+4096-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;
}
curr_task=first_task;
return state;
}
@ -68,14 +80,25 @@ auto Multitasking::task_b() -> void
}
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
{
if(current_task >= 0) {
task_states[current_task] = cpu;
}
current_task++;
current_task%= num_tasks;
cpu=task_states[current_task];
tss[1]=(uint32_t)(cpu+1);
return cpu;
Task* next=curr_task->pause(cpu);
if(next==nullptr)
next=first_task;
curr_task=next;
return next->unpause();
}
Task::Task(struct cpu_state* cpu): cpu_state(cpu), next(nullptr) {};
//This is run every time this task is chosen by the scheduler
auto Task::unpause() -> struct cpu_state* {
return cpu_state;
}
//This is run every time the timer ticks and a task is running
auto Task::pause(struct cpu_state* cpu) -> Task * {
cpu_state=cpu;
return next;
}
auto Task::addTask(Task* task) -> void {
if(next)
return next->addTask(task);
next=task;
}
} // namespace MTGosHAL

View file

@ -8,6 +8,7 @@
#include <Multitasking.hpp>
#include <multiboot.h>
#include <blockdev.hpp>
#include <pmm.hpp>
extern "C" void intr_stub_0(void);
void main();
namespace MTGosHAL {
@ -19,6 +20,7 @@ namespace MTGosHAL {
GDT gdt;
Multitasking tasks;
BlockDevice disk;
PMM mm;
void main(int eax, struct multiboot_info* ebx) {
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
err << BG_color::BLACK << FG_color::RED;
@ -41,6 +43,7 @@ namespace MTGosHAL {
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();
mm.init(ebx);
::main();
sti();
for(;;);

View file

@ -1,9 +1,40 @@
#include <stdint.h>
#include <base.hpp>
#include <pmm.hpp>
#include <multiboot.h>
extern "C" const int kernel_start;
extern "C" const int kernel_end; //those are voids actually
void *operator new(size_t size) {
if(size>4096) {
asm("int $0x1F");
}
void *ptr;
MTGosHAL::mm >> ptr;
return ptr;
}
void *operator new[](size_t size) {
if(size>4096) {
asm("int $0x1F");
}
void *ptr;
MTGosHAL::mm >> ptr;
return ptr;
}
void operator delete(void* p) {
MTGosHAL::mm << p;
}
void operator delete[](void* p) {
MTGosHAL::mm << p;
}
void operator delete(void* p, size_t size) {
MTGosHAL::mm << p;
}
void operator delete[](void* p, size_t size) {
MTGosHAL::mm << p;
}
namespace MTGosHAL {
PMM::PMM(struct multiboot_info * mb_info) {
PMM::PMM() {}
auto PMM::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*) mb_info->mmap_addr;
@ -18,13 +49,14 @@ PMM::PMM(struct multiboot_info * mb_info) {
addr += 0x1000;
}
}
mmap++;
}
mmap++;
unsigned int addr = (unsigned int) &kernel_start;
while(addr < (unsigned int) &kernel_end) {
markUsed((void*)addr);
addr+=0x1000;
}
markUsed(nullptr);
}
auto PMM::markUsed(void * addr) -> void {
unsigned int address=(unsigned int)addr;
@ -40,7 +72,7 @@ auto PMM::operator >> (void * &addr) -> PMM & {
for(int j=0;j<32;j++) {
if(bitmap[i]&(1<<j)) {
//We found a free page!
bitmap[i]&=(1<<j);
bitmap[i]&=~(1<<j);
addr=(void*)(((i<<5)+j)<<12);
return *this;
}

View file

@ -6,6 +6,22 @@
#include <Multitasking.h>
#include <blockdev.hpp>
using namespace MTGosHAL;
void task_a() {
MTGosHAL::out << "a";
}
void task_b() {
MTGosHAL::out << "b";
}
void task_c() {
MTGosHAL::out << "c";
}
void task_d() {
MTGosHAL::out << "d";
}
void main() {
MTGosHAL::out << "Initializing Kernel!\n";
MTGosHAL::tasks.initTask(&task_a);
MTGosHAL::tasks.initTask(&task_b);
MTGosHAL::tasks.initTask(&task_c);
MTGosHAL::tasks.initTask(&task_d);
}