PMM should work now
This commit is contained in:
parent
fe979e8774
commit
9a3a11d78c
12 changed files with 163 additions and 48 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
17
kernel/hal/dummy/include/pmm.hpp
Normal file
17
kernel/hal/dummy/include/pmm.hpp
Normal 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
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(;;);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue