VMem & PMem

git-svn-id: https://spexeah.com:8443/svn/Asuro@124 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
This commit is contained in:
kieron
2017-05-19 23:09:35 +00:00
parent 0bfa418d56
commit 57b6845ed4
14 changed files with 139 additions and 106 deletions

View File

@ -52,12 +52,13 @@ begin
isr.init();
irq.init();
pmemorymanager.init();
vmemorymanager.init();
scheduler.init();
STI;
isr32.hook(uint32(@bios_data_area.tick_update));
z:= 1;
{z:= 1;
while true do begin
console.writeword(z);
console.writestring(': ');
@ -65,11 +66,11 @@ begin
console.writewordln(uint32(pint));
if pint = nil then while true do begin end else pint^:= 1234;
z:=z+1;
end;
end;}
//drivers
keyboard.init(keyboard_layout);
if PageDirectory[KERNEL_PAGE_NUMBER].Present then begin
if PageDirectory^[KERNEL_PAGE_NUMBER].Present then begin
console.writestringln('!');
end else begin
console.writestringln('?');

View File

@ -4,109 +4,67 @@ interface
uses
util,
console,
vmemorymanager;
const
ALLOC_SPACE = 8; //64-Bit Allocations
MAX_ENTRIES = $FFFFF;
procedure init;
function kalloc(size : uint32) : void;
procedure kfree(area : void);
console;
type
TBlock_Entry = packed record
Present : Boolean;
Length : uint8;
TPhysicalMemoryEntry = packed record
Present : Boolean;
MappedTo : uint32;
end;
TPhysicalMemory = array[0..1023] of TPhysicalMemoryEntry;
procedure init;
function newblock(caller : uint32) : uint16;
procedure freeblock(block : uint16; caller : uint32);
implementation
var
Memory_Start : uint32;
Memory_Manager : packed array[1..MAX_ENTRIES] of TBlock_Entry;
PhysicalMemory: TPhysicalMemory;
procedure init;
var
i : uint32;
begin
console.writestringln('MEM-MANAGER: INIT BEGIN.');
For i:=0 to MAX_ENTRIES-1 do begin
Memory_Manager[i].Present:= False;
with PhysicalMemory[0] do begin
Present:= True;
MappedTo:= 0;
end;
Memory_Start:= uint32(@util.endptr);
console.writestringln('MEM-MANAGER: INIT END.');
end;
function kalloc(size : uint32) : void;
var
blocks : uint32;
rem : uint32;
i,j : uint32;
miss : boolean;
begin
blocks:= size div ALLOC_SPACE;
rem:= size - (blocks * ALLOC_SPACE);
if rem > 0 then blocks:= blocks + 1;
kalloc:= nil;
for i:=0 to MAX_ENTRIES-1 do begin
miss:= false;
for j:=0 to blocks-1 do begin
if Memory_Manager[i+j].Present then begin
miss:= true;
break;
end;
end;
if not miss then begin
kalloc:= void(Memory_Start+(i * ALLOC_SPACE));
for j:=0 to blocks-1 do begin
Memory_Manager[i+j].Present:= true;
Memory_Manager[i+j].Length:= 0;
if j = 0 then Memory_Manager[i+j].Length:= blocks;
end;
console.writestring('Allocated ');
console.writeint(blocks);
console.writestring(' Block(s). [Block: ');
console.writeint(i);
console.writestringln(']');
break;
end;
with PhysicalMemory[1] do begin
Present:= True;
MappedTo:= 0;
end;
end;
procedure kfree(area : void);
function newblock(caller : uint32) : uint16;
var
Block : uint32;
bLength : uint8;
i : uint32;
i : uint16;
begin
if uint32(area) < Memory_Start then begin
asm
INT 13
end;
end;
Block:= (uint32(Area) - Memory_Start) div ALLOC_SPACE;
if Memory_Manager[Block].Present then begin
If Memory_Manager[Block].Length > 0 then begin
bLength:= Memory_Manager[Block].Length;
for i:=0 to bLength-1 do begin
Memory_Manager[Block+i].Present:= False;
end;
//console.writestring('Freed ');
//console.writeint(bLength);
//console.writestring(' Block(s). [Block: ');
//console.writeint(Block);
//console.writestringln(']');
end else begin
asm
INT 13
end;
newblock:= 0;
for i:=2 to 1023 do begin
if not PhysicalMemory[i].Present then begin
PhysicalMemory[i].Present:= True;
PhysicalMemory[i].MappedTo:= caller;
newblock:= i;
exit;
end;
end;
end;
procedure freeblock(block : uint16; caller : uint32);
begin
if block > 1023 then begin
GPF;
exit;
end;
if block < 2 then begin
GPF;
exit;
end;
if PhysicalMemory[block].caller <> caller then begin
GPF;
exit;
end;
PhysicalMemory[block].Present:= false;
end;
end.

View File

@ -18,6 +18,7 @@ uses
procedure CLI();
procedure STI();
procedure GPF();
function hi(b : uint8) : uint8;
function lo(b : uint8) : uint8;
function switchendian(b : uint8) : uint8;
@ -61,6 +62,11 @@ asm
STI
end;
procedure GPF(); assembler;
asm
INT 13
end;
function switchendian(b : uint8) : uint8; [public, alias: 'util_switchendian'];
begin
switchendian:= (lo(b) SHL 4) OR hi(b);

View File

@ -2,22 +2,12 @@ unit vmemorymanager;
interface
type
{PPageTableEntry = ^TPageTableEntry;
TPageTableEntry = bitpacked record
Present,
Writable,
UserMode,
WriteThrough,
NotCacheable,
Accessed,
Dirty,
AttrIndex,
GlobalPage: Boolean;
Available: UBit3;
FrameAddress: UBit20;
end;}
uses
util,
pmemorymanager,
console;
type
PPageDirEntry = ^TPageDirEntry;
TPageDirEntry = bitpacked record
Present,
@ -30,15 +20,93 @@ type
PageSize,
GlobalPage: Boolean;
Available: UBit3;
TableAddress: UBit20;
Address: UBit20;
end;
TPageDirectory = Array[1..1024] of TPageDirEntry;
TPageDirectory = Array[0..1023] of TPageDirEntry;
PPageDirectory = ^TPageDirectory;
Var
PageDirectory : TPageDirectory; external name '_PageDirectory';
var
PageDirectory : PPageDirectory;
procedure init;
function new_page(page_number : uint16) : boolean;
function new_page_at_address(address : uint32) : boolean;
procedure free_page(page_number : uint16);
implementation
function load_current_page_directory : PPageDirectory;
var
Directory : uint32;
begin
asm
MOV EAX, CR3
MOV Directory, EAX
end;
Directory:= Directory + KERNEL_VIRTUAL_BASE;
load_current_page_directory:= PPageDirectory(Directory);
end;
procedure init;
var
i : uint32;
begin
console.writestringln('VMM: INIT BEGIN.');
PageDirectory:= load_current_page_directory;
console.writestringln('VMM: INIT END.');
end;
function new_page(page_number : uint16) : boolean;
var
block : uint16;
page : uint16;
begin
new_page:= false;
if PageDirectory^[block].Present then exit;
if PageDirectory^[block].Reserved then exit;
block:= pmemorymanager.newblock(uint32(PageDirectory));
if block < 2 then begin
GPF;
exit;
end else begin
PageDirectory^[block].Present:= true;
PageDirectory^[block].Address:= block;
PageDirectory^[block].PageSize:= true;
new_page:= true;
end;
end;
function new_page_at_address(address : uint32) : boolean;
var
page_number : uint16;
begin
page_number:= address SHR 22;
new_page_at_address:= new_page(page_number);
end;
procedure free_page(page_number : uint16);
begin
if PageDirectory^[page_number].Present then begin
asm
invlpg [page_number]
end;
end else begin
GPF;
end;
end;
function free_page_at_address(address : uint32);
var
page_number : uint16;
begin
page_number:= address SHR 22;
free_page(page_number);
end;
end.