; **********************************************************
; 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