Renamed the PMM to QDPMM (quick & dirty physical memory manager)
Added skeleton of the new PMM, which uses QDPMM
This commit is contained in:
parent
bc7c6f835e
commit
dc6b62e64e
12 changed files with 228 additions and 126 deletions
|
@ -14,7 +14,7 @@ function buildscript() {
|
||||||
echo "[$(date +%c)] Building gcc for $1." | tee -a buildlog
|
echo "[$(date +%c)] Building gcc for $1." | tee -a buildlog
|
||||||
mkdir build-gcc
|
mkdir build-gcc
|
||||||
cd build-gcc
|
cd build-gcc
|
||||||
../gcc-5.3.0/configure --prefix=$CROSSPATH --target=$1 --disable-nls --enable-languages=c,c++ --without-headers 2>&1 > /dev/null
|
../gcc-6.1.0/configure --prefix=$CROSSPATH --target=$1 --disable-nls --enable-languages=c,c++ --without-headers 2>&1 > /dev/null
|
||||||
make all-gcc -j8 2>&1 > /dev/null
|
make all-gcc -j8 2>&1 > /dev/null
|
||||||
make all-target-libgcc -j8 2>&1 > /dev/null
|
make all-target-libgcc -j8 2>&1 > /dev/null
|
||||||
make install-gcc 2>&1 > /dev/null
|
make install-gcc 2>&1 > /dev/null
|
||||||
|
@ -27,17 +27,21 @@ tempdir=$(mktemp -d)
|
||||||
cd $tempdir
|
cd $tempdir
|
||||||
echo "Temponary files are in $tempdir. Build log can be found under $tempdir/buildlog" | tee -a buildlog
|
echo "Temponary files are in $tempdir. Build log can be found under $tempdir/buildlog" | tee -a buildlog
|
||||||
echo "Downloading GCC, Binutils, MPC, MPFR and GMP" | tee -a buildlog
|
echo "Downloading GCC, Binutils, MPC, MPFR and GMP" | tee -a buildlog
|
||||||
wget ftp://ftp.gnu.org/gnu/gcc/gcc-5.3.0/gcc-5.3.0.tar.bz2 ftp://ftp.gnu.org/gnu/binutils/binutils-2.26.tar.bz2 ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.xz ftp://ftp.gnu.org/gnu/gmp/gmp-6.1.0.tar.xz
|
wget ftp://ftp.gnu.org/gnu/gcc/gcc-6.1.0/gcc-6.1.0.tar.bz2 ftp://ftp.gnu.org/gnu/binutils/binutils-2.26.tar.bz2 ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.xz ftp://ftp.gnu.org/gnu/gmp/gmp-6.1.0.tar.xz http://isl.gforge.inria.fr/isl-0.16.tar.xz http://www.bastoul.net/cloog/pages/download/cloog-0.18.4.tar.gz
|
||||||
echo "Untaring..." 2>&1 | tee -a buildlog
|
echo "Untaring..." 2>&1 | tee -a buildlog
|
||||||
tar -xf gcc-5.3.0.tar.bz2
|
tar -xf gcc-6.1.0.tar.bz2
|
||||||
tar -xf binutils-2.26.tar.bz2
|
tar -xf binutils-2.26.tar.bz2
|
||||||
cd gcc-5.3.0
|
cd gcc-6.1.0
|
||||||
tar -xf ../mpc-1.0.3.tar.gz
|
tar -xf ../mpc-1.0.3.tar.gz
|
||||||
mv mpc-1.0.3 mpc
|
mv mpc-1.0.3 mpc
|
||||||
tar -xf ../mpfr-3.1.3.tar.xz
|
tar -xf ../mpfr-3.1.3.tar.xz
|
||||||
mv mpfr-3.1.3 mpfr
|
mv mpfr-3.1.3 mpfr
|
||||||
tar -xf ../gmp-6.1.0.tar.xz
|
tar -xf ../gmp-6.1.0.tar.xz
|
||||||
mv gmp-6.1.0 gmp
|
mv gmp-6.1.0 gmp
|
||||||
|
tar -xf ../isl-0.16.tar.xz
|
||||||
|
mv isl-0.16 isl
|
||||||
|
tar -xf ../cloog-0.18.4.tar.gz
|
||||||
|
mv cloog-0.18.4 cloog
|
||||||
cd ..
|
cd ..
|
||||||
echo "Preperation done. Beginning the compilation now." 2>&1 | tee -a buildlog
|
echo "Preperation done. Beginning the compilation now." 2>&1 | tee -a buildlog
|
||||||
buildscript i686-elf #x86 port
|
buildscript i686-elf #x86 port
|
||||||
|
|
|
@ -5,12 +5,14 @@ namespace MTGosHAL {
|
||||||
class PMM {
|
class PMM {
|
||||||
private:
|
private:
|
||||||
uint32_t bitmap[0x8000]; //Enough for 4 GB
|
uint32_t bitmap[0x8000]; //Enough for 4 GB
|
||||||
auto markUsed(void * addr) -> void;
|
|
||||||
public:
|
public:
|
||||||
PMM();
|
template <typename T>
|
||||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
auto markUsed(T * addr) -> void;
|
||||||
auto operator << (const void * addr) -> PMM &; //free
|
auto init(struct multiboot_info*) -> void;
|
||||||
auto operator()(int pages) -> void*; //alloc_multipage
|
template <typename T>
|
||||||
|
auto operator >> (T * &addr) -> QDPMM &; //alloc
|
||||||
|
template <typename T>
|
||||||
|
auto operator << (const T * addr) -> QDPMM &; //free
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace MTGosHAL {
|
||||||
class Multitasking;
|
class Multitasking;
|
||||||
class BlockDevice;
|
class BlockDevice;
|
||||||
class Task;
|
class Task;
|
||||||
class PMM;
|
class QDPMM;
|
||||||
enum class BG_color: uint16_t;
|
enum class BG_color: uint16_t;
|
||||||
enum class FG_color: uint16_t;
|
enum class FG_color: uint16_t;
|
||||||
extern Serial debug;
|
extern Serial debug;
|
||||||
|
@ -23,6 +23,6 @@ namespace MTGosHAL {
|
||||||
extern IDT idt;
|
extern IDT idt;
|
||||||
extern Multitasking tasks;
|
extern Multitasking tasks;
|
||||||
extern BlockDevice disk;
|
extern BlockDevice disk;
|
||||||
extern PMM mm;
|
extern QDPMM qdmm;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
#ifndef _PMM_HPP
|
#ifndef _PMM_HPP
|
||||||
#define _PMM_HPP
|
#define _PMM_HPP
|
||||||
|
#include <qdpmm.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
namespace MTGosHAL {
|
namespace MTGosHAL {
|
||||||
class PMM {
|
class PMM {
|
||||||
private:
|
private:
|
||||||
uint32_t bitmap[0x8000]; //Enough for 4 GB
|
uint16_t **pageTable;
|
||||||
|
QDPMM qdpmm;
|
||||||
auto markUsed(void * addr) -> void;
|
auto markUsed(void * addr) -> void;
|
||||||
public:
|
public:
|
||||||
PMM();
|
PMM();
|
||||||
auto init(struct multiboot_info*) -> void;
|
template <typename T>
|
||||||
auto operator >> (void * &addr) -> PMM &; //alloc
|
auto markUsed(T * addr, uint32_t length) -> void;
|
||||||
auto operator << (const void * addr) -> PMM &; //free
|
auto init(struct multiboot_info*) -> void;
|
||||||
auto operator()(int pages) -> void*; //alloc_multipage
|
template <typename T>
|
||||||
|
auto operator >> (T * &addr) -> QDPMM &; //alloc
|
||||||
|
template <typename T>
|
||||||
|
auto operator << (const T * addr) -> QDPMM &; //free
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
21
kernel/hal/x86/include/qdpmm.hpp
Normal file
21
kernel/hal/x86/include/qdpmm.hpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef _QDPMM_HPP
|
||||||
|
#define _QDPMM_HPP
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
namespace MTGosHAL {
|
||||||
|
class QDPMM {
|
||||||
|
private:
|
||||||
|
uint32_t bitmap[0x8000]; //Enough for 4 GB
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
QDPMM();
|
||||||
|
template <typename T>
|
||||||
|
auto markUsed(T * 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -3,7 +3,7 @@
|
||||||
#include <Multitasking.hpp>
|
#include <Multitasking.hpp>
|
||||||
#include <serial.hpp>
|
#include <serial.hpp>
|
||||||
#include <blockdev.hpp>
|
#include <blockdev.hpp>
|
||||||
#include <pmm.hpp>
|
#include <qdpmm.hpp>
|
||||||
auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
||||||
return MTGosHAL::tasks.schedule(cpu);
|
return MTGosHAL::tasks.schedule(cpu);
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
|
||||||
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
|
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
|
||||||
if(!idt.request(0x20,::schedule)) {
|
if(!idt.request(0x20,::schedule)) {
|
||||||
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
|
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
|
||||||
while(true);
|
while(true)
|
||||||
asm volatile("cli; hlt");
|
asm volatile("cli; hlt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
||||||
{
|
{
|
||||||
void *tmp1, *tmp2;
|
void *tmp1, *tmp2;
|
||||||
mm >> tmp1 >> tmp2;
|
qdmm >> tmp1 >> tmp2;
|
||||||
uint8_t *stack=(uint8_t*)tmp1, *user_stack=(uint8_t*)tmp2;
|
uint8_t *stack=(uint8_t*)tmp1, *user_stack=(uint8_t*)tmp2;
|
||||||
struct cpu_state new_state = {
|
struct cpu_state new_state = {
|
||||||
0, //EAX
|
0, //EAX
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <Multitasking.hpp>
|
#include <Multitasking.hpp>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
#include <blockdev.hpp>
|
#include <blockdev.hpp>
|
||||||
#include <pmm.hpp>
|
#include <qdpmm.hpp>
|
||||||
extern "C" void intr_stub_0(void);
|
extern "C" void intr_stub_0(void);
|
||||||
void main(void ** programs);
|
void main(void ** programs);
|
||||||
namespace MTGosHAL {
|
namespace MTGosHAL {
|
||||||
|
@ -20,7 +20,7 @@ namespace MTGosHAL {
|
||||||
GDT gdt;
|
GDT gdt;
|
||||||
Multitasking tasks;
|
Multitasking tasks;
|
||||||
BlockDevice disk;
|
BlockDevice disk;
|
||||||
PMM mm;
|
QDPMM qdmm;
|
||||||
void main(int eax, struct multiboot_info* ebx) {
|
void main(int eax, struct multiboot_info* ebx) {
|
||||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||||
err << BG_color::BLACK << FG_color::RED;
|
err << BG_color::BLACK << FG_color::RED;
|
||||||
|
@ -43,16 +43,18 @@ 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(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.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();
|
idt.apply();
|
||||||
mm.init(ebx);
|
qdmm.init(ebx);
|
||||||
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
||||||
void** progs=nullptr;
|
void** progs=nullptr;
|
||||||
void* tmp;
|
void* tmp;
|
||||||
mm >> tmp;
|
qdmm >> tmp;
|
||||||
progs=(void**)tmp;
|
progs=(void**)tmp;
|
||||||
uint32_t i;
|
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.
|
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);
|
progs[i]=(void*)(mods[i].mod_start);
|
||||||
|
debug << "Found module!\n";
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
progs[i]=nullptr;
|
progs[i]=nullptr;
|
||||||
::main(progs);
|
::main(progs);
|
||||||
sti();
|
sti();
|
||||||
|
|
|
@ -1,99 +1,43 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <base.hpp>
|
|
||||||
#include <pmm.hpp>
|
#include <pmm.hpp>
|
||||||
#include <multiboot.h>
|
//In this part, please remember that the address is split into 3 parts. Bitmap:
|
||||||
extern "C" const int kernel_start;
|
// AAAA AAAA ABBB BBBB BBBB CCCC CCCC CCCC
|
||||||
extern "C" const int kernel_end; //those are voids actually
|
#define SPLIT1_FLAG 0xFF800000ul
|
||||||
void *operator new(size_t size) {
|
#define SPLIT1_SHIFT(a) (a)<<23
|
||||||
if(size>4096) {
|
#define SPLIT1_UNSHIFT(a) (a)>>23
|
||||||
asm("int $0x1F");
|
#define SPLIT2_FLAG 0x007FF000ul
|
||||||
}
|
#define SPLIT2_SHIFT(a) (a)<<12
|
||||||
void *ptr;
|
#define SPLIT2_UNSHIFT(a) ((a)<<23)&0x7FF
|
||||||
MTGosHAL::mm >> ptr;
|
#define SPLIT3_FLAG 0x00000FFFul
|
||||||
return ptr;
|
#define SPLIT3_SHIFT(a) (a)
|
||||||
}
|
#define SPLIT3_UNSHIFT(a) (a)&0xFFF
|
||||||
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 {
|
namespace MTGosHAL {
|
||||||
PMM::PMM() {}
|
PMM::PMM(): qdpmm() {
|
||||||
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;
|
|
||||||
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) {
|
|
||||||
// Memory is free
|
|
||||||
uintptr_t addr = mmap->addr;
|
|
||||||
uintptr_t end_addr = addr + mmap->len;
|
|
||||||
while (addr < end_addr) {
|
|
||||||
*this << (void*) addr;
|
|
||||||
addr += 0x1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mmap++;
|
|
||||||
}
|
|
||||||
unsigned int addr = (unsigned int) &kernel_start;
|
|
||||||
while(addr < (unsigned int) &kernel_end) {
|
|
||||||
markUsed((void*)addr);
|
|
||||||
addr+=0x1000;
|
|
||||||
}
|
|
||||||
markUsed(nullptr);
|
|
||||||
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))); //Mark all of the module table as used
|
|
||||||
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
|
|
||||||
markUsed((void*)start); //Protect all multiboot modules
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auto PMM::markUsed(void * addr) -> void {
|
template <typename T>
|
||||||
unsigned int address=(unsigned int)addr;
|
auto PMM::markUsed(T * addr, uint32_t length) -> void {
|
||||||
address>>=12;
|
uint32_t add=(uint32_t)addr;
|
||||||
int index=address>>5;
|
uint32_t pagetid = SPLIT1_UNSHIFT(add);
|
||||||
int bit=1<<(address&0x1F);
|
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
|
||||||
bitmap[index]&=~bit;
|
return;
|
||||||
|
if(!pageTable[pagetid]) {
|
||||||
|
void* temp;
|
||||||
|
qdpmm >> temp;
|
||||||
|
pageTable[pagetid]=(uint16_t*)temp;
|
||||||
|
markUsed(pageTable[pagetid],1024); //Not a mistake
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto PMM::operator >> (void * &addr) -> PMM & {
|
auto PMM::init(struct multiboot_info* mb_info) -> void {
|
||||||
for(int i=0;i<0x8000;i++) {
|
qdpmm.init(mb_info);
|
||||||
if(!bitmap[i])
|
void *temp;
|
||||||
continue;
|
qdpmm >> temp;
|
||||||
for(int j=0;j<32;j++) {
|
pageTable=(uint16_t**)temp;
|
||||||
if(bitmap[i]&(1<<j)) {
|
markUsed(pageTable,1024);
|
||||||
//We found a free page!
|
for(int i=0;i<4096;i++)
|
||||||
bitmap[i]&=~(1<<j);
|
pageTable[i]=nullptr;
|
||||||
addr=(void*)(((i<<5)+j)<<12);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addr=nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
auto PMM::operator << (const void * addr) -> PMM & {
|
|
||||||
unsigned int address=(unsigned int)addr;
|
|
||||||
address>>=12;
|
|
||||||
int index=address>>5;
|
|
||||||
int bit=1<<(address&0x1F);
|
|
||||||
bitmap[index]|=bit;
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
102
kernel/hal/x86/mm/qdmm.cpp
Normal file
102
kernel/hal/x86/mm/qdmm.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <base.hpp>
|
||||||
|
#include <qdpmm.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::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 {
|
||||||
|
for(int i=0;i<0x8000;i++)
|
||||||
|
bitmap[i]=0;
|
||||||
|
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) {
|
||||||
|
// Memory is free
|
||||||
|
uintptr_t addr = mmap->addr;
|
||||||
|
uintptr_t end_addr = addr + mmap->len;
|
||||||
|
while (addr < end_addr) {
|
||||||
|
*this << (void*) addr;
|
||||||
|
addr += 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mmap++;
|
||||||
|
}
|
||||||
|
unsigned int addr = (unsigned int) &kernel_start;
|
||||||
|
while(addr < (unsigned int) &kernel_end) {
|
||||||
|
markUsed((void*)addr);
|
||||||
|
addr+=0x1000;
|
||||||
|
}
|
||||||
|
markUsed((void*)0);
|
||||||
|
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))); //Mark all of the module table as used
|
||||||
|
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
|
||||||
|
markUsed((void*)start); //Protect all multiboot modules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto QDPMM::markUsed(T * 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 & {
|
||||||
|
for(int i=0;i<0x8000;i++) {
|
||||||
|
if(!bitmap[i])
|
||||||
|
continue;
|
||||||
|
for(int j=0;j<32;j++) {
|
||||||
|
if(bitmap[i]&(1<<j)) {
|
||||||
|
//We found a free page!
|
||||||
|
bitmap[i]&=~(1<<j);
|
||||||
|
addr=(void*)(((i<<5)+j)<<12);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addr=nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto QDPMM::operator << (const T * addr) -> QDPMM & {
|
||||||
|
unsigned int address=(unsigned int)addr;
|
||||||
|
address>>=12;
|
||||||
|
int index=address>>5;
|
||||||
|
int bit=1<<(address&0x1F);
|
||||||
|
bitmap[index]|=bit;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,35 @@
|
||||||
#include <elf.hpp>
|
#include <elf.hpp>
|
||||||
|
#include <base.hpp>
|
||||||
|
#include <serial.hpp>
|
||||||
|
#include <output.hpp>
|
||||||
|
using namespace MTGosHAL;
|
||||||
auto load(Elf32_Ehdr* file) -> void* {
|
auto load(Elf32_Ehdr* file) -> void* {
|
||||||
if((file->e_ident[0]!=ELFMAG0)||
|
if((file->e_ident[0]!=ELFMAG0)||
|
||||||
(file->e_ident[1]!=ELFMAG1)||
|
(file->e_ident[1]!=ELFMAG1)||
|
||||||
(file->e_ident[2]!=ELFMAG2)||
|
(file->e_ident[2]!=ELFMAG2)||
|
||||||
(file->e_ident[3]!=ELFMAG3) )
|
(file->e_ident[3]!=ELFMAG3) ) {
|
||||||
return nullptr;
|
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*)((uint32_t)(file->e_phoff)+(uint32_t)file);
|
||||||
|
debug << "entry=";
|
||||||
|
debug << Base::HEXADECIMAL;
|
||||||
|
debug << (int)file->e_entry;
|
||||||
for(int i=0;i<file->e_phnum;i++) {
|
for(int i=0;i<file->e_phnum;i++) {
|
||||||
uint32_t start=phdr[i].p_vaddr;
|
uint32_t start=phdr[i].p_vaddr;
|
||||||
|
debug << "start=";
|
||||||
|
debug << Base::HEXADECIMAL;
|
||||||
|
debug << (int)start;
|
||||||
uint32_t end=start+phdr[i].p_memsz;
|
uint32_t end=start+phdr[i].p_memsz;
|
||||||
if((start < file->e_entry) && (file->e_entry < end))
|
debug << "end=";
|
||||||
|
debug << Base::HEXADECIMAL;
|
||||||
|
debug << (int)end;
|
||||||
|
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
|
return (void*) (file->e_entry-start+phdr[i].p_offset+(uint32_t)file); //Calculate _start address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
BIN
test.elf
BIN
test.elf
Binary file not shown.
16
user/test.c
16
user/test.c
|
@ -1,11 +1,15 @@
|
||||||
unsigned short* videomem = (unsigned short*) 0xb8000;
|
|
||||||
|
|
||||||
void _start(void)
|
void temp() {
|
||||||
{
|
static unsigned short* videomem = (unsigned short*) 0xb8000;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
*videomem++ = (0x07 << 8) | ('0' + i);
|
*videomem++ = (0x07 << 8) | ('0' + i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while(1);
|
void _start(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<100;i++)
|
||||||
|
temp();
|
||||||
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue