📄 _vflat.asm
字号:
cprocstart InstallBankFunc
ARG codeLen:UINT, bankFunc:DPTR
enter_c
mov esi,[bankFunc] ; Copy the code into buffer
mov edi,offset BankFuncBuf
mov ecx,[codeLen]
rep movsb
mov [BYTE edi],0C3h ; Terminate the function with a near ret
leave_c
ret
cprocend
;----------------------------------------------------------------------------
; int InitPaging(void)
;----------------------------------------------------------------------------
; Initializes paging system. If paging is not enabled, builds a page table
; directory and page tables for physical memory
;
; Exit: 0 - Successful
; -1 - Couldn't initialize paging mechanism
;----------------------------------------------------------------------------
cprocstart InitPaging
push ebx
push ecx
push edx
push esi
push edi
; Are we running under CauseWay?
mov ax,0FFF9h
int 31h
jc @@NotCauseway
cmp ecx,"CAUS"
jnz @@NotCauseway
cmp edx,"EWAY"
jnz @@NotCauseway
mov [BOOL VF_haveCauseWay],1
mov [CauseWayDIRLinear],esi
mov [CauseWay1stLinear],edi
; Check for DPMI
mov ax,0ff00h
push es
int 31h
pop es
shr edi,2
and edi,3
cmp edi,2
jz @@ErrExit ; Not supported under DPMI
mov eax,[CauseWayDIRLinear]
jmp @@CopyCR3
@@NotCauseway:
mov ax,cs
test ax,3 ; Which ring are we running
jnz @@ErrExit ; Needs zero ring to access
; page tables (CR3)
mov eax,cr0 ; Load CR0
test eax,80000000h ; Is paging enabled?
jz @@ErrExit ; No, we must have paging!
mov eax,cr3 ; Load directory address
and eax,0FFFFF000h
@@CopyCR3:
mov [PDBR],eax ; Save it
mov esi,eax
mov edi,offset pageDirectory
mov ecx,1024
cld
rep movsd ; Copy the original page table directory
cmp [DWORD accessPageAddr],0; Check if we have allocated page
jne @@HaveRealMem ; table already (we cant free it)
mov eax,0100h ; DPMI DOS allocate
mov ebx,8192/16
int 31h ; Allocate 8192 bytes
and eax,0FFFFh
shl eax,4 ; EAX points to newly allocated memory
add eax,4095
and eax,0FFFFF000h ; Page align
mov [accessPageAddr],eax
@@HaveRealMem:
mov eax,[accessPageAddr] ; EAX -> page table in 1st Mb
shr eax,12
and eax,3FFh ; Page table offset
shl eax,2
cmp [BOOL VF_haveCauseWay],0
jz @@NotCW0
mov ebx,[CauseWay1stLinear]
jmp @@Put1st
@@NotCW0:
mov ebx,[PDBR]
mov ebx,[ebx]
and ebx,0FFFFF000h ; Page table for 1st megabyte
@@Put1st:
add eax,ebx
mov [accessPageTable],eax
sub eax,eax ; No error
jmp @@Exit
@@ErrExit:
mov eax,-1
@@Exit: pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
cprocend
;----------------------------------------------------------------------------
; void ClosePaging(void)
;----------------------------------------------------------------------------
; Closes the paging system
;----------------------------------------------------------------------------
cprocstart ClosePaging
push eax
push ecx
push edx
push esi
push edi
mov eax,[accessPageAddr]
call AccessPage ; Restore AccessPage mapping
mov edi,[PDBR]
mov esi,offset pageDirectory
mov ecx,1024
cld
rep movsd ; Restore the original page table directory
@@Exit: pop edi
pop esi
pop edx
pop ecx
pop eax
ret
cprocend
;----------------------------------------------------------------------------
; long AccessPage(long phys)
;----------------------------------------------------------------------------
; Maps a known page to given physical memory
; Entry: EAX - Physical memory
; Exit: EAX - Linear memory address of mapped phys mem
;----------------------------------------------------------------------------
cprocstatic AccessPage
push edx
mov edx,[accessPageTable]
or eax,7
mov [edx],eax
mov eax,cr3
mov cr3,eax ; Update page table cache
mov eax,[accessPageAddr]
pop edx
ret
cprocend
;----------------------------------------------------------------------------
; long GetPhysicalAddress(long linear)
;----------------------------------------------------------------------------
; Returns the physical address of linear address
; Entry: EAX - Linear address to convert
; Exit: EAX - Physical address
;----------------------------------------------------------------------------
cprocstatic GetPhysicalAddress
push ebx
push edx
mov edx,eax
shr edx,22 ; EDX is the directory offset
mov ebx,[PDBR]
mov edx,[edx*4+ebx] ; Load page table address
push eax
mov eax,edx
call AccessPage ; Access the page table
mov edx,eax
pop eax
shr eax,12
and eax,03FFh ; EAX offset into page table
mov eax,[edx+eax*4] ; Load physical address
and eax,0FFFFF000h
pop edx
pop ebx
ret
cprocend
;----------------------------------------------------------------------------
; void CreatePageTable(long pageDEntry)
;----------------------------------------------------------------------------
; Creates a page table for specific address (4MB)
; Entry: EAX - Page directory entry (top 10-bits of address)
;----------------------------------------------------------------------------
cprocstatic CreatePageTable
push ebx
push ecx
push edx
push edi
mov ebx,eax ; Save address
mov eax,8192
push eax
call VF_malloc ; Allocate page table directory
add esp,4
add eax,0FFFh
and eax,0FFFFF000h ; Page align (4KB)
mov edi,eax ; Save page table linear address
sub eax,eax ; Fill with zero
mov ecx,1024
cld
rep stosd ; Clear page table
sub edi,4096
mov eax,edi
call GetPhysicalAddress
mov edx,[PDBR]
or eax,7 ; Present/write/user bit
mov [edx+ebx*4],eax ; Save physical address into page directory
mov eax,cr3
mov cr3,eax ; Update page table cache
pop edi
pop edx
pop ecx
pop ebx
ret
cprocend
;----------------------------------------------------------------------------
; void MapPhysical2Linear(ulong pAddr, ulong lAddr, int pages, int flags);
;----------------------------------------------------------------------------
; Maps physical memory into linear memory
; Entry: pAddr - Physical address
; lAddr - Linear address
; pages - Number of 4K pages to map
; flags - Page flags
; bit 0 = present
; bit 1 = Read(0)/Write(1)
;----------------------------------------------------------------------------
cprocstart MapPhysical2Linear
ARG pAddr:ULONG, lAddr:ULONG, pages:UINT, pflags:UINT
enter_c
and [ULONG pAddr],0FFFFF000h; Page boundary
and [ULONG lAddr],0FFFFF000h; Page boundary
mov ecx,[pflags]
and ecx,11b ; Just two bits
or ecx,100b ; Supervisor bit
mov [pflags],ecx
mov edx,[lAddr]
shr edx,22 ; EDX = Directory
mov esi,[PDBR]
mov edi,[pages] ; EDI page count
mov ebx,[lAddr]
@@CreateLoop:
mov ecx,[esi+edx*4] ; Load page table address
test ecx,1 ; Is it present?
jnz @@TableOK
mov eax,edx
call CreatePageTable ; Create a page table
@@TableOK:
mov eax,ebx
shr eax,12
and eax,3FFh
sub eax,1024
neg eax ; EAX = page count in this table
inc edx ; Next table
mov ebx,0 ; Next time we'll map 1K pages
sub edi,eax ; Subtract mapped pages from page count
jns @@CreateLoop ; Create more tables if necessary
mov ecx,[pages] ; ECX = Page count
mov esi,[lAddr]
shr esi,12 ; Offset part isn't needed
mov edi,[pAddr]
@@MappingLoop:
mov eax,esi
shr eax,10 ; EAX = offset to page directory
mov ebx,[PDBR]
mov eax,[eax*4+ebx] ; EAX = page table address
call AccessPage
mov ebx,esi
and ebx,3FFh ; EBX = offset to page table
mov edx,edi
add edi,4096 ; Next physical address
inc esi ; Next linear page
or edx,[pflags] ; Update flags...
mov [eax+ebx*4],edx ; Store page table entry
loop @@MappingLoop
mov eax,cr3
mov cr3,eax ; Update page table cache
leave_c
ret
cprocend
endcodeseg _vflat
endif
END ; End of module
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -