⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memcode.inc

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 INC
📖 第 1 页 / 共 3 页
字号:
		PUSH EBX				;(save for caller)
		PUSH ECX				;
		PUSH EDX				;
		PUSH ESI				;
		PUSH EDI				;

		;This first section sets to make [ESI] point to first PT that
		;we have to move the other guy's physical pages into

		MOV ECX, EBX			;Copy number of pages to ECX (EBX free to use).
		MOV EDX, EAX			;LinAdd to EDX
		SHR EDX, 22				;Get index into PD for first PT
		SHL EDX, 2				;Make it index to DWORDS

		PUSH EAX				;Save EAX thru GetpCrntJCB call
		CALL GetpCrntJCB		;Leaves pCrntJCB in EAX
		MOV ESI, [EAX.JcbPD] 	;ESI now has linear address of PD
		POP EAX					;Restore linear address

		ADD ESI, 2048			;Offset to shadow addresses in PD
		ADD ESI, EDX			;ESI now points to first PT of interest

		MOV EDX, EAX			;LinAdd into EDX again
		AND EDX, 003FF000h		;get rid of upper 10 bits & lower 12
		SHR EDX, 10 			;Index into PD for PT (10 vice 12 -> DWORDS)
ALR0:
		MOV EDI, [ESI]			;Linear address of crnt page table into EDI

		;At this point, EDI is pointing to the PT we are in.
		;SO... EDI+EDX will point to the next PTE to do.
		;Now we must call LinToPhy with Linear Add & JobNum
		; to get a physical address into EAX.
		;This is the Physical address to store in the new PTE.  We must
		;mark it MEMALIAS before adding it to PT.
ALR1:
		PUSH ESI				;Save for next loop (used by LinToPhy)

		MOV EAX, AliasJob		;Job we are aliasing
		MOV EBX, AliasLin		;Address we are aliasing
		ADD AliasLin, 4096		;Set up for next loop (post increment)
		CALL LinToPhy			;

		;EAX now has physical address for this page
		;

		AND EAX, 0FFFFF000h		;cut off system bits of PTE
		OR EAX, MEMALIAS		;Set system bits as ALIAS

		POP	ESI					;Restore ESI (LinToPhy used it)

		;Now store it in new PTE

		MOV DWORD PTR [EDI+EDX], EAX	;EDX is index to exact entry

		DEC ECX					;Are we done??
		JZ ALRDone
		ADD EDX, 4				;Next PTE please...
		CMP EDX, 4096			;Are we past last PTE of this PT?
		JB ALR1					;No, go do next PTE
		ADD ESI, 4				;Yes, next PDE (to get next PT)
		XOR EDX,EDX				;Start at the entry 0 of next PT
		JMP SHORT ALR0			;
ALRDone:
		POP EDI				;
		POP ESI				;
		POP EDX				;
		POP ECX				;
		POP EBX				;

		MOV ESP,EBP             ;
		POP EBP                 ;
		RETN

;=============================================================================
; AddUserPT
; This creates a new User Page Table, initializes it and sticks it
; in the Users's PD (in User Address space above 1GB).
; This is easier than AddOSPT because there is no need to update
; anyone else's PDs!  This sets the protection on the PT to user
; Read & Write.  Individual PTEs will be set read only for code.
;
; IN :  Nothing
; OUT:  0 if OK or Error (ErcNoMem - no free phy pages!)
; USED: EAX, EFlags
;
AddUserPT:
		PUSH EBX				;(save for caller)
		PUSH ECX				;
		PUSH EDX				;
		PUSH ESI				;
		PUSH EDI				;

		MOV EAX, _nPagesFree	;See if have enuf physical memory
		OR EAX, EAX
		JNZ AUPT01
		MOV EAX, ErcNoMem		;Sorry, out of physical mem
		JMP AUPTDone
AUPT01:
		CALL GetCrntJobNum		;Leaves job num in EAX (for LinToPhy)
		MOV EBX, pNextPT		;Pre allocated Page (Linear Address)
		CALL LinToPhy			;EAX will have Physical address

		; Put it in the User PD (and linear in shadow).
		; Find first empty slot

		CALL GetpCrntJCB		;pJCB in EAX
		MOV EDI, JcbPD			;Offset to PcbPD in JCB
		ADD EDI, EAX			;EDI points to UserPD Address
		MOV ESI, [EDI]			;ESI now points to PD
		ADD ESI, 2048			;ESI now points to upper 1 GB in PD
		MOV ECX, 511			;Number of entries (at least 1 is already gone)
AUPT02:
		ADD ESI, 4				; Next possible empty entry
		MOV	EBX, [ESI]
		OR EBX, EBX 			; Is it empty?
		LOOPNZ AUPT02			; No! (Try again)

		; ESI now points to empty Slot
		; Physical Address of new table is still in EAX
		; Get Linear address back into EBX
		; and put them into PD

		OR  EAX, MEMUSERD		;Set user bits (Read/Write)
		MOV [ESI], EAX			;Physical address in lower half
		ADD ESI, 2048			;Move to shadow
		MOV EBX, pNextPT		;Linear add back into EBX
		MOV [ESI], EBX			;Put in Linear address of PT (upper half)

		;Now we now need another PreAllocated Page Table for
		;next time. Get a run of 1 for next new page table

		MOV EBX, 1				;size of request
		XOR EAX, EAX			;PD shadow offset needed by FindRun (0)
		CALL FindRun
		OR EAX, EAX				;was there an error (0 means no mem)
		JNZ AUPT05
		MOV EAX, ErcNoMem		;
		JMP SHORT AUPTDone
AUPT05:
		MOV pNextPT, EAX		;save pNextPT (the linear address)
		CALL AddRun				;AddRun will return NON-ZERO on error
AUPTDone:
		POP EDI				;
		POP ESI				;
		POP EDX				;
		POP ECX				;
		POP EBX				;
		RETN

;=============================================================================
; AddOSPT
; This creates a new OS Page Table, initializes it and sticks it
; in the OS's PD (in OS address space below 1GB).
; This also updates ALL PDs for ALL jobs.  We must do this
; to ensure the OS code can reach its memory no matter what JOB/TASK
; it is running in.
;
; IN :  Nothing
; OUT:  0 if OK or Error (ErcNoMem - no free phy pages!)
; USED: EAX, EFlags
;
AddOSPT:
		PUSH EBX				;(save for caller)
		PUSH ECX				;
		PUSH EDX				;
		PUSH ESI				;
		PUSH EDI				;

		MOV EAX, _nPagesFree	;See if have enuf physical memory
		OR EAX, EAX
		JNZ AOPT01
		MOV EAX, ErcNoMem		;Sorry, out of physical mem
		JMP AOPTDone
AOPT01:
		MOV EAX, 1				;OS Job Number (Monitor)
		MOV EBX, pNextPT		;Pre allocated Page (Linear Address)
		CALL LinToPhy			;EAX will have Physical address

		; Put it in the OS PD (and linear in shadow).
		; Find first empty slot

		MOV ESI, OFFSET PDir1	; ESI points to OS Pdir
		MOV ECX, 511			; Count of PDEs to check
AOPT02:
		ADD ESI, 4				; Next possible empty entry
		MOV EBX, [ESI]
		OR EBX, EBX				; Is it empty?
		LOOPNZ AOPT02			; No! (Try again)

		; ESI now points to empty PDir Slot
		; EAX still has Physical Address of new table
		; Get Physical Address back into EBX
		; and put them into PDir

		OR EAX, PRSNTBIT		;Set present bit
		MOV [ESI], EAX			;Physical address in lower half
		ADD ESI, 2048			;Move to shadow
		MOV EBX, pNextPT		;Linear add back into EBX
		MOV [ESI], EBX			;Put in Linear address of PT (upper half)

		; Update ALL PDs from PDir1 !!
		; This doesn't happen often if it happens at all.
		; The OS will usually not take 4 MBs even with ALL
		; of its dynamic structures (except on
		; a 32 Mb system or larger and when fully loaded)

		MOV EDX, nJCBs			; # of dynamic JCBs
AOPT03:
		MOV EAX, EDX			;Next JCB
		CALL GetpJCB			;EAX now has pointer to a job's PD
		MOV ECX, [EAX.JcbPD]	;See if PD id zero (Inactive JCB)
		OR ECX, ECX				;Is it a valid Job? (0 if not)
		JZ AOPT04				;No, Not a valid JCB (unused)

		ADD EAX, JcbPD			;EAX NOW points to PD of JCB
		MOV EBX, OFFSET PDir1	;Source of Copy

		PUSH EDX				;Save nJCB we are on

		PUSH EAX				;Save values on stack
		PUSH EBX

		PUSH EBX				;Source
		PUSH EAX				;Destination
		PUSH 1024				;Lower half of PD (Physical Adds)
		CALL FAR PTR _CopyData

		POP  EBX				;Get values from stack
		POP  EAX

		ADD EBX, 2048			;Move to shadow
		PUSH EBX
		ADD EAX, 2048			;Move to shadow
		PUSH EAX
		PUSH 1024				;Upper half of PD (Linear Adds)
		CALL FAR PTR _CopyData

		POP EDX					; Get back JCB number

AOPT04:
		DEC EDX
		CMP EDX, 2
		JA AOPT03				;Jobs 1 & 2 use PDir1 (Mon & Debugger)

		;At this point the new table is valid to ALL jobs!
		;We now need another PreAllocated Page Table for
		;next time. Get a run of 1 for next new page table

		MOV EBX, 1				;size of request
		XOR EAX, EAX			;PD shadow offset needed by FindRun (0)
		CALL FindRun
		OR EAX, EAX				;was there an error (0 means no mem)
		JNZ AOPT05
		MOV EAX, ErcNoMem		;
		JMP SHORT AOPTDone
AOPT05:
		MOV pNextPT, EAX		;save pNextPT (the linear address)
		CALL AddRun				;AddRun
		XOR EAX, EAX			;Set ErcOK (0)
AOPTDone:
		POP EDI				;
		POP ESI				;
		POP EDX				;
		POP ECX				;
		POP EBX				;
		RETN

;=============================================================================
; GetGDTDesc
; You supply the GDT selector in BX and this puts entry in EAX,EDX.
; EAX, EBX and EDX are used.
; This assumes that the PUBLIC Variable GDTbase has been filled in by
; the OS using SGDT after it went PMode.
; Used by the Debugger among other things...
;
GetGDTDesc:
		AND EBX,0000FFF8h       ;Mask any left overs (hi word)
		ADD EBX,GDTBase         ;Add to GDT base
		MOV EAX,[EBX]
		MOV EDX,[EBX+4]
		RETN


;=============================================================================
;=============================================================================
;  BEGIN PUBLIC CALL DEFINITION FOR MEMORY MANAGEMENT
;=============================================================================
;=============================================================================
; PUBLIC calls (far through call gates)
; AddCallGate   - Adds a public CallGate to the GDT
; AddIDTGate    - Adds an Interrupt Vector to the IDT
; AllocPage     - Returns a ptr for allocated memory pages (Hi Phys)
; AllocOSPage   - Returns a ptr with linear memory pages
; AllocDMAPage  - Returns a ptr with physical and linear memory pages
; AliasMem		- Aliases a memory address from one Job to another
; DeAllocPage   - Provided with ptr, deallocates memory pages
; QueryMemPages - Tells you how many pages are left free
; GetPhyAdd		- Returns the Physical Address for a Linear Address
;=============================================================================
; AddGDTCallGate will build and add a GDT entry for a call gate allowing
; access to OS procedures. This call doesn't check to see if the GDT
; descriptor for the call is already defined. It assumes you know what you
; are doing and overwrites one if already defined.  The Selector number is
; checked to make sure you're in range (40h thru max call gate num).
;
; IN: AX - Word with Call Gate ID type as follows:
;
;			DPL entry of 3 EC0x   (most likely)
;			DPL entry of 2 CC0x   (Not used in MMURTL)
;			DPL entry of 1 AC0x   (Not used in MMURTL)
;			DPL entry of 0 8C0x   (OS call ONLY)
;			(x = count of DWord params 0-F)
;
;     CX    Selector number for call gate in GDT (constants!)
;	  ESI	Offset of entry point in segment of code to execute
;
; OUT:  EAX	Returns Errors, else 0 if all's well
;
; USES: EAX, EBX, ECX, ESI, EFLAGS

_AddCallGate PROC FAR
		CMP CX, 40h 		;Is number within range of callgates?
		JAE AddCG01			;not too low...
		MOV EAX, ercBadGateNum
		RETF
AddCG01:
		MOVZX EBX, CX
		SUB EBX, 40			;sub call gate base selector
		SHR EBX, 3			;make index vice selector
		CMP EBX, nCallGates	;see if too high!
		JBE AddCG02			;No...
		MOV EAX, ercBadGateNum	;Yes...
		RETF
AddCG02:
		MOVZX EBX, CX		;Extend selector into EBX
		ADD EBX, GDTBase	;NOW a true offset in GDT
		MOV WORD PTR [EBX+02], 8	;Put Code Seg selector into Call gate
		MOV [EBX], SI		;0:15 of call offset
		SHR ESI, 16			;move upper 16 of offset into SI
		MOV [EBX+06], SI	;16:31 of call offset
		MOV [EBX+04], AX	;call DPL & ndParams
		XOR EAX, EAX		;0 = No Error
		RETF
_AddCallGate ENDP

;=============================================================================
; AddIDTGate will build and add an IDT Trap, Interrupt, or Task Gate.
; The Selector of the call is Always 8 for Int or Trap, and is the
; TSS of the task for a Task gate.
;
; IN:	AX	- Word with Gate ID type as follows:
;				Trap Gate with DPL of 3       8F00
;				Interrupt Gate with DPL of 3  8E00
;				Task Gate with DPL of 3       8500
;
;		BX	- Selector of gate (08 or TSS selector for task gates)
;
;		CX	- Word with Interrupt Number (00-FF)
;
;		ESI - Offset of entry point in OS code to execute
;			  (THIS MUST BE 0 FOR TASK GATES)
;
; USES: EAX, EBX, ECX, EDX, ESI, EFLAGS

_AddIDTGate PROC FAR
		MOVZX EDX, CX				;Extend INT Num into EDX
		SHL EDX, 3					;Gates are 8 bytes each (times 8)
		ADD EDX, OFFSET IDT			;EDX now points to gate
		MOV WORD PTR [EDX+4], AX	;Put Gate ID into gate
		MOV EAX, ESI
		MOV WORD PTR [EDX], AX		;Put Offset 15:00 into gate
		SHR EAX, 16
		MOV WORD PTR [EDX+6], AX	;Put Offset 31:16 into gate
		MOV WORD PTR [EDX+2], BX	;Put in the selector
		RETF
_AddIDTGate ENDP
;
;
;=============================================================================
; AllocOSPage --
; This allocates one or more pages of physical memory and returns a
; linear pointer to one or more pages of contiguous memory in the OS space.
; A result code is returned in the EAX register.
; STEPS:
; 1) See if we have enough physical memory (check nPagesFree)
; 2) Find a contiguous run of linear pages to allocate (PTEs)
; 3) Allocate each physical page placing it in the run of PTEs
;
; We search thru the page tables for the current job and find enough
; contiguous PTEs to satisfy the request.  If the current PT doesn't have
; enough contiguous entries, we add another page table to the OS PD
; and get them from the new one and the old one (i.e., the run may
; span page tables).
;
; Procedureal Interface :
;
;   AllocOSPage(dn4KPages,ppMemRet): dError
;
;   dn4KPages is a DWORD (4 BYTES). This is the number of contigous pages
;	to be allocated.
;
;   ppMemRet points to the pointer where the address of the
;			new linear memory is returned.
;
n4KPages	EQU [EBP+10h]		;These equates are also used by AllocPage
ppMemRet 	EQU [EBP+0Ch]		;

_AllocOSPage PROC FAR           ;
		PUSH EBP                ;
		MOV EBP,ESP             ;
		PUSH MemExch			;Wait at the MemExch for Msg
		MOV EAX, pRunTSS		;Put Msg in callers TSS Message Area
		ADD EAX, TSS_Msg
		PUSH EAX
		CALL FAR PTR _WaitMsg
		CMP EAX,0h				;Kernel Error??
		JNE SHORT ALOSPExit     ;Yes! Serious problem...

		MOV EAX,n4KPages		;size of request
		OR  EAX,EAX				;More than 0?
		JNZ ALOSP00				;Yes
		MOV EAX,ercBadMemReq    ;Can't be zero!
		JMP ALOSPExit           ;
ALOSP00:
		CMP EAX, _nPagesFree	;See if have enuf physical memory
		JBE ALOSP01				;Yes
		MOV EAX, ErcNoMem		;Sorry boss, we're maxed out
		JMP SHORT ALOSPExit
ALOSP01:
		MOV EBX,n4KPages		;size of request
		XOR EAX, EAX			;PD shadow offset needed by FindRun (0)
		CALL FindRun
		OR EAX, EAX				;(0 = No Runs big enuf)
		JNZ SHORT ALOSP02		;No Error!

		;If we didn't find a run big enuf we add a page table

		CALL AddOSPT			;Add a new page table (we need it!)
		OR EAX, EAX				;See if it's 0 (0 = NO Error)
		JZ SHORT ALOSP01		;Go back & try again
		JMP SHORT ALOSPExit		;ERROR!!
ALOSP02:
								;EAX now has linear address
								;EBX still has count of pages

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -