Finished the PMM. Freezes the kernel (undebugged)
This commit is contained in:
parent
dc6b62e64e
commit
c6d89476cb
8 changed files with 123 additions and 71 deletions
|
@ -6,13 +6,10 @@ class PMM {
|
|||
private:
|
||||
uint32_t bitmap[0x8000]; //Enough for 4 GB
|
||||
public:
|
||||
template <typename T>
|
||||
auto markUsed(T * addr) -> void;
|
||||
auto markUsed(void * addr) -> void;
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
template <typename T>
|
||||
auto operator >> (T * &addr) -> QDPMM &; //alloc
|
||||
template <typename T>
|
||||
auto operator << (const T * addr) -> QDPMM &; //free
|
||||
auto operator >> (void * &addr) -> QDPMM &; //alloc
|
||||
auto operator << (const void * addr) -> QDPMM &; //free
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace MTGosHAL {
|
|||
class Multitasking;
|
||||
class BlockDevice;
|
||||
class Task;
|
||||
class QDPMM;
|
||||
class PMM;
|
||||
enum class BG_color: uint16_t;
|
||||
enum class FG_color: uint16_t;
|
||||
extern Serial debug;
|
||||
|
@ -23,6 +23,6 @@ namespace MTGosHAL {
|
|||
extern IDT idt;
|
||||
extern Multitasking tasks;
|
||||
extern BlockDevice disk;
|
||||
extern QDPMM qdmm;
|
||||
extern PMM mm;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,16 +8,13 @@ class PMM {
|
|||
private:
|
||||
uint16_t **pageTable;
|
||||
QDPMM qdpmm;
|
||||
auto markUsed(void * addr) -> void;
|
||||
public:
|
||||
PMM();
|
||||
template <typename T>
|
||||
auto markUsed(T * addr, uint32_t length) -> void;
|
||||
auto markUsed(const void * addr, uint32_t length) -> bool;
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
template <typename T>
|
||||
auto operator >> (T * &addr) -> QDPMM &; //alloc
|
||||
template <typename T>
|
||||
auto operator << (const T * addr) -> QDPMM &; //free
|
||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
||||
auto operator << (const void * addr) -> PMM &; //free
|
||||
auto operator()(int pages) -> void*; //alloc_multipage
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,13 +9,10 @@ private:
|
|||
protected:
|
||||
public:
|
||||
QDPMM();
|
||||
template <typename T>
|
||||
auto markUsed(T * addr) -> void;
|
||||
auto markUsed(const void * addr) -> void;
|
||||
auto init(struct multiboot_info*) -> void;
|
||||
template <typename T>
|
||||
auto operator >> (T * &addr) -> QDPMM &; //alloc
|
||||
template <typename T>
|
||||
auto operator << (const T * addr) -> QDPMM &; //free
|
||||
auto operator >> (void * &addr) -> QDPMM &; //alloc
|
||||
auto operator << (const void * addr) -> QDPMM &; //free
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <Multitasking.hpp>
|
||||
#include <serial.hpp>
|
||||
#include <blockdev.hpp>
|
||||
#include <qdpmm.hpp>
|
||||
#include <pmm.hpp>
|
||||
auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return MTGosHAL::tasks.schedule(cpu);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
|
|||
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
||||
{
|
||||
void *tmp1, *tmp2;
|
||||
qdmm >> tmp1 >> tmp2;
|
||||
mm >> tmp1 >> tmp2;
|
||||
uint8_t *stack=(uint8_t*)tmp1, *user_stack=(uint8_t*)tmp2;
|
||||
struct cpu_state new_state = {
|
||||
0, //EAX
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <Multitasking.hpp>
|
||||
#include <multiboot.h>
|
||||
#include <blockdev.hpp>
|
||||
#include <qdpmm.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" void intr_stub_0(void);
|
||||
void main(void ** programs);
|
||||
namespace MTGosHAL {
|
||||
|
@ -20,7 +20,7 @@ namespace MTGosHAL {
|
|||
GDT gdt;
|
||||
Multitasking tasks;
|
||||
BlockDevice disk;
|
||||
QDPMM qdmm;
|
||||
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;
|
||||
|
@ -43,11 +43,11 @@ 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();
|
||||
qdmm.init(ebx);
|
||||
mm.init(ebx);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
||||
void** progs=nullptr;
|
||||
void* tmp;
|
||||
qdmm >> tmp;
|
||||
mm >> tmp;
|
||||
progs=(void**)tmp;
|
||||
uint32_t i;
|
||||
for(i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
|
||||
|
|
|
@ -1,43 +1,135 @@
|
|||
#include <pmm.hpp>
|
||||
#include <base.hpp>
|
||||
//In this part, please remember that the address is split into 3 parts. Bitmap:
|
||||
// AAAA AAAA ABBB BBBB BBBB CCCC CCCC CCCC
|
||||
#define SPLIT1_FLAG 0xFF800000ul
|
||||
#define SPLIT1_SHIFT(a) (a)<<23
|
||||
#define SPLIT1_UNSHIFT(a) (a)>>23
|
||||
#define SPLIT1_SHIFT(a) ((a)<<23)
|
||||
#define SPLIT1_UNSHIFT(a) ((a)>>23)
|
||||
#define SPLIT2_FLAG 0x007FF000ul
|
||||
#define SPLIT2_SHIFT(a) (a)<<12
|
||||
#define SPLIT2_UNSHIFT(a) ((a)<<23)&0x7FF
|
||||
#define SPLIT2_SHIFT(a) ((a)<<12)
|
||||
#define SPLIT2_UNSHIFT(a) (((a)<<23)&0x7FF)
|
||||
#define SPLIT3_FLAG 0x00000FFFul
|
||||
#define SPLIT3_SHIFT(a) (a)
|
||||
#define SPLIT3_UNSHIFT(a) (a)&0xFFF
|
||||
#define SPLIT3_SHIFT(a) ((a))
|
||||
#define SPLIT3_UNSHIFT(a) ((a)&0xFFF)
|
||||
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) {
|
||||
return MTGosHAL::mm(size/4096);
|
||||
}
|
||||
void *ptr;
|
||||
MTGosHAL::mm >> ptr;
|
||||
return ptr;
|
||||
}
|
||||
void *operator new[](size_t size) {
|
||||
if(size>4096) {
|
||||
return MTGosHAL::mm(size/4096);
|
||||
}
|
||||
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(): qdpmm() {
|
||||
}
|
||||
template <typename T>
|
||||
auto PMM::markUsed(T * addr, uint32_t length) -> void {
|
||||
|
||||
auto PMM::markUsed(const void * addr, uint32_t length) -> bool {
|
||||
uint32_t add=(uint32_t)addr;
|
||||
uint32_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
|
||||
return;
|
||||
return false;
|
||||
if(!pageTable[pagetid]) {
|
||||
void* temp;
|
||||
qdpmm >> temp;
|
||||
pageTable[pagetid]=(uint16_t*)temp;
|
||||
for(int i=0;i<2048;i++)
|
||||
pageTable[pagetid][i]=0;
|
||||
markUsed(pageTable[pagetid],1024); //Not a mistake
|
||||
}
|
||||
//Check if used
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint16_t counter=1;
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)]=counter++;
|
||||
qdpmm.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto PMM::operator >> (void * &addr) -> PMM & {
|
||||
for(int i=0;i<512;i++) {
|
||||
if(!pageTable[i]) {
|
||||
markUsed((void*)(SPLIT1_SHIFT(i)),4096);
|
||||
addr=(void*)(SPLIT1_SHIFT(i));
|
||||
return *this;
|
||||
}
|
||||
for(int j=0;j<2048;j++) {
|
||||
if(!pageTable[i][j])
|
||||
markUsed((void*)(SPLIT1_SHIFT(i)+SPLIT2_SHIFT(j)),4096);
|
||||
addr=(void*)(SPLIT1_SHIFT(i)+SPLIT2_SHIFT(j));
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
auto PMM::operator << (const void *addr) -> PMM & {
|
||||
uint32_t add=(uint32_t)addr;
|
||||
if(!pageTable[SPLIT1_UNSHIFT(add)])
|
||||
return *this; //Prevent nullptr derefs
|
||||
for(int i=0;i<pageTable[SPLIT1_UNSHIFT(add)][SPLIT2_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*4096)][SPLIT2_UNSHIFT(add+i*4096)]=0;
|
||||
qdpmm << (void*)(add+i*4096);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
auto PMM::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(uint32_t i=0;i<(uint32_t)(-(pages*4096));i+=4096) {
|
||||
if(markUsed((void*)i,pages*4096))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
auto PMM::init(struct multiboot_info* mb_info) -> void {
|
||||
qdpmm.init(mb_info);
|
||||
void *temp;
|
||||
qdpmm >> temp;
|
||||
pageTable=(uint16_t**)temp;
|
||||
markUsed(pageTable,1024);
|
||||
markUsed(pageTable,4096);
|
||||
markUsed((void*)nullptr,4096);
|
||||
for(int i=0;i<4096;i++)
|
||||
pageTable[i]=nullptr;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
}
|
||||
}
|
||||
markUsed(&kernel_start,((uint32_t)&kernel_end)-((uint32_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)mods[i].mod_start,mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,34 +4,6 @@
|
|||
#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::qdmm >> ptr;
|
||||
return ptr;
|
||||
}
|
||||
void *operator new[](size_t size) {
|
||||
if(size>4096) {
|
||||
asm("int $0x1F");
|
||||
}
|
||||
void *ptr;
|
||||
MTGosHAL::qdmm >> ptr;
|
||||
return ptr;
|
||||
}
|
||||
void operator delete(void* p) {
|
||||
MTGosHAL::qdmm << p;
|
||||
}
|
||||
void operator delete[](void* p) {
|
||||
MTGosHAL::qdmm << p;
|
||||
}
|
||||
void operator delete(void* p, size_t size) {
|
||||
MTGosHAL::qdmm << p;
|
||||
}
|
||||
void operator delete[](void* p, size_t size) {
|
||||
MTGosHAL::qdmm << p;
|
||||
}
|
||||
namespace MTGosHAL {
|
||||
QDPMM::QDPMM() {}
|
||||
auto QDPMM::init(struct multiboot_info * mb_info) -> void {
|
||||
|
@ -65,16 +37,14 @@ auto QDPMM::init(struct multiboot_info * mb_info) -> void {
|
|||
}
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
auto QDPMM::markUsed(T * addr) -> void {
|
||||
auto QDPMM::markUsed(const void * addr) -> void {
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
}
|
||||
template <typename T>
|
||||
auto QDPMM::operator >> (T * &addr) -> QDPMM & {
|
||||
auto QDPMM::operator >> (void * &addr) -> QDPMM & {
|
||||
for(int i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
|
@ -90,8 +60,7 @@ auto QDPMM::operator >> (T * &addr) -> QDPMM & {
|
|||
addr=nullptr;
|
||||
return *this;
|
||||
}
|
||||
template <typename T>
|
||||
auto QDPMM::operator << (const T * addr) -> QDPMM & {
|
||||
auto QDPMM::operator << (const void * addr) -> QDPMM & {
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
|
|
Loading…
Reference in a new issue