CTAOS v4
This commit is contained in:
@ -16,13 +16,20 @@ goto build
|
||||
:build
|
||||
@echo Building Memory Manager...
|
||||
|
||||
del %objpath%\mmngr_cr.o
|
||||
del %objpath%\mmngr.o
|
||||
del %objpath%\mmngr_ph.o
|
||||
|
||||
@echo * Compiling Physical Memory Manager...
|
||||
%nasm_path%\nasm.exe -f aout -o %objpath%/mmngr_cr.o mmngr_cr.asm
|
||||
%nasm_path%\nasm.exe -f aout -o %objpath%/mmngr.o mmngr.asm
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_ph.o mmngr_ph.c
|
||||
|
||||
|
||||
@echo * Compiling Virtual Memory Manager...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_vi.o mmngr_vi.c
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_de.o lib/pde.c
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/mmngr_te.o lib/pte.c
|
||||
:check
|
||||
if not exist %objpath%\mmngr_cr.o goto error
|
||||
if not exist %objpath%\mmngr_vi.o goto error
|
||||
if not exist %objpath%\mmngr_de.o goto error
|
||||
if not exist %objpath%\mmngr_te.o goto error
|
||||
if not exist %objpath%\mmngr.o goto error
|
||||
if not exist %objpath%\mmngr_ph.o goto error
|
||||
|
36
SysCore/memory/lib/pde.c
Normal file
36
SysCore/memory/lib/pde.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "pde.h"
|
||||
|
||||
void pd_entry_add_attrib (pd_entry* entry, unsigned mask) {
|
||||
*entry |= mask;
|
||||
}
|
||||
|
||||
void pd_entry_del_attrib (pd_entry* entry, unsigned mask) {
|
||||
*entry &= ~mask;
|
||||
}
|
||||
|
||||
void pd_entry_set_frame (pd_entry* entry, unsigned address) {
|
||||
*entry = (*entry & ~_I86_PDE_FRAME) | address;
|
||||
}
|
||||
|
||||
unsigned pd_entry_get_frame (pd_entry entry) {
|
||||
return entry&_I86_PDE_FRAME;
|
||||
}
|
||||
|
||||
unsigned char pd_entry_is_present (pd_entry entry) {
|
||||
return (entry & _I86_PDE_PRESENT);
|
||||
}
|
||||
|
||||
unsigned char pd_entry_is_user (pd_entry entry) {
|
||||
return (entry & _I86_PDE_USER);
|
||||
}
|
||||
|
||||
unsigned char pd_entry_is_4mb (pd_entry entry) {
|
||||
return (entry & _I86_PDE_4MB);
|
||||
}
|
||||
|
||||
unsigned char pd_entry_is_writable (pd_entry entry) {
|
||||
return (entry & _I86_PDE_WRITABLE);
|
||||
}
|
||||
|
||||
void pd_entry_enable_global (pd_entry entry) {
|
||||
}
|
30
SysCore/memory/lib/pde.h
Normal file
30
SysCore/memory/lib/pde.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef __PAGE_DIRECTORY_ENTRY_
|
||||
#define __PAGE_DIRECTORY_ENTRY_
|
||||
|
||||
enum __PAGE_PDE_FLAGS {
|
||||
_I86_PDE_PRESENT = 1,
|
||||
_I86_PDE_WRITABLE = 2,
|
||||
_I86_PDE_USER = 4,
|
||||
_I86_PDE_PWT = 8,
|
||||
_I86_PDE_PCD = 0x10,
|
||||
_I86_PDE_ACCESSED = 0x20,
|
||||
_I86_PDE_DIRTY = 0x40,
|
||||
_I86_PDE_4MB = 0x80,
|
||||
_I86_PDE_CPU_GLOBAL = 0x100,
|
||||
_I86_PDE_LV4_GLOBAL = 0x200,
|
||||
_I86_PDE_FRAME = 0x7FFFF000
|
||||
};
|
||||
|
||||
typedef unsigned pd_entry;
|
||||
|
||||
extern void pd_entry_add_attrib (pd_entry* entry, unsigned mask);
|
||||
extern void pd_entry_del_attrib (pd_entry* entry, unsigned mask);
|
||||
extern void pd_entry_set_frame (pd_entry* entry, unsigned address);
|
||||
extern unsigned pd_entry_get_frame (pd_entry entry);
|
||||
|
||||
extern unsigned char pd_entry_is_present (pd_entry entry);
|
||||
extern unsigned char pd_entry_is_user (pd_entry entry);
|
||||
extern unsigned char pd_entry_is_4mb (pd_entry entry);
|
||||
extern unsigned char pd_entry_is_writable (pd_entry entry);
|
||||
extern void pd_entry_enable_global (pd_entry entry);
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
#include <pte.h>
|
||||
#include "pte.h"
|
||||
|
||||
void pt_entry_add_attrib (pt_entry* entry, unsigned mask) {
|
||||
*entry |= mask;
|
||||
@ -9,18 +9,17 @@ void pt_entry_add_attrib (pt_entry* entry, unsigned mask) {
|
||||
}
|
||||
|
||||
void pt_entry_set_frame (pt_entry* entry, unsigned address) {
|
||||
*entry &= ~_I86_PTE_FRAME;
|
||||
*entry |= address & _I86_PTE_FRAME;
|
||||
*entry = (*entry & ~_I86_PTE_FRAME) | address;
|
||||
}
|
||||
|
||||
unsigned pt_entry_get_frame (pt_entry entry) {
|
||||
return entry&_I86_PTE_FRAME;
|
||||
return (entry & _I86_PTE_FRAME);
|
||||
}
|
||||
|
||||
unsigned char pt_entry_is_present (pt_entry entry) {
|
||||
return ( (entry & _I86_PTE_PRESENT) > 0 );
|
||||
return (entry & _I86_PTE_PRESENT);
|
||||
}
|
||||
|
||||
unsigned char pt_entry_is_writable (pt_entry entry) {
|
||||
return ( (entry & _I86_PTE_WRITABLE) > 0 );
|
||||
return (entry & _I86_PTE_WRITABLE);
|
||||
}
|
@ -27,3 +27,11 @@ _write_cr3:
|
||||
mov cr3, eax
|
||||
pop ebp
|
||||
retn
|
||||
|
||||
global _vmmngr_flush_tbl_entry
|
||||
_vmmngr_flush_tbl_entry:
|
||||
mov eax, [ebp+8]
|
||||
cli
|
||||
invlpg [eax]
|
||||
sti
|
||||
retn
|
@ -1,26 +1,34 @@
|
||||
/******************************************************
|
||||
* Physical Memory Manager *
|
||||
******************************************************/
|
||||
#include <system.h>
|
||||
#include <string.h>
|
||||
|
||||
// +==============================================+
|
||||
// | HEADERS |
|
||||
// +===================================== cta os =+
|
||||
#include "mmngr_ph.h"
|
||||
|
||||
|
||||
// +==============================================+
|
||||
// | DEFINITIONS |
|
||||
// +===================================== cta os =+
|
||||
#define PMMNGR_BLOCK_SIZE 4096 // block size (4k)
|
||||
#define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE // block alignment
|
||||
|
||||
struct memory_stack_entry{
|
||||
word low;
|
||||
byte high;
|
||||
} __attribute__ ((__packed__));
|
||||
typedef struct memory_stack_entry mstack;
|
||||
|
||||
static uint32_t _mmngr_memory_size=0; // size of physical memory
|
||||
static uint32_t _mmngr_used_blocks=0; // number of blocks currently in use
|
||||
static uint32_t _mmngr_max_blocks=0; // maximum number of available memory blocks
|
||||
static uint32_t _mmngr_index = 0;
|
||||
// +==============================================+
|
||||
// | DATA DECLARATIONS |
|
||||
// +===================================== cta os =+
|
||||
static unsigned _mmngr_memory_size=0; // size of physical memory
|
||||
static unsigned _mmngr_used_blocks=0; // number of blocks currently in use
|
||||
static unsigned _mmngr_max_blocks=0; // maximum number of available memory blocks
|
||||
static unsigned _mmngr_index = 0;
|
||||
|
||||
static mstack* _mmngr_memory_stack= 0; // memory stack
|
||||
|
||||
|
||||
// +==============================================+
|
||||
// | LOCAL FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
inline mstack mstack_pop ()
|
||||
{
|
||||
mstack temp;
|
||||
@ -34,7 +42,6 @@ inline mstack mstack_pop ()
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
inline void mstack_push (const mstack *block)
|
||||
{
|
||||
if (block->low == 0 && block-> high == 0) return;
|
||||
@ -46,54 +53,90 @@ inline void mstack_push (const mstack *block)
|
||||
_mmngr_used_blocks--;
|
||||
}
|
||||
|
||||
|
||||
inline byte mstack_test (const mstack *block)
|
||||
inline int mstack_test (const mstack *block)
|
||||
{
|
||||
uint32_t i;
|
||||
unsigned i;
|
||||
for (i = 0; i < _mmngr_index; i++)
|
||||
if (_mmngr_memory_stack[i].low == block->low && _mmngr_memory_stack[i].high == block->high) return 1;
|
||||
if (_mmngr_memory_stack[i].low == block->low && _mmngr_memory_stack[i].high == block->high)
|
||||
return (int) i;
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte pmmngr_test_block (uint32_t block)
|
||||
inline int mstack_qsort_cmp (mstack a, mstack b)
|
||||
{
|
||||
mstack temp;
|
||||
temp.low = block & 0xFFFF;
|
||||
temp.high = (block>>16) & 0xFF;
|
||||
|
||||
return mstack_test(&temp);
|
||||
return (a.high == b.high) ? (int)a.low - (int)b.low : (int)a.high - (int)b.high;
|
||||
}
|
||||
|
||||
void pmmngr_free_block(void* address)
|
||||
void mstack_qsort(int beg, int end)
|
||||
{
|
||||
// Calculate block
|
||||
mstack block;
|
||||
uint32_t temp = (uint32_t)address / PMMNGR_BLOCK_SIZE;
|
||||
block.low = temp & 0xFFFF;
|
||||
block.high = (temp>>16) & 0xFF;
|
||||
|
||||
// Push it
|
||||
mstack_push (&block);
|
||||
|
||||
mstack piv; mstack tmp;
|
||||
|
||||
int l,r,p;
|
||||
|
||||
while (beg<end) // This while loop will avoid the second recursive call
|
||||
{
|
||||
l = beg; p = (beg+end)/2; r = end;
|
||||
|
||||
piv.low = _mmngr_memory_stack[p].low;
|
||||
piv.high = _mmngr_memory_stack[p].high;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while ((l<=r) && (mstack_qsort_cmp(_mmngr_memory_stack[l],piv) <= 0)) l++;
|
||||
while ((l<=r) && (mstack_qsort_cmp(_mmngr_memory_stack[r],piv) > 0)) r--;
|
||||
|
||||
if (l>r) break;
|
||||
|
||||
tmp.low = _mmngr_memory_stack[l].low;
|
||||
tmp.high = _mmngr_memory_stack[l].high;
|
||||
|
||||
_mmngr_memory_stack[l].low = _mmngr_memory_stack[r].low;
|
||||
_mmngr_memory_stack[l].high = _mmngr_memory_stack[r].high;
|
||||
|
||||
_mmngr_memory_stack[r].low = tmp.low;
|
||||
_mmngr_memory_stack[r].high = tmp.high;
|
||||
|
||||
if (p==r) p=l;
|
||||
|
||||
l++; r--;
|
||||
}
|
||||
|
||||
_mmngr_memory_stack[p].low = _mmngr_memory_stack[r].low;
|
||||
_mmngr_memory_stack[p].high = _mmngr_memory_stack[r].high;
|
||||
|
||||
_mmngr_memory_stack[r].low = piv.low;
|
||||
_mmngr_memory_stack[r].high = piv.high;
|
||||
r--;
|
||||
|
||||
// Recursion on the shorter side & loop (with new indexes) on the longer
|
||||
if ((r-beg)<(end-l)) {
|
||||
mstack_qsort(beg, r);
|
||||
beg=l;
|
||||
}
|
||||
else {
|
||||
mstack_qsort(l, end);
|
||||
end=r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* pmmngr_alloc_block()
|
||||
// +==============================================+
|
||||
// | DEBUGGING FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
/*void print_stack()
|
||||
{
|
||||
if (_mmngr_index == 0) return 0;// Out of memory
|
||||
// pop a block
|
||||
mstack block = mstack_pop();
|
||||
|
||||
// Calculate and return address;
|
||||
void* address;
|
||||
uint32_t temp = block.low | (block.high<<16);
|
||||
address = (void *)(temp * PMMNGR_BLOCK_SIZE);
|
||||
|
||||
return address;
|
||||
int i;
|
||||
for (i = 0; i < _mmngr_index; i++) printf (" %u", _mmngr_memory_stack[i].low);
|
||||
}
|
||||
extern char getch();*/
|
||||
|
||||
|
||||
void pmmngr_init (size_t memSize, uint32_t stack) {
|
||||
// +==============================================+
|
||||
// | INITIALISATION FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
void pmmngr_init (unsigned memSize, unsigned stack) {
|
||||
|
||||
_mmngr_memory_size = memSize;
|
||||
_mmngr_memory_stack = (mstack*) stack;
|
||||
@ -104,7 +147,7 @@ void pmmngr_init (size_t memSize, uint32_t stack) {
|
||||
// By default, all of memory is in use
|
||||
}
|
||||
|
||||
void pmmngr_init_region (physical_addr base, size_t size) {
|
||||
void pmmngr_init_region (unsigned base, unsigned size) {
|
||||
|
||||
mstack block;
|
||||
|
||||
@ -121,7 +164,7 @@ void pmmngr_init_region (physical_addr base, size_t size) {
|
||||
|
||||
}
|
||||
|
||||
void pmmngr_deinit_region (physical_addr base, size_t size) {
|
||||
void pmmngr_deinit_region (unsigned base, unsigned size) {
|
||||
unsigned int start = base / PMMNGR_BLOCK_SIZE;
|
||||
unsigned int count = size / PMMNGR_BLOCK_SIZE;
|
||||
int temp;
|
||||
@ -161,28 +204,136 @@ void pmmngr_deinit_region (physical_addr base, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
size_t pmmngr_get_memory_size () {
|
||||
// +==============================================+
|
||||
// | MEMORY MANAGING FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
unsigned char pmmngr_test_block (unsigned block)
|
||||
{
|
||||
mstack temp;
|
||||
temp.low = block & 0xFFFF;
|
||||
temp.high = (block>>16) & 0xFF;
|
||||
|
||||
return (mstack_test(&temp) == -1)? 0 : 1;
|
||||
}
|
||||
|
||||
void pmmngr_free_block(void* address)
|
||||
{
|
||||
// Calculate block
|
||||
mstack block;
|
||||
unsigned temp = (unsigned)address / PMMNGR_BLOCK_SIZE;
|
||||
block.low = temp & 0xFFFF;
|
||||
block.high = (temp>>16) & 0xFF;
|
||||
|
||||
// Push it
|
||||
mstack_push (&block);
|
||||
}
|
||||
|
||||
void pmmngr_free_blocks (unsigned base, unsigned size)
|
||||
{
|
||||
mstack start, end, i;
|
||||
|
||||
// 4k align
|
||||
base /= PMMNGR_BLOCK_SIZE;
|
||||
size /= PMMNGR_BLOCK_SIZE;
|
||||
|
||||
// Calculate blocks
|
||||
start.low = base & 0xFFFF;
|
||||
start.high = (base >> 16) & 0xFF;
|
||||
end.low = (base + size) & 0xFFFF;
|
||||
end.high = ((base + size)>>16) & 0xFF;
|
||||
|
||||
for (i.low = start.low, i.high = start.high; // i = start
|
||||
i.low < end.low || i.high < end.high;) // i != end
|
||||
{
|
||||
// only push if block is used
|
||||
if (mstack_test(&i) == -1) mstack_push(&i);
|
||||
|
||||
// increment i.high
|
||||
if (i.low == 0xFFFF) {
|
||||
i.low = 0; i.high++;
|
||||
}
|
||||
else i.low++;
|
||||
}
|
||||
}
|
||||
|
||||
void* pmmngr_alloc_block()
|
||||
{
|
||||
if (_mmngr_index == 0) return 0;// Out of memory
|
||||
// pop a block
|
||||
mstack block = mstack_pop();
|
||||
|
||||
// Calculate and return address;
|
||||
void* address;
|
||||
unsigned temp = block.low | (block.high<<16);
|
||||
address = (void *)(temp * PMMNGR_BLOCK_SIZE);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void* pmmngr_alloc_blocks (unsigned blocks)
|
||||
{
|
||||
// Less than 2 blocks requested
|
||||
if (blocks == 0) return 0;
|
||||
if (blocks == 1) return pmmngr_alloc_block();
|
||||
|
||||
// Sort the stack for the next step
|
||||
mstack_qsort(0, (int)_mmngr_index);
|
||||
|
||||
int i = (int) _mmngr_index-1; // i = counter
|
||||
int l = 1; // l = number of consecutive blocks
|
||||
unsigned temp; // temp = temporary storage
|
||||
unsigned prev = _mmngr_memory_stack[i].low | (_mmngr_memory_stack[i].high<<16); --i;
|
||||
|
||||
// Search consecutive blocks
|
||||
for (; i >=0; i--) {
|
||||
temp = _mmngr_memory_stack[i].low | (_mmngr_memory_stack[i].high<<16);
|
||||
|
||||
if (temp == prev-1) l++;
|
||||
else l = 1;
|
||||
|
||||
if (l == blocks) {
|
||||
pmmngr_deinit_region (temp * PMMNGR_BLOCK_SIZE, blocks * PMMNGR_BLOCK_SIZE);
|
||||
return (void*) (temp * PMMNGR_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
prev = temp;
|
||||
}
|
||||
|
||||
return 0; // Could not find so many free blocks
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// +==============================================+
|
||||
// | GET DATA FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
unsigned pmmngr_get_memory_size () {
|
||||
return _mmngr_memory_size;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_block_count () {
|
||||
unsigned pmmngr_get_block_count () {
|
||||
return _mmngr_max_blocks;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_use_block_count () {
|
||||
unsigned pmmngr_get_use_block_count () {
|
||||
return _mmngr_used_blocks;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_free_block_count () {
|
||||
unsigned pmmngr_get_free_block_count () {
|
||||
return _mmngr_index;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_block_size () {
|
||||
unsigned pmmngr_get_block_size () {
|
||||
return PMMNGR_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
void pmmngr_paging_enable (byte b) {
|
||||
uint32_t temp;
|
||||
|
||||
// +==============================================+
|
||||
// | PAGING RELATED FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
void pmmngr_paging_enable (unsigned char b) {
|
||||
unsigned temp;
|
||||
|
||||
temp = read_cr0();
|
||||
// Enable
|
||||
@ -192,13 +343,7 @@ void pmmngr_paging_enable (byte b) {
|
||||
write_cr0(temp);
|
||||
}
|
||||
|
||||
|
||||
byte pmmngr_is_paging () {
|
||||
uint32_t temp = read_cr0();
|
||||
unsigned char pmmngr_is_paging () {
|
||||
unsigned temp = read_cr0();
|
||||
return ((temp&0x80000000)>0);
|
||||
}
|
||||
|
||||
mstack* pmmngr_get_stack_addr()
|
||||
{
|
||||
return _mmngr_memory_stack;
|
||||
}
|
@ -1,33 +1,47 @@
|
||||
|
||||
#ifndef _MMNGR_PHYS_H
|
||||
#define _MMNGR_PHYS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <system.h>
|
||||
|
||||
|
||||
#define pmmngr_load_PDBR(addr) write_cr3(addr)
|
||||
#define pmmngr_get_PDBR() read_cr3()
|
||||
|
||||
// physical address
|
||||
typedef unsigned physical_addr;
|
||||
|
||||
extern uint32_t read_cr0();
|
||||
extern uint32_t read_cr3();
|
||||
extern void write_cr0(uint32_t data);
|
||||
extern void write_cr3(uint32_t data);
|
||||
extern void pmmngr_free_block(void* address); // releases a memory block
|
||||
extern void* pmmngr_alloc_block (); // allocates a single memory block
|
||||
extern void pmmngr_init (size_t memSize, uint32_t stack); // initialize the physical memory manager
|
||||
extern void pmmngr_init_region (physical_addr base, size_t size); // enables a physical memory region for use
|
||||
extern void pmmngr_deinit_region (physical_addr base, size_t size); // disables a physical memory region as in use (unuseable)
|
||||
extern size_t pmmngr_get_memory_size (); // returns amount of physical memory the manager is set to use
|
||||
extern uint32_t pmmngr_get_use_block_count (); // returns number of blocks currently in use
|
||||
extern uint32_t pmmngr_get_free_block_count (); // returns number of blocks not in use
|
||||
extern uint32_t pmmngr_get_block_count (); // returns number of memory blocks
|
||||
extern uint32_t pmmngr_get_block_size (); // returns default memory block size in bytes
|
||||
extern void pmmngr_paging_enable (byte b); // enable or disable paging
|
||||
extern byte pmmngr_is_paging (); // test if paging is enabled
|
||||
struct memory_stack_entry{
|
||||
unsigned short low;
|
||||
unsigned char high;
|
||||
} __attribute__ ((__packed__));
|
||||
typedef struct memory_stack_entry mstack;
|
||||
|
||||
// CR registers r/w operations
|
||||
extern unsigned read_cr0();
|
||||
extern unsigned read_cr3();
|
||||
extern void write_cr0(unsigned data);
|
||||
extern void write_cr3(unsigned data);
|
||||
|
||||
// Free/Alloc memory block(s)
|
||||
extern void pmmngr_free_block(void* address);
|
||||
extern void pmmngr_free_blocks(unsigned base, unsigned size);
|
||||
extern void* pmmngr_alloc_block ();
|
||||
extern void* pmmngr_alloc_blocks (unsigned blocks);
|
||||
|
||||
// De/Initialisation routines
|
||||
extern void pmmngr_init (unsigned memSize, unsigned stack);
|
||||
extern void pmmngr_init_region (unsigned base, unsigned size);
|
||||
extern void pmmngr_deinit_region (unsigned base, unsigned size);
|
||||
|
||||
// Useful information
|
||||
extern unsigned pmmngr_get_memory_size (); // returns amount of physical memory the manager is set to use
|
||||
extern unsigned pmmngr_get_use_block_count (); // returns number of blocks currently in use
|
||||
extern unsigned pmmngr_get_free_block_count (); // returns number of blocks not in use
|
||||
extern unsigned pmmngr_get_block_count (); // returns number of memory blocks
|
||||
extern unsigned pmmngr_get_block_size (); // returns default memory block size in unsigned chars
|
||||
extern unsigned char pmmngr_test_block (unsigned block);
|
||||
|
||||
// Paging
|
||||
extern void pmmngr_paging_enable (unsigned char b); // enable or disable paging
|
||||
extern unsigned char pmmngr_is_paging (); // test if paging is enabled
|
||||
|
||||
extern void print_stack();
|
||||
|
||||
extern byte pmmngr_test_block (uint32_t block);
|
||||
#endif
|
||||
|
140
SysCore/memory/mmngr_vi.c
Normal file
140
SysCore/memory/mmngr_vi.c
Normal file
@ -0,0 +1,140 @@
|
||||
// +==============================================+
|
||||
// | HEADERS |
|
||||
// +===================================== cta os =+
|
||||
#include "mmngr_vi.h"
|
||||
#include "mmngr_ph.h"
|
||||
|
||||
// +==============================================+
|
||||
// | DEFINITIONS |
|
||||
// +===================================== cta os =+
|
||||
#define PAGE_SIZE 4096
|
||||
#define PTABLE_ADDR_SPACE_SIZE 0x400000
|
||||
#define DTABLE_ADDR_SPACE_SIZE 0xffffffff
|
||||
|
||||
pdirectory* _current_directory;
|
||||
unsigned _current_page_directory_base_register;
|
||||
extern unsigned char *memset (unsigned char *dest, unsigned char val, int count);
|
||||
extern char getch();
|
||||
|
||||
// +==============================================+
|
||||
// | PAGE FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
unsigned char vmmngr_alloc_page (pt_entry* entry)
|
||||
{
|
||||
void* p = pmmngr_alloc_block ();
|
||||
if (!p) return 0;
|
||||
|
||||
pt_entry_set_frame(entry, (unsigned)p);
|
||||
pt_entry_add_attrib (entry, _I86_PTE_PRESENT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vmmngr_free_page (pt_entry* entry)
|
||||
{
|
||||
void* p = (void*) pt_entry_get_frame(*entry);
|
||||
|
||||
if (p) pmmngr_free_block (p);
|
||||
|
||||
pt_entry_del_attrib (entry, _I86_PTE_PRESENT);
|
||||
}
|
||||
|
||||
|
||||
// +==============================================+
|
||||
// | PAGE TABLE FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
inline void vmmngr_ptable_clear(ptable* p)
|
||||
{
|
||||
if(p) memset ((unsigned char*)p, 0, sizeof(ptable));
|
||||
}
|
||||
|
||||
inline unsigned vmmngr_ptable_virt_to_index (unsigned addr)
|
||||
{
|
||||
return (addr >= PTABLE_ADDR_SPACE_SIZE) ? 0 : addr/PAGE_SIZE;
|
||||
}
|
||||
|
||||
inline pt_entry* vmmngr_ptable_lookup_entry (ptable* p, unsigned addr)
|
||||
{
|
||||
if (p) return &p->m_entries[vmmngr_ptable_virt_to_index(addr)];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// +==============================================+
|
||||
// | PAGE DIRECTORY FUNCTIONS |
|
||||
// +===================================== cta os =+
|
||||
inline void vmmngr_pdirectory_clear(pdirectory* dir)
|
||||
{
|
||||
if(dir) memset ((unsigned char*)dir, 0, sizeof(pdirectory));
|
||||
}
|
||||
|
||||
inline unsigned vmmngr_pdirectory_virt_to_index (unsigned addr)
|
||||
{
|
||||
return (addr > DTABLE_ADDR_SPACE_SIZE) ? 0 : addr/PAGE_SIZE;
|
||||
}
|
||||
|
||||
inline pd_entry* vmmngr_pdirectory_lookup_entry (pdirectory* dir, unsigned addr)
|
||||
{
|
||||
if (dir) return &dir->m_entries[vmmngr_ptable_virt_to_index(addr)];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// +==============================================+
|
||||
// | VIRTUAL MEMORY MANAGER |
|
||||
// +===================================== cta os =+
|
||||
inline unsigned char vmmngr_switch_pdirectory (pdirectory* dir)
|
||||
{
|
||||
if (!dir) return 0;
|
||||
_current_directory = dir;
|
||||
|
||||
write_cr3 (_current_page_directory_base_register);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pdirectory* vmmngr_get_directory() {
|
||||
return _current_directory;
|
||||
}
|
||||
|
||||
void vmmngr_initialize()
|
||||
{
|
||||
// Allocate default page table
|
||||
ptable* table = (ptable*) pmmngr_alloc_block();
|
||||
if (!table) return;
|
||||
|
||||
// Clear page table
|
||||
vmmngr_ptable_clear(table);
|
||||
|
||||
// Identity map the first page table
|
||||
int i, frame;
|
||||
for (i = 0, frame = 0; i < 1024; i++, frame += 4096)
|
||||
{
|
||||
// Create a new page
|
||||
pt_entry page = 0;
|
||||
pt_entry_add_attrib (&page, _I86_PTE_PRESENT);
|
||||
pt_entry_set_frame (&page, frame);
|
||||
|
||||
table->m_entries[vmmngr_ptable_virt_to_index(frame)] = page;
|
||||
}
|
||||
|
||||
// Create default directory table
|
||||
pdirectory* dir = (pdirectory*) pmmngr_alloc_blocks(3);
|
||||
if (!dir) return;
|
||||
|
||||
// Clear directory table and set it as current
|
||||
vmmngr_pdirectory_clear(dir);
|
||||
|
||||
// Get first entry in dir table and set it up to point to our table
|
||||
pd_entry* entry = vmmngr_pdirectory_lookup_entry(dir, 0);
|
||||
pd_entry_add_attrib (entry, _I86_PDE_PRESENT);
|
||||
pd_entry_add_attrib (entry, _I86_PDE_WRITABLE);
|
||||
pd_entry_set_frame (entry, (unsigned) table);
|
||||
|
||||
// Store current PDBR
|
||||
_current_page_directory_base_register = (unsigned) &dir->m_entries;
|
||||
|
||||
// Switch to our page directory
|
||||
vmmngr_switch_pdirectory (dir);
|
||||
|
||||
// Enable paging
|
||||
pmmngr_paging_enable (1);
|
||||
}
|
25
SysCore/memory/mmngr_vi.h
Normal file
25
SysCore/memory/mmngr_vi.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef __MEMORY_MANAGER_VIRTUAL__
|
||||
#define __MEMORY_MANAGER_VIRTUAL__
|
||||
|
||||
#include "lib/pde.h"
|
||||
#include "lib/pte.h"
|
||||
|
||||
#define PAGES_PER_TABLE 1024
|
||||
#define PAGES_PER_DIR 1024
|
||||
|
||||
typedef unsigned virtual_address;
|
||||
|
||||
typedef struct {
|
||||
pt_entry m_entries[PAGES_PER_TABLE];
|
||||
} ptable ;
|
||||
|
||||
typedef struct {
|
||||
pd_entry m_entries[PAGES_PER_DIR];
|
||||
} pdirectory ;
|
||||
|
||||
//extern pdirectory* _current_directory;
|
||||
|
||||
extern void vmmngr_flush_tbl_entry (unsigned addr);
|
||||
extern void vmmngr_initialize();
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
#include <pde.h>
|
||||
|
||||
void pt_entry_add_attrib (pt_entry* entry, unsigned mask) {
|
||||
*entry |= mask;
|
||||
}
|
||||
|
||||
void pt_entry_del_attrib (pt_entry* entry, unsigned mask) {
|
||||
*entry &= ~mask;
|
||||
}
|
||||
|
||||
void pt_entry_set_frame (pt_entry* entry, unsigned address) {
|
||||
*entry &= ~_I86_PTE_FRAME;
|
||||
*entry |= address & _I86_PTE_FRAME;
|
||||
}
|
||||
|
||||
unsigned pt_entry_get_frame (pt_entry entry) {
|
||||
return entry&_I86_PTE_FRAME;
|
||||
}
|
||||
|
||||
unsigned char pt_entry_is_present (pt_entry entry) {
|
||||
return ( (entry & _I86_PTE_PRESENT) > 0 );
|
||||
}
|
||||
|
||||
unsigned char pt_entry_is_writable (pt_entry entry) {
|
||||
return ( (entry & _I86_PTE_WRITABLE) > 0 );
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#ifndef __PAGE_DIRECTORY_ENTRY_
|
||||
#define __PAGE_DIRECTORY_ENTRY_
|
||||
|
||||
enum __PAGE_FLAGS {
|
||||
_I86_PTE_PRESENT = 1,
|
||||
_I86_PTE_WRITABLE = 2,
|
||||
_I86_PTE_USER = 4,
|
||||
_I86_PTE_WRITETHROUGH = 8,
|
||||
_I86_PTE_NOT_CACHEABLE = 0x10,
|
||||
_I86_PTE_ACCESSED = 0x20,
|
||||
_I86_PTE_DIRTY = 0x40,
|
||||
_I86_PTE_PAT = 0x80,
|
||||
_I86_PTE_CPU_GLOBAL = 0x100,
|
||||
_I86_PTE_LV4_GLOBAL = 0x200,
|
||||
_I86_PTE_FRAME = 0x7FFFF000
|
||||
};
|
||||
|
||||
typedef unsigned pt_entry;
|
||||
|
||||
extern void pt_entry_add_attrib (pt_entry* entry, unsigned mask);
|
||||
extern void pt_entry_del_attrib (pt_entry* entry, unsigned mask);
|
||||
extern void pt_entry_set_frame (pt_entry* entry, unsigned address);
|
||||
extern unsigned pt_entry_get_frame (pt_entry entry);
|
||||
|
||||
extern unsigned char pt_entry_is_present (pt_entry entry);
|
||||
extern unsigned char pt_entry_is_writable (pt_entry entry);
|
||||
#endif
|
Reference in New Issue
Block a user