All pastes #227581 Raw Edit

Memory Manager

public text v1 · immutable
#227581 ·published 2006-10-29 11:00 UTC
rendered paste body
; **********************************************************

;	Name: Memory Manager
;	Autor: Toaster Burger
;	Version: 1.00
;	Date: 26.11.2005
;	last Update: 10.03.2006
;	see document: ToasterOS.pdf

; **********************************************************

[bits 32]
CPU 486

%define	Type_System
%include "interface.asm"
%include "Lp Global Tables.asm"

org Memory_Manager



jmp Set_Kernel_Memory

jmp New_Memory
jmp Free_Memory

jmp Get_Process_Handle
jmp Check_Process_Handle
jmp Set_Process_CR3
jmp Get_Process_CR3


jmp Create_VAS
jmp Expand_VAS
jmp Destroy_VAS

jmp Create_System_VAS
jmp Expand_System_VAS


jmp Copy_Process_Data


; the native API
jmp Enable_Memory_Management
jmp Map_Memory
jmp New_Page_Table
jmp New_Page_Frame

jmp Map_self_Memory
jmp New_self_Page_Table




; set the gates for the functions to export

;jmp dword Set_Memory

;jmp dword Create_VAS
;jmp dword Destroy_VAS
;jmp dword Expand_VAS
;jmp dword System_VAS

;jmp dword Get_CR3

;jmp dword Check_Process_Handle

;jmp dword Copy_Process_Data

;jmp dword Get_static_Page

;jmp dword Reserve_Memory
;jmp dword Deserve_Memory





; include the Public Heap Manager Functions
%include "Public Heap Manager Functions.asm"

%define	System_Memory_Heap_descriptors	512*1024 / descriptor_size
%define	SMHs				System_Memory_Heap_descriptors

%define	Page_Info_Array_size		20000h
%define	PIAs				Page_Info_Array_size







Enable_Memory_Management:

; calling macro:	API
; user:			Memory Manager
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Enable Memory Management"
; date:			Thursday, 28th September 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Enable_Memory_Management, Memory

;   Memory = size of the physical memory in bytes
;   return = void

;   This function enables the Memory Management.
;   It sets up the Memory Management buffers, the Heap Tree.

Enter_System    28


; create the System Memory Heap
call Create_System_Memory_Heap

; set the memory to physical present
call Set_Memory_block_internal


Leave_System

ret







New_Memory:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"New physical Memory"
; date:			Thursday, 28th September 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API New_Memory, size

;   size = size in bytes of needed memory
;   return = address of memory

Enter_System    28


; use the System Memory Heap
mov [Heap_Tree],dword Memory_Heap_Tree
mov [Heap_Tree_descriptors],dword SMHs


; call the sub function
call New_Polymorph


New_Exit:
Leave_System

ret







Free_Memory:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Free physical Memory"
; date:			Thursday, 28th September 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Free_Memory, memory

;   memory = memory to free, returned by "New Memory"

Enter_System    28


; use the System Memory Heap
mov [Heap_Tree],dword Memory_Heap_Tree
mov [Heap_Tree_descriptors],dword SMHs

; call the sub function
call Free_Polymorph


Leave_System

ret











Create_System_Memory_Heap:

; LAPI Create_System_Memory_Heap

; creates the System Memory Heap, with following conditions:
;     Heap = physical 0 - 4 GB (without Extensions)
;     Heap size = max. 4 GB (without Extensions)
;     Heap Tree = Memory_Heap_Tree
;     Heap Tree size = 512 KB


; create the System Memory Heap Tree
mov edi,Memory_Heap_Tree


; create the first descriptor of the Heap Tree
;    eax = physical memory size in bytes
shr eax,1
stosd							; store the Heap Segment Size

mov al,10001000b
stosb							; store the state

xor eax,eax
stosd							; store Pointer 1
stosd							; store Pointer 2


; set the variables
mov [Heap_Tree],dword Memory_Heap_Tree
mov [Heap_Tree_descriptors],dword SMHs


ret












; Process Handle functions:
;    Get Process Handle
;    Check Process Handle
;    Set Process CR3
;    Get Process CR3








Get_Process_Handle:

; API Get_Process_Handle

; return = Process Handle

Enter_System    28


mov esi,Process_Info_Array
mov ecx,PIAs/4


Get_Process_Handle_np:
lodsd
or eax,eax
jz Process_Handle_found
loop Get_Process_Handle_np

stc
mov eax,No_free_Process
jmp Get_Process_Handle_Exit


Process_Handle_found:
; reserve the fount Process Handle
sub esi,4
mov [esi],dword 1

; store the Handle (equal to the number of the free Process Structure) in eax
mov eax,PIAs/4 - 1
sub eax,ecx


Get_Process_Handle_Exit:
Leave_System

ret









Check_Process_Handle:

; API Check_Process_Handle, Handle

; Handle = Process Handle to check of validity

Enter_System    28


mov eax,[Param1]

; check the boundary
cmp eax,PIAs/4 - 1
jg Invalid_Process_Handle

lea esi,[Process_Info_Array + 4*eax]
lodsd

or eax,eax
jnz Check_Process_Handle_Exit


Invalid_Process_Handle:
stc
mov eax,Invalid_Handle


Check_Process_Handle_Exit:
Leave_System

ret











Set_Process_CR3:

; API Set_Process_CR3, Handle, CR3

; (undocumented)
;    the CR3 value may be set to zero to destroy and invalidate the Process Handle

Enter_System    28


movzx eax,word [Param1]
lea esi,[Process_Info_Array + 4*eax]

mov eax,[Param2]
stosd


Leave_System

ret











Get_Process_CR3:

; API Get_Process_CR3, Handle

; Handle = Process Handle
; return = CR3 Register of Process

Enter_System    28


; load the cr3 register from the table
movzx eax,word [Param1]
lea esi,[Process_Info_Array + 4*eax]
lodsd


Leave_System

ret

















; Virtual Address Space functions:
;    Set_Kernel_Memory
;    ?
;    
;    


;jmp dword Create_VAS
;jmp dword Destroy_VAS
;jmp dword Expand_VAS
;jmp dword System_VAS





Set_Kernel_Memory:

; API Set_Kernel_Memory, Address

; Address = physical address of the Memory Manager
; return = void

; enables paging, and sets the Kernel memory

;   stack
;    + Address
;    - Param1


%define Temp_Memory_size                   System_Var-32
%define Temp_Memory_Manager_Address        System_Var-36
%define Temp_Mem_Page_Table_#0             System_Var-40
%define Temp_Mem_Page_Table_#128           System_Var-44
%define Temp_Mem_Page_Table_#192           System_Var-48


; enter to a new API-like stack
pop ebx
pop eax
mov esp,101000h
push eax
sub esp,8
push ebx

Enter_System	48



; check the memory size
xor eax,eax
mov ecx,2*1024*1024*1024


Check_Memory_size:
; if ecx = 16 end loop
cmp ecx,16
je Check_Memory_size_Exit

add eax,ecx

mov [eax],dword 55AA77FFh
cmp [eax],dword 55AA77FFh
je Check_Memory_size_next

; else the memory is not available
sub eax,ecx
shr ecx,1
jmp Check_Memory_size

Check_Memory_size_next:
shr ecx,1
jmp Check_Memory_size


Check_Memory_size_Exit:
mov [Temp_Memory_size],eax




; the Kernel memory pages, direct after the Memory Manager
;    Page 0:  Page Directory for System
;    Page 1:  Page Table 0
;    Page 2:  Page Table 128
;    Page 3:  Page Table 192
;    512 KB: Memory Heap Tree



; set the Kernel memory
mov eax,[Param1]
mov [Temp_Memory_Manager_Address],eax
add eax,64*1024
mov ebx,eax

; store the link to the Page Table 0
add ebx,4096 + Page_TF_entry_S_g
mov [Temp_Mem_Page_Table_#0],ebx
mov [eax + 4*768 + 4*0],ebx

; store the link to the Page Table 128
add ebx,4096
mov [Temp_Mem_Page_Table_#128],ebx
mov [eax + 4*768 + 4*128],ebx

; store the link to the Page Table 192
add ebx,4096
mov [Temp_Mem_Page_Table_#192],ebx
mov [eax + 4*768 + 4*192],ebx


; map the GDT and the Paging Switcher
add eax,4096
mov [eax+4*16],dword 10000h + Page_TF_entry_S_g
mov [eax+4*256],dword 100000h + Page_TF_entry_S_g

; map the Memory Manager
add eax,4096
mov ebx,[Param1]
add ebx,Page_TF_entry_S_g
mov [eax+4*128],ebx

; map the Virtual Window Page Table
add eax,4096
mov [eax+4*128],eax


; map the Memory Heap Tree
sub eax,2*4096
add ebx,64*1024 + 4096
mov ecx,512*1024 / 4096

Link_Memory_Heap_Tree:
mov [eax],ebx
add eax,4
add ebx,4096
loop Link_Memory_Heap_Tree



; set the CR3
mov eax,[Param1]
add eax,64*1024
mov cr3,eax



; copy the Paging switcher to memory 100000h
mov esi,[Param1]
add esi,Memory_Manager_Switcher-Memory_Manager
mov edi,100000h
mov ecx,Memory_Manager_Switcher_ret - Memory_Manager_Switcher

rep movsb


; jump to the Paging Switcher
jmp dword Code_Selector:100000h



Memory_Manager_Switcher:
; the Paging switcher

; enable Paging
mov eax,cr0
or eax,80000000h
mov cr0,eax

; enable the Global Page Extension
mov eax,cr4
or eax,010000000b
mov cr4,eax

jmp dword Code_Selector:Memory_Manager_Switcher_ret


Memory_Manager_Switcher_ret:
; here, paging is activated



; copy the Temp variables back
mov eax,[Temp_Memory_size]
mov [Memory_size],eax
mov ebx,[Temp_Memory_Manager_Address]
mov [Memory_Manager_Address],ebx
mov ecx,[Temp_Mem_Page_Table_#0]
mov [Mem_Page_Table_#0],ecx
mov edx,[Temp_Mem_Page_Table_#128]
mov [Mem_Page_Table_#128],edx
mov esi,[Temp_Mem_Page_Table_#192]
mov [Mem_Page_Table_#192],esi



; Create the Memory Heap Tree
API Enable_Memory_Management, [Memory_size]



; Set the physical available Memory

; set the variables
mov [Heap_Tree],dword Memory_Heap_Tree
mov [Heap_Tree_descriptors],dword SMHs
mov [address],dword 0
m2m dword [Param1],dword [Memory_size]

; and call the sub function
call Set_Memory_block_internal



; preserve the memory of the Memory Manager
mov [Memory_Manager_Address],eax
m2m dword [address],dword [Memory_Manager_Address]
mov [Param1],dword 2*1024*1024
call Preserve_Memory_internal



; reserve the whole first MB
mov [address],dword 0
mov [Param1],dword 1024*1024
call Reserve_Memory_internal





; physical Kernel memory, 2048 KB
;   Memory Manager, 64 KB
;   Page 0 - 3, 16 KB
;   Memory Heap Tree, 512 KB
;   Kernel_NT_Emulator, 4 KB
;   Kernel stack, 16 KB
;   Task Table, 384 KB
;   Process Info Array, 128 KB
;   OS runtime info, 8 KB
;   Name Buffer, 8 KB
;   File Handles, 32 KB
;   TSS, 16 KB
;   TSS vm86, 16 KB
;   API Buffer (for System), 16 KB
;   Message Queue (for System), 16 KB
;   Main Heap Tree (for System), 16 KB


mov edx,[Memory_Manager_Address]
add edx,64*1024 + 16*1024 + 512*1024
or edx,Page_TF_entry_S_g





; physical lowlevel memory, starting at 10000h
;   GDT, 2 KB
;   IDT, 2 KB
;   IVT, 2 KB




; set the Kernel memory



; set the GDT, IDT and IVT
API Map_self_Memory, GDT, 10000h + Page_TF_entry_S_g, 2

; set the Kernel NT Emulator
API Map_self_Memory, Kernel_NT_Emulator, edx, 1
add edx,4*1024



; switch to the GDT and IDT (use the stack)
sub esp,6

; load the GDT Register
mov [esp],word GDT_Limit
mov [esp+02h],dword GDT
lgdt [esp]

; load the IDT Register
mov [esp],word IDT_Limit
mov [esp+02h],dword IDT
lidt [esp]

; restore the original stack pointer
add esp,6


jmp Code_Selector:Prefetch_Clear
Prefetch_Clear:



; set the BIOS Data Area, Data Area
API Map_self_Memory, BIOS_Data_Area, 0400h + Page_TF_entry_S_g, 1

; set the Extended BIOS Data Area
mov ebx,[BIOS_Data_Area + 0040Eh]
shl ebx,4
or ebx,Page_TF_entry_S_g
API Map_self_Memory, Extended_BIOS_Data_Area, ebx, 1



; set the VESA BIOS memorys
API Map_self_Memory, VESA_BIOS_A0000h, 0A0000h + Page_TF_entry_S_g, 64/4
API Map_self_Memory, VESA_BIOS_B0000h, 0B0000h + Page_TF_entry_S_g, 64/4
API Map_self_Memory, VESA_BIOS_B8000h, 0B8000h + Page_TF_entry_S_g, 32/4
API Map_self_Memory, VESA_BIOS_image, 0C0000h + Page_TF_entry_S_g, 32/4
API Map_self_Memory, Textmode_Buffer, 0B8000h + Page_TF_entry_S_g, 32/4



; set the Kernel data memory

; set the Kernel stack
leave
pop ecx
mov esp,[Memory_Manager_Address]
add esp,64*1024
API Map_self_Memory, Kernel_Stack - 16*1024, edx, 16/4
add edx,16*1024
mov esp,Kernel_Stack
push ecx

; set the Task Table
API Map_self_Memory, Task_Table, edx, 384/4
add edx,384*1024

; set the Process Info Array
API Map_self_Memory, Process_Info_Array, edx, 128/4
add edx,128*1024

; set the OS runtime info
API Map_self_Memory, OS_info, edx, 8/4
add edx,8*1024

; set the Name Buffer
API Map_self_Memory, Name_Buffer, edx, 8/4
add edx,8*1024

; set the File Handles
API Map_self_Memory, File_Handles, edx, 32/4
add edx,32*1024

; set the TSS
API Map_self_Memory, TSS, edx, 16/4
add edx,16*1024

; set the vm86 TSS
API Map_self_Memory, TSS_vm86, edx, 16/4
add edx,16*1024

mov [Last_Kernel_Memory],edx



; set the Kernel module code memory (at this time, dynamic!)

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, BIOS_wrapper, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Desktop_Viewer, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Drive_Manager, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Driver_model, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Error_Manager, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Execute_module, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Heap_Manager, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, IDT_Manager, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Security_Module, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, System_Loader, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Task_Switcher, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Timer, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, Utils, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, VESA_GDI, edx, 64/4

API New_Memory, 64*1024
mov edx,eax
API Map_self_Memory, VESA_GUI, edx, 64/4



; set the User Data Area

; create and set the Page Table #224
API New_self_Page_Table, Page_Table_#224, 1, Page_TF_entry_S
mov ebx,eax
API Map_self_Memory, Page_Table_#224, ebx, 1

; set the API Buffer
API Map_self_Memory, API_Buffer, [Last_Kernel_Memory], 16/4
add [Last_Kernel_Memory],dword 16*1024

; set the Message Queue
API Map_self_Memory, Message_Queue, [Last_Kernel_Memory], 16/4
add [Last_Kernel_Memory],dword 16*1024

; set the Kernel stack (stack lowercase!)
API Map_self_Memory, Kernel_stack, [Last_Kernel_Memory], 1
add [Last_Kernel_Memory],dword 4*1024

; set the Main Heap Tree
API Map_self_Memory, Main_Heap_Tree, [Last_Kernel_Memory], 16/4
add [Last_Kernel_Memory],dword 16*1024



; set the TSS (the Stacks in the TSS)
mov [TSS+24],dword 0
mov [TSS+20],dword 0
mov [TSS+16],dword 0
mov [TSS+12],dword 0

mov [TSS+8],word Data_Selector
mov [TSS+4],dword Kernel_stack + 4096



; set a system Process Handle
mov eax,cr3
API Set_Process_CR3, 0, eax



; It work !
;        S




; return = Memory size
mov eax,[Memory_size]

ret












Map_Memory:

; LAPI Map_Memory, linear Address, physical Address, pages

; physical Address = Page Base Address

Enter_System    28



; get the CR3 Register
API Get_Process_CR3, [Param4]
mov [Param4],eax



; set in the Virtual Window 1 the linear Address to the physical one
Map_Memory_l2p:

; link the Page Directory with the Virtual Window 1
mov eax,[Param4]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]

; link the Page Table with the Virtual Window 1
mov ebx,[Param1]
shr ebx,12+10
shl ebx,2
mov eax,[ebx + User_Window_1]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; set the Address of the Page Frame in the Virtual Window
Map_Memory_l2p_set:
mov ebx,[Param1]
add [Param1],dword 4096
shr ebx,12-2
and ebx,0FFCh

mov eax,[Param2]
add [Param2],dword 4096
mov [ebx + User_Window_1],eax
add ebx,4



; last page?
dec dword [Param3]
jz Map_Memory_Exits


; link the next table if neccesary
cmp ebx,4096
jne Map_Memory_l2p_set

; else map next Page Table
jmp Map_Memory_l2p



Map_Memory_Exits:
clc

Map_Memory_Exit:
Leave_System

ret












Map_self_Memory:

; LAPI Map_self_Memory, linear Address, physical Address, pages

; physical Address = Page Base Address

Enter_System    28


; set in the Virtual Window 1 the linear Address to the physical one
Map_self_Memory_l2p:

; link the Page Directory with the Virtual Window 1
mov eax,cr3
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]

; link the Page Table with the Virtual Window 1
mov ebx,[Param1]
shr ebx,12+10
shl ebx,2
mov eax,[ebx + User_Window_1]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; set the Address of the Page Frame in the Virtual Window
Map_self_Memory_l2p_set:
mov ebx,[Param1]
add [Param1],dword 4096
shr ebx,12-2
and ebx,0FFCh

mov eax,[Param2]
add [Param2],dword 4096
mov [ebx + User_Window_1],eax
add ebx,4



; last page?
dec dword [Param3]
jz Map_self_Memory_Exits


; link the next table if neccesary
cmp ebx,4096
jne Map_self_Memory_l2p_set

; else map next Page Table
jmp Map_self_Memory_l2p



Map_self_Memory_Exits:
clc

Map_self_Memory_Exit:
Leave_System

ret













New_Page_Table:

; LAPI New_Page_Table, linear Address, Tables, Attributes, Handle

Enter_System    28


; get the CR3 Register
API Get_Process_CR3, [Param4]
mov [Param4],eax


; link the Page Directory with the Virtual Window 1
mov eax,[Param4]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; get a new Page Table
Next_Page_Table:
API New_Memory, 4096, New_Page_Table_Exit

; link the Page Table in the Page Directory
or eax,[Param3]
mov ebx,[Param1]
shr ebx,12+10
shl ebx,2
mov [User_Window_1 + ebx],eax


; last Page Table?
add [Param1],dword 4*1024*1024
dec dword [Param2]
jnz Next_Page_Table

clc


New_Page_Table_Exit:
Leave_System

ret







New_self_Page_Table:

; LAPI New_Page_Table, linear Address, Tables, Attributes

Enter_System    28


; link the Page Directory with the Virtual Window 1
mov eax,cr3
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; get a new Page Table
Next_self_Page_Table:
API New_Memory, 4096, New_Page_Table_Exit

; link the Page Table in the Page Directory
or eax,[Param3]
mov ebx,[Param1]
shr ebx,12+10
shl ebx,2
mov [User_Window_1 + ebx],eax


; last Page Table?
add [Param1],dword 4*1024*1024
dec dword [Param2]
jnz Next_self_Page_Table

clc


Leave_System

ret












New_Page_Frame:

; LAPI New_Page_Frame, linear Address, Frames, Attributes, Handle

Enter_System    28


; get the CR3 Register
API Get_Process_CR3, [Param4]
mov [Param4],eax


New_Page_Frame_l2p:

; link the Page Directory with the Virtual Window 1
mov eax,[Param4]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]

; link the Page Table with the Virtual Window 1
mov ebx,[Param1]
shr ebx,12+10
shl ebx,2
mov eax,[ebx + User_Window_1]
and eax,0FFFFF000h
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; create the Page Frame within the Virtual Window 1
New_Page_Frame_l2p_set:
API New_Memory, 4096, New_Page_Frame_Exit
or eax,[Param3]
mov ebx,[Param1]
add [Param1],dword 4096
shr ebx,12-2
and ebx,0FFCh
mov [User_Window_1 + ebx],eax
add ebx,4


; last page?
dec dword [Param2]
jz New_Page_Frame_Exits


; create the next frame if neccesary
cmp ebx,4096
jne New_Page_Frame_l2p_set

; else map next Page Table
jmp New_Page_Frame_l2p


New_Page_Frame_Exits:
clc

New_Page_Frame_Exit:
Leave_System

ret












Create_VAS:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Create Virtual Address Space"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Create_VAS, size

;   size = size of user memory in bytes
;   return = Process Handle

%define Process_Handle                     System_Var-32
%define Page_Directory                     System_Var-32

Enter_System    32


; get a Process Handle
API Get_Process_Handle, Create_VAS_Exit
mov [Process_Handle],eax


; create the Page Directory
API New_Memory, 4096, Create_VAS_Exite

; link the CR3 with the Page Directory
mov [Page_Directory],eax
mov ebx,eax
or ebx,Page_TF_entry_U
API Set_Process_CR3, [Process_Handle], ebx


; link the System Page Tables
mov [Page_Table_#192 + 4],ebx
invlpg [User_Window_1]

mov eax,[Mem_Page_Table_#0]
mov [User_Window_1 + 4*768 + 4*0],eax
mov eax,[Mem_Page_Table_#128]
mov [User_Window_1 + 4*768 + 4*128],eax
mov eax,[Mem_Page_Table_#192]
mov [User_Window_1 + 4*768 + 4*192],eax



; create the User Memory

; create the Page Tables
mov ebx,[Param1]
shr ebx,22

API New_Page_Table, 0, ebx, Page_TF_entry_U, Create_VAS_Exite, [Process_Handle]


; create the Page Frames
mov ebx,[Param1]
shr ebx,12

API New_Page_Frame, 0, ebx, Page_TF_entry_U, Create_VAS_Exite, [Process_Handle]



Create_VAS_Exit:
mov eax,[Process_Handle]
Leave_System

clc
ret


Create_VAS_Exite:
API Destroy_VAS, [Process_Handle]
Leave_System

xor eax,eax
stc
ret











Expand_VAS:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Expand Virtual Address Space"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Expand_VAS, Handle, address, size

;   size = size of user memory in bytes started at address
;   may used on a Parity Error to preserve the physical pages!

Enter_System    28


; check the validity of the Handle
API Check_Process_Handle, [Param1], Expand_VAS_Exit


; create the Page Tables
mov ebx,[Param1]
add ebx,003FFFFFh
shr ebx,22

API New_Page_Table, [Param2], ebx, Page_TF_entry_U, [Param1]


; create the Page Frames
mov ebx,[Param1]
add ebx,4098
shr ebx,12

API New_Page_Frame, [Param2], ebx, Page_TF_entry_U, [Param1]


Expand_VAS_Exit:
Leave_System

ret










Destroy_VAS:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Destroy Virtual Address Space"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Destroy_VAS, Handle

;   Handle mustn't be Process(Sender).Handle!

Enter_System    28


; check the validity of the Handle
API Check_Process_Handle, [Param1], Destroy_VAS_Exit


; get the CR3 Register, and destroy the Handle
API Get_Process_CR3, [Param1]
push eax
API Set_Process_CR3, [Param1], 0
pop dword [Param1]




; link the Virtual Window 1 with the Page Directory
and eax,0FFFFF000h

; free the virtual Frame
or eax,eax
jz Destroy_VAS_Exit
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]




mov ecx,1024

Destroy_VAS_Page_Tables:

; link the Virtual Window 2 with the Page Table
mov eax,[4*ecx + User_Window_1]
and eax,0FFFFF000h

; free the virtual Frame
or eax,eax
jz Destroyed_VAS_Page_Tables
or eax,Page_TF_entry_S
mov [Page_Table_#192+2*4],eax
invlpg [User_Window_2]



    push ecx
    mov ecx,1024
    
    Destroy_VAS_Page_Frames:
    
      ; free the virtual Frame
      mov ebx,[4*ecx + User_Window_2]
      and ebx,0FFFFF000h
      or ebx,ebx
      jz Destroyed_VAS_Page_Frames
      
      ; free the physical Frame
      API Free_Memory, ebx
      
      Destroyed_VAS_Page_Frames:
    
    loop Destroy_VAS_Page_Frames
    
    pop ecx



; free the physical Frame
mov ebx,[4*ecx + User_Window_1]
and ebx,0FFFFF000h
API Free_Memory, ebx

Destroyed_VAS_Page_Tables:



loop Destroy_VAS_Page_Tables



; free the physical Frame
mov ebx,[Param1]
and ebx,0FFFFF000h
API Free_Memory, ebx





Destroy_VAS_Exit:
Leave_System

ret
















Create_System_VAS:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Create System Virtual Address Space"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Create_VAS, size

;   size = size of user memory in bytes
;   return = Process Handle

%define Process_Handle                     System_Var-32
%define Page_Directory                     System_Var-32

Enter_System    32


; get a Process Handle
API Get_Process_Handle, Create_VAS_Exit
mov [Process_Handle],eax


; create the Page Directory
API New_Memory, 4096, Create_VAS_Exite

; link the CR3 with the Page Directory
mov [Page_Directory],eax
mov ebx,eax
or ebx,Page_TF_entry_S
API Set_Process_CR3, [Process_Handle], ebx


; link the System Page Tables
mov [Page_Table_#192 + 4],ebx
invlpg [User_Window_1]

mov eax,[Mem_Page_Table_#0]
mov [User_Window_1 + 4*768 + 4*0],eax
mov eax,[Mem_Page_Table_#128]
mov [User_Window_1 + 4*768 + 4*128],eax
mov eax,[Mem_Page_Table_#192]
mov [User_Window_1 + 4*768 + 4*192],eax



; create the User Memory

; create the Page Tables
mov ebx,[Param1]
shr ebx,22

API New_Page_Table, 0, ebx, Page_TF_entry_S, Create_VAS_Exite, [Process_Handle]


; create the Page Frames
mov ebx,[Param1]
shr ebx,12

API New_Page_Frame, 0, ebx, Page_TF_entry_S, Create_VAS_Exite, [Process_Handle]



jmp Create_VAS_Exit












Expand_System_VAS:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Expand System Virtual Address Space"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Expand_VAS, Handle, address, size

;   size = size of user memory in bytes started at address
;   may used on a Parity Error to preserve the physical pages!

Enter_System    28


; check the validity of the Handle
API Check_Process_Handle, [Param1], Expand_VAS_Exit


; create the Page Tables
mov ebx,[Param1]
add ebx,003FFFFFh
shr ebx,22

API New_Page_Table, [Param2], ebx, Page_TF_entry_S, [Param1]


; create the Page Frames
mov ebx,[Param1]
add ebx,4098
shr ebx,12

API New_Page_Frame, [Param2], ebx, Page_TF_entry_S, [Param1]


jmp Expand_VAS_Exit













Copy_Process_Data:

; calling macro:	API
; user:			System
; stack size:		unknown
; heap size:		unknown
; Multitasking		n/u
; Multithreading	n/u
; name:			"Copy Data over different Virtual Address Spaces"
; date:			Wednesday, 25 October 2006
; autor:		Peter Kleissner
; publisher:		Vienna Computing

; style:
;   API Copy_Process_Data, Handle, Handle, Source, Destination, Size

;   Handle = source Process Handle
;   Handle = destination Process Handle
;   Source = source Address
;   Destination = destination Address
;   Size = size (in bytes) of the data to copy

Enter_System    28


; check the validity of the Handles
API Check_Process_Handle, [Param1], Copy_Process_Data_Exit
API Check_Process_Handle, [Param2], Copy_Process_Data_Exit


; link the Virtual Window 1 with the Page Directory of #1
API Get_Process_CR3, [Param1]
and eax,0FFFFF000h
or eax,eax
jz Copy_Process_Data_Exit
or eax,Page_TF_entry_S
mov [Page_Table_#192+1*4],eax
invlpg [User_Window_1]


; link the Virtual Window 2 with the Page Directory of #2
API Get_Process_CR3, [Param2]
and eax,0FFFFF000h
or eax,eax
jz Copy_Process_Data_Exit
or eax,Page_TF_entry_S
mov [Page_Table_#192+2*4],eax
invlpg [User_Window_2]



call Copy_Memory_Area



Copy_Process_Data_Exit:
Leave_System

ret












Copy_Memory_Area:


; link the Virtual Window 3 with the correct Page Table of #1
mov eax,[Param3]
shr eax,22
shl eax,2
mov ebx,[User_Window_1 + eax]
or ebx,Page_TF_entry_S
mov [Page_Table_#192+3*4],ebx
invlpg [User_Window_3]

; link the Virtual Window 3 with the correct Page Frame of #1
mov eax,[Param3]
shr eax,12-2
and eax,0FFCh
or eax,Page_TF_entry_S
mov ebx,[User_Window_3 + eax]
or ebx,Page_TF_entry_S
mov [Page_Table_#192+3*4],ebx
invlpg [User_Window_3]


; link the Virtual Window 4 with the correct Page Table of #2
mov eax,[Param4]
shr eax,22
shl eax,2
mov ebx,[User_Window_2 + eax]
or ebx,Page_TF_entry_S
mov [Page_Table_#192+4*4],ebx
invlpg [User_Window_4]

; link the Virtual Window 4 with the correct Page Frame of #2
mov eax,[Param4]
shr eax,12-2
and eax,0FFCh
or eax,Page_TF_entry_S
mov ebx,[User_Window_4 + eax]
or ebx,Page_TF_entry_S
mov [Page_Table_#192+4*4],ebx
invlpg [User_Window_4]



; copy 4096 - source.PageOffset or 4096 - destination.PageOffset, the less one
mov ecx,4096
mov esi,[Param3]
and esi,0FFFh
sub ecx,esi

mov ebx,4096
mov edi,[Param3]
and edi,0FFFh
sub ebx,edi

cmp ecx,ebx
jle Copy_Memory_Area_size
mov ecx,ebx
Copy_Memory_Area_size:


; copy eax or Param5 bytes, take the less one
cmp ecx,[Param5]
jle Copy_Memory_Area_size1
mov ecx,[Param5]
Copy_Memory_Area_size1:

sub [Param5],ecx


; copy the spanned data area
rep movsb


; if not zero, copy next data
cmp [Param5],dword 0
jne Copy_Memory_Area


ret



































; public variables
Mem_Page_Table_#0     dd        0	; data memory
Mem_Page_Table_#128   dd        0	; code memory
Mem_Page_Table_#192   dd        0	; Virtual Windows

Memory_size           dd        0

Memory_Manager_Address   dd        0

Last_Kernel_Memory    dd        0