diff --git a/kernel/hal/dummy/c_include/macro.h b/kernel/hal/dummy/c_include/macro.h new file mode 100644 index 0000000..d26c597 --- /dev/null +++ b/kernel/hal/dummy/c_include/macro.h @@ -0,0 +1,2 @@ +#define MIN(a,b) ((a)>(b))?(b):(a) +#define MAX(a,b) ((a)<(b))?(b):(a) diff --git a/kernel/hal/dummy/include/pmm.hpp b/kernel/hal/dummy/include/pmm.hpp index 329836a..99b64d8 100644 --- a/kernel/hal/dummy/include/pmm.hpp +++ b/kernel/hal/dummy/include/pmm.hpp @@ -8,9 +8,9 @@ private: public: auto markUsed(void * addr) -> void; auto init(struct multiboot_info*) -> void; - auto operator >> (void * &addr) -> QDPMM &; //alloc - auto operator << (const void * addr) -> QDPMM &; //free - + auto operator >> (void * &addr) -> PMM &; //alloc + auto operator << (const void * addr) -> PMM &; //free + auto operator () (uint32_t len) -> void*; }; } #endif diff --git a/kernel/hal/x86/c_include/macro.h b/kernel/hal/x86/c_include/macro.h new file mode 100644 index 0000000..d26c597 --- /dev/null +++ b/kernel/hal/x86/c_include/macro.h @@ -0,0 +1,2 @@ +#define MIN(a,b) ((a)>(b))?(b):(a) +#define MAX(a,b) ((a)<(b))?(b):(a) diff --git a/kernel/hal/x86/include/pmm.hpp b/kernel/hal/x86/include/pmm.hpp index d9b61d0..862df9a 100644 --- a/kernel/hal/x86/include/pmm.hpp +++ b/kernel/hal/x86/include/pmm.hpp @@ -1,20 +1,23 @@ #ifndef _PMM_HPP #define _PMM_HPP -#include +#include #include #include namespace MTGosHAL { +struct malloc_t { + uint32_t len; + malloc_t *last; + malloc_t *next; +}; class PMM { private: - uint16_t **pageTable; - QDPMM qdpmm; + malloc_t *head; + PMM2 pmm2; public: - PMM(); - auto markUsed(const void * addr, uint32_t length) -> bool; + 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 + auto alloc(uint32_t length) -> void *; + auto free(void* ptr) -> bool; }; } #endif diff --git a/kernel/hal/x86/include/pmm2.hpp b/kernel/hal/x86/include/pmm2.hpp new file mode 100644 index 0000000..3162828 --- /dev/null +++ b/kernel/hal/x86/include/pmm2.hpp @@ -0,0 +1,20 @@ +#ifndef _PMM2_HPP +#define _PMM2_HPP +#include +#include +#include +namespace MTGosHAL { +class PMM2 { +private: + uint16_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 diff --git a/kernel/hal/x86/include/qdpmm.hpp b/kernel/hal/x86/include/pmm3.hpp similarity index 57% rename from kernel/hal/x86/include/qdpmm.hpp rename to kernel/hal/x86/include/pmm3.hpp index 97c69db..f664993 100644 --- a/kernel/hal/x86/include/qdpmm.hpp +++ b/kernel/hal/x86/include/pmm3.hpp @@ -1,18 +1,18 @@ -#ifndef _QDPMM_HPP -#define _QDPMM_HPP +#ifndef _PMM3_HPP +#define _PMM3_HPP #include #include namespace MTGosHAL { -class QDPMM { +class PMM3 { private: uint32_t bitmap[0x8000]; //Enough for 4 GB protected: public: - QDPMM(); + PMM3(); auto markUsed(const void * addr) -> void; auto init(struct multiboot_info*) -> void; - auto operator >> (void * &addr) -> QDPMM &; //alloc - auto operator << (const void * addr) -> QDPMM &; //free + auto operator >> (void * &addr) -> PMM3 &; //alloc + auto operator << (const void * addr) -> PMM3 &; //free }; } #endif diff --git a/kernel/hal/x86/init/Multitasking.cpp b/kernel/hal/x86/init/Multitasking.cpp index 89d6ed5..52896f5 100644 --- a/kernel/hal/x86/init/Multitasking.cpp +++ b/kernel/hal/x86/init/Multitasking.cpp @@ -27,9 +27,7 @@ Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr) } 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; + uint8_t *stack=(uint8_t*)mm.alloc(4096), *user_stack=(uint8_t*)mm.alloc(4096); struct cpu_state new_state = { 0, //EAX 0, //EBX diff --git a/kernel/hal/x86/init/init.cpp b/kernel/hal/x86/init/init.cpp index 5405728..c0945f7 100644 --- a/kernel/hal/x86/init/init.cpp +++ b/kernel/hal/x86/init/init.cpp @@ -44,11 +44,29 @@ namespace MTGosHAL { 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); - multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr; - void** progs=nullptr; - void* tmp; - mm >> tmp; - progs=(void**)tmp; + debug << "Now tesing the PMM... Allocating 1 byte\n"; + char* tmp=(char*)mm.alloc(1); + debug << "Allocating another byte\n"; + char* tmp2=(char*)mm.alloc(1); + tmp2[0]='A'; + debug << "Freeing the first byte...\n"; + mm.free((void*)tmp); + debug << "Allocating 14 bytes... \n"; + tmp=(char*)mm.alloc(14); + debug << "Changing the last byte... \n"; + tmp[13]='B'; + debug << "Changing if the second byte has changed...\n"; + if(tmp2[0]=='B') { + err << "The allocate function is broken.\n"; + debug << "The allocate function is broken.\n"; + } else { + debug << "The allocate function works!\n"; + } + debug << "Freeing up both pointers."; + mm.free((void*)tmp); + mm.free((void*)tmp2); + multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr; + void** progs=(void**)mm.alloc(4096); 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. progs[i]=(void*)(mods[i].mod_start); diff --git a/kernel/hal/x86/mm/pmm.cpp b/kernel/hal/x86/mm/pmm.cpp index fa9d72a..176ac2b 100644 --- a/kernel/hal/x86/mm/pmm.cpp +++ b/kernel/hal/x86/mm/pmm.cpp @@ -1,125 +1,107 @@ -#include #include -//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 SPLIT2_FLAG 0x007FF000ul -#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) +#include 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; + return MTGosHAL::mm.alloc(size); } void *operator new[](size_t size) { - if(size>4096) { - return MTGosHAL::mm(size/4096); - } - void *ptr; - MTGosHAL::mm >> ptr; - return ptr; + return MTGosHAL::mm.alloc(size); } void operator delete(void* p) { - MTGosHAL::mm << p; + MTGosHAL::mm.free(p); } void operator delete[](void* p) { - MTGosHAL::mm << p; + MTGosHAL::mm.free(p); } void operator delete(void* p, size_t size) { - MTGosHAL::mm << p; + MTGosHAL::mm.free(p); } void operator delete[](void* p, size_t size) { - MTGosHAL::mm << p; + MTGosHAL::mm.free(p); } namespace MTGosHAL { -PMM::PMM(): qdpmm() { -} - -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 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 & { - qdpmm >> addr; - markUsed(addr,4096); - 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 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; -} +PMM::PMM(): head(nullptr), pmm2() {} auto PMM::init(struct multiboot_info* mb_info) -> void { - qdpmm.init(mb_info); - void *temp; - qdpmm >> temp; - pageTable=(uint16_t**)temp; - for(int i=0;i<4096;i++) - pageTable[i]=nullptr; - markUsed(pageTable,4096); - markUsed((void*)nullptr,4096); - 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); - } - mmap++; + pmm2.init(mb_info); +} +auto PMM::alloc(uint32_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. + void *tmp; + pmm2 >> tmp; + head=(malloc_t*)tmp; + } else + head=(malloc_t*)pmm2(((length+sizeof(malloc_t))>>12)+1); + if(!head) //The alloc() didn't work! We're out of RAM! + return nullptr; + head->len=length; + head->next=head->last=nullptr; + malloc_t* tmp=head; + tmp++; + return (void*)tmp; } - 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;imods_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); - } + malloc_t* curr=head; + malloc_t* last=nullptr; + do { + uint32_t loc=(uint32_t)curr+sizeof(malloc_t)+curr->len; + if((loc+length+sizeof(malloc_t))<((loc&(~0xFFF))+4096)) { + malloc_t *allocd=(malloc_t *)loc; + allocd->len=length; + allocd->last=curr; + allocd->next=curr->next; //Set double linked list + curr->next=allocd; + if(allocd->next) + allocd->next->last=allocd; + malloc_t *tmp=allocd; + tmp++; + return (void*)tmp; + } + last=curr; + curr=curr->next; + } while(curr); + malloc_t *allocd=nullptr; + if(length+sizeof(malloc_t)<=4096) { //Small optimization. The routine for allocating more than one continuous page is terribly slow. + void *tmp; + pmm2 >> tmp; + allocd=(malloc_t*)tmp; + } else + allocd=(malloc_t*)pmm2(((length+sizeof(malloc_t))>>12)+1); + if(!allocd) //The alloc() didn't work! We're out of RAM! + return nullptr; + last->next=allocd; + allocd->len=length; + allocd->last=last; + allocd->next=nullptr; + malloc_t *tmp=allocd; + tmp++; + return (void*)tmp; +} +auto PMM::free(void* ptr) -> bool { + if(!ptr) + return false; + malloc_t* curr=head; + malloc_t* chk=(malloc_t*)ptr; + chk--; + do { + if(curr==chk) { + uint32_t start=((uint32_t)chk)&(~0xFFF); + uint32_t end=start+0x1000; + if((((uint32_t)(curr->last)last)>=end))&&(((uint32_t)(curr->next)>=end)||((uint32_t)(curr->next)last) + curr->last->next=curr->next; + else { + head=curr->next; + } + if(curr->next) + curr->next->last=curr->last; + return true; + } + curr=curr->next; + } while(curr); + return false; } } diff --git a/kernel/hal/x86/mm/pmm2.cpp b/kernel/hal/x86/mm/pmm2.cpp new file mode 100644 index 0000000..72decf9 --- /dev/null +++ b/kernel/hal/x86/mm/pmm2.cpp @@ -0,0 +1,98 @@ +#include +#include +//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 SPLIT2_FLAG 0x007FF000ul +#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) +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 { + uint32_t add=(uint32_t)addr; + uint32_t pagetid = SPLIT1_UNSHIFT(add); + if(length > 256*1024*1024) //Maximum allocation limit is 256MB + return false; + if(!pageTable[pagetid]) { + void* temp; + pmm3 >> 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++; + pmm3.markUsed((void*)curr_addr); + } + return true; +} + +auto PMM2::operator >> (void * &addr) -> PMM2 & { + pmm3 >> addr; + markUsed(addr,4096); + return *this; +} +auto PMM2::operator << (const void *addr) -> PMM2 & { + uint32_t add=(uint32_t)addr; + if(!pageTable[SPLIT1_UNSHIFT(add)]) + return *this; //Prevent nullptr derefs + for(int i=0;i 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 PMM2::init(struct multiboot_info* mb_info) -> void { + pmm3.init(mb_info); + void *temp; + pmm3 >> temp; + pageTable=(uint16_t**)temp; + for(int i=0;i<4096;i++) + pageTable[i]=nullptr; + markUsed(pageTable,4096); + markUsed((void*)nullptr,4096); + 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); + } + mmap++; + } + 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;imods_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); + } +} +} diff --git a/kernel/hal/x86/mm/qdmm.cpp b/kernel/hal/x86/mm/pmm3.cpp similarity index 87% rename from kernel/hal/x86/mm/qdmm.cpp rename to kernel/hal/x86/mm/pmm3.cpp index 96cc913..13cd052 100644 --- a/kernel/hal/x86/mm/qdmm.cpp +++ b/kernel/hal/x86/mm/pmm3.cpp @@ -1,12 +1,12 @@ #include #include -#include +#include #include extern "C" const int kernel_start; extern "C" const int kernel_end; //those are voids actually namespace MTGosHAL { -QDPMM::QDPMM() {} -auto QDPMM::init(struct multiboot_info * mb_info) -> void { +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*) mb_info->mmap_addr; @@ -37,14 +37,14 @@ auto QDPMM::init(struct multiboot_info * mb_info) -> void { } } } -auto QDPMM::markUsed(const void * addr) -> void { +auto PMM3::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; } -auto QDPMM::operator >> (void * &addr) -> QDPMM & { +auto PMM3::operator >> (void * &addr) -> PMM3 & { for(int i=0;i<0x8000;i++) { if(!bitmap[i]) continue; @@ -60,7 +60,7 @@ auto QDPMM::operator >> (void * &addr) -> QDPMM & { addr=nullptr; return *this; } -auto QDPMM::operator << (const void * addr) -> QDPMM & { +auto PMM3::operator << (const void * addr) -> PMM3 & { unsigned int address=(unsigned int)addr; address>>=12; int index=address>>5; diff --git a/mtgos.old b/mtgos.old new file mode 100755 index 0000000..4668c9e Binary files /dev/null and b/mtgos.old differ diff --git a/test.elf b/test.elf index d9d6f5e..e8795ec 100755 Binary files a/test.elf and b/test.elf differ diff --git a/user/test.c b/user/test.c index 3f86876..79cf4c1 100644 --- a/user/test.c +++ b/user/test.c @@ -1,6 +1,6 @@ +static unsigned short* videomem = (unsigned short*) 0xb8000; void temp() { - static unsigned short* videomem = (unsigned short*) 0xb8000; int i; for (i = 0; i < 3; i++) { *videomem++ = (0x07 << 8) | ('0' + i);