CTAOS v4
This commit is contained in:
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);
|
||||
}
|
Reference in New Issue
Block a user