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

BIN
Asuro.iso

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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.