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