This commit is contained in:
2021-09-14 18:34:14 +03:00
parent 7cb940e485
commit 4e5c38d0ff
152 changed files with 5042 additions and 2585 deletions

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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