140 lines
4.1 KiB
C
140 lines
4.1 KiB
C
// +==============================================+
|
|
// | 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);
|
|
} |