CTAOS v3
This commit is contained in:
28
SysCore/memory/compile.bat
Normal file
28
SysCore/memory/compile.bat
Normal file
@ -0,0 +1,28 @@
|
||||
@echo off
|
||||
|
||||
rem NASM and DJGPP executable paths:
|
||||
set nasm_path=C:\nasm
|
||||
set djgpp_path=C:\DJGPP\bin
|
||||
set objpath=..\objects
|
||||
set incpath=../include
|
||||
goto build
|
||||
|
||||
:error
|
||||
@echo.
|
||||
@echo There have been build errors. Building halted.
|
||||
@pause
|
||||
exit
|
||||
|
||||
:build
|
||||
@echo Building Memory Manager...
|
||||
|
||||
del %objpath%\mmngr_cr.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
|
||||
%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
|
||||
|
||||
:check
|
||||
if not exist %objpath%\mmngr_cr.o goto error
|
||||
if not exist %objpath%\mmngr_ph.o goto error
|
29
SysCore/memory/mmngr_cr.asm
Normal file
29
SysCore/memory/mmngr_cr.asm
Normal file
@ -0,0 +1,29 @@
|
||||
bits 32
|
||||
|
||||
global _read_cr0
|
||||
_read_cr0:
|
||||
mov eax, cr0
|
||||
retn
|
||||
|
||||
global _write_cr0
|
||||
_write_cr0:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [ebp+8]
|
||||
mov cr0, eax
|
||||
pop ebp
|
||||
retn
|
||||
|
||||
global _read_cr3
|
||||
_read_cr3:
|
||||
mov eax, cr3
|
||||
retn
|
||||
|
||||
global _write_cr3
|
||||
_write_cr3:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [ebp+8]
|
||||
mov cr3, eax
|
||||
pop ebp
|
||||
retn
|
204
SysCore/memory/mmngr_ph.c
Normal file
204
SysCore/memory/mmngr_ph.c
Normal file
@ -0,0 +1,204 @@
|
||||
/******************************************************
|
||||
* Physical Memory Manager *
|
||||
******************************************************/
|
||||
#include <system.h>
|
||||
#include <string.h>
|
||||
#include "mmngr_ph.h"
|
||||
|
||||
#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;
|
||||
|
||||
static mstack* _mmngr_memory_stack= 0; // memory stack
|
||||
|
||||
inline mstack mstack_pop ()
|
||||
{
|
||||
mstack temp;
|
||||
temp.low = _mmngr_memory_stack[--_mmngr_index].low;
|
||||
temp.high = _mmngr_memory_stack[_mmngr_index].high;
|
||||
_mmngr_used_blocks++;
|
||||
|
||||
_mmngr_memory_stack[_mmngr_index].low = 0xFFFF;
|
||||
_mmngr_memory_stack[_mmngr_index].high = 0xFF;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
inline void mstack_push (const mstack *block)
|
||||
{
|
||||
if (block->low == 0 && block-> high == 0) return;
|
||||
|
||||
_mmngr_memory_stack[_mmngr_index].low = block->low;
|
||||
_mmngr_memory_stack[_mmngr_index].high = block->high;
|
||||
|
||||
_mmngr_index++;
|
||||
_mmngr_used_blocks--;
|
||||
}
|
||||
|
||||
|
||||
inline byte mstack_test (const mstack *block)
|
||||
{
|
||||
uint32_t 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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte pmmngr_test_block (uint32_t block)
|
||||
{
|
||||
mstack temp;
|
||||
temp.low = block & 0xFFFF;
|
||||
temp.high = (block>>16) & 0xFF;
|
||||
|
||||
return mstack_test(&temp);
|
||||
}
|
||||
|
||||
void pmmngr_free_block(void* address)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
uint32_t temp = block.low | (block.high<<16);
|
||||
address = (void *)(temp * PMMNGR_BLOCK_SIZE);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
void pmmngr_init (size_t memSize, uint32_t stack) {
|
||||
|
||||
_mmngr_memory_size = memSize;
|
||||
_mmngr_memory_stack = (mstack*) stack;
|
||||
_mmngr_max_blocks = (_mmngr_memory_size*1024) / PMMNGR_BLOCK_SIZE;
|
||||
_mmngr_used_blocks = _mmngr_max_blocks;
|
||||
_mmngr_index = 0;
|
||||
|
||||
// By default, all of memory is in use
|
||||
}
|
||||
|
||||
void pmmngr_init_region (physical_addr base, size_t size) {
|
||||
|
||||
mstack block;
|
||||
|
||||
|
||||
unsigned int count = size / PMMNGR_BLOCK_SIZE;
|
||||
unsigned int start = base / PMMNGR_BLOCK_SIZE;
|
||||
|
||||
for (; count!=0; count--) {
|
||||
block.low = (start + count) & 0xFFFF;
|
||||
block.high = ((start + count) << 16) & 0xFF;
|
||||
mstack_push(&block);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void pmmngr_deinit_region (physical_addr base, size_t size) {
|
||||
unsigned int start = base / PMMNGR_BLOCK_SIZE;
|
||||
unsigned int count = size / PMMNGR_BLOCK_SIZE;
|
||||
int temp;
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
// Find free blocks in the area and zero them
|
||||
for (i = 0; i < _mmngr_index; i++) {
|
||||
temp = (_mmngr_memory_stack[i].high << 16) | _mmngr_memory_stack[i].low;
|
||||
if (temp >=start && temp < start+count)
|
||||
{ _mmngr_memory_stack[i].high = 0;
|
||||
_mmngr_memory_stack[i].low = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Eliminate zero blocks
|
||||
for (i = 0; i<_mmngr_index; i++)
|
||||
if (_mmngr_memory_stack[i].high == 0 && _mmngr_memory_stack[i].low == 0)
|
||||
{
|
||||
// Find next non-zero
|
||||
for (j = i; _mmngr_memory_stack[j].high == 0 && _mmngr_memory_stack[j].low == 0; j++)
|
||||
if (j == _mmngr_index-1) {
|
||||
j = 0; break; }
|
||||
|
||||
if (j == 0) {
|
||||
_mmngr_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
_mmngr_memory_stack[i].high = _mmngr_memory_stack[j].high;
|
||||
_mmngr_memory_stack[i].low = _mmngr_memory_stack[j].low;
|
||||
_mmngr_memory_stack[j].high = 0;
|
||||
_mmngr_memory_stack[j].low = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t pmmngr_get_memory_size () {
|
||||
return _mmngr_memory_size;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_block_count () {
|
||||
return _mmngr_max_blocks;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_use_block_count () {
|
||||
return _mmngr_used_blocks;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_free_block_count () {
|
||||
return _mmngr_index;
|
||||
}
|
||||
|
||||
uint32_t pmmngr_get_block_size () {
|
||||
return PMMNGR_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
void pmmngr_paging_enable (byte b) {
|
||||
uint32_t temp;
|
||||
|
||||
temp = read_cr0();
|
||||
// Enable
|
||||
if (b) temp |= 0x80000000;
|
||||
else temp &= ~0x80000000;
|
||||
|
||||
write_cr0(temp);
|
||||
}
|
||||
|
||||
|
||||
byte pmmngr_is_paging () {
|
||||
uint32_t temp = read_cr0();
|
||||
return ((temp&0x80000000)>0);
|
||||
}
|
||||
|
||||
mstack* pmmngr_get_stack_addr()
|
||||
{
|
||||
return _mmngr_memory_stack;
|
||||
}
|
33
SysCore/memory/mmngr_ph.h
Normal file
33
SysCore/memory/mmngr_ph.h
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
#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
|
||||
|
||||
extern byte pmmngr_test_block (uint32_t block);
|
||||
#endif
|
26
SysCore/memory/pde.c
Normal file
26
SysCore/memory/pde.c
Normal file
@ -0,0 +1,26 @@
|
||||
#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 );
|
||||
}
|
27
SysCore/memory/pde.h
Normal file
27
SysCore/memory/pde.h
Normal file
@ -0,0 +1,27 @@
|
||||
#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
|
26
SysCore/memory/pte.c
Normal file
26
SysCore/memory/pte.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <pte.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 );
|
||||
}
|
27
SysCore/memory/pte.h
Normal file
27
SysCore/memory/pte.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __PAGE_TABLE_ENTRY_
|
||||
#define __PAGE_TABLE_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