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

📄 kernel.inc

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 INC
📖 第 1 页 / 共 4 页
字号:
		;This will involve aliasing the pointers in the RqBlk
		;This must done before we start building and using user PDs

Chk04:
        MOV EBX,[EAX.DataLo]    ; Get pLB^.Data into ECX:EBX
		MOV ECX,[EAX.DataHi]    ;
		MOV EDX,pCkMessage		; Get Storage Addr in EDX
		MOV [EDX],EBX        	; Put pLB^.Data in specified
		MOV [EDX+4],ECX			; memory space (EDX)

		;Return the LB to the pool
		MOV EBX,pFreeLB         ; pLBin^.Next <= pFreeLB;
		MOV [EAX.NextLB],EBX    ;
		MOV pFreeLB,EAX         ; pFreeLB <= pLBin;
		INC _nLBLeft			;
		STI                     ;

		MOV EAX,ercOk           ;
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 8					;
_CheckMsg ENDP


;====================================================================
; NewTask --- OS PUBLIC - Creates a new task and schedules it for execution.
; used primarily to create a task for a job other than the one you are in.
; The OS uses this to create the initial task for a newly loaded job.
;
; The OS stacks are preallocated as part of the TSS.  If this is an OS
; task (CodeSeg = 8) then we load the TSS Stack into TSS_ESP and
; TSS_ESP0, otherwise we take the ESP param and place it into TSS_ESP.
;
;  Procedural interface:
;
;	NewTask(JobNum, CodeSeg, Priority, fDebug, Exch, ESP, EIP): dErcRet
;
;
NTS_Job		EQU [EBP+36]		;Job Num for this task
NTS_CS		EQU [EBP+32]		;8 for OS, 18h for user task
NTS_Pri		EQU [EBP+28]		;Priority of this task
NTS_fDbg	EQU [EBP+24]		;TRUE for DEBUGing
NTS_Exch	EQU [EBP+20]		;Exchange for TSS
NTS_ESP		EQU [EBP+16]		;Initial stack pointer
NTS_EIP		EQU [EBP+12]		;Task start address

_NewTask PROC FAR                   ;
		PUSH EBP                    ;
		MOV EBP,ESP                 ;

        MOV EDX, NTS_Pri			;
		CMP EDX, nPRI-1   			;Priority OK?
		JBE NT0000
		MOV EAX,ercBadPriority
		JMP NTEnd
NT0000:
		MOV ECX, NTS_Exch
        CMP ECX, nExch 				;Exch in range?
		JBE NT0001
		MOV EAX,ercOutOfRange
		JMP NTEnd
NT0001:
		CLI                     ;we can't be interrupted
		MOV EAX,pFreeTSS        ; NewTSS <= pFreeTSS;
		OR EAX,EAX              ; IF pFreeTSS=NIL THEN Return;
		JNZ NT0002              ;
		MOV EAX,ercNoMoreTSSs       ;No...
		JMP NTEnd
NT0002:
		MOV EBX,[EAX.NextTSS]   ; pFreeTSS <= pFreeTSS^.Next
		MOV pFreeTSS,EBX        ;
		DEC _nTSSLeft			;
		STI

		;EAX now has pNewTSS

		MOV [EAX.Priority],DL       ;put Priority into TSS
		MOV [EAX.TSS_EFlags],0202h  ;Load the Flags Register
		MOV [EAX.TSS_Exch], ECX		;Put new Exch in TSS (ECX is free)
		MOV EBX, NTS_EIP			;mov EIP into TSS (Start Address)
		MOV [EAX.TSS_EIP],EBX
		MOV EBX, NTS_ESP			;mov ESP into TSS
		MOV [EAX.TSS_ESP],EBX
		MOV [EAX.TSS_ESP0],EBX		;
		MOV ECX, NTS_CS				;mov CS into TSS
		MOV [EAX.TSS_CS],CX

		PUSH EAX					;Save pNewTSS

		;Now we get pJCB from JobNum they passed in so we can
		;get the PD from the JCB

		MOV EAX, NTS_Job			;Set up to call GetpJCB
		CALL GetpJCB				;EAX now has pJCB
		MOV ECX, EAX				;ECX now has pJCB

		POP EAX						;Restore pNewTSS to EAX

		MOV [EAX.TSS_pJCB],ECX		;Put pJCB into TSS
		MOV EBX, [ECX.JcbPD]        ;Set up to call LinToPhy

		PUSH EAX					;Save pNewTSS again

		MOV EAX, NTS_Job			;
		CALL LinToPhy				;Get Physical Address for PD into EAX
		MOV EBX, EAX
		POP EAX						;pNewTSS into EAX
		MOV [EAX.TSS_CR3],EBX		;Put Physical Add for PD into TSS_CR3
		CMP DWORD PTR NTS_fDbg, 0	;Debug on entry?
		JE NT0004                   ;No
		MOV [EAX.TSS_TrapBit],1h    ;Yes
NT0004:

		MOV EBX, NTS_Pri			;Get priority of new task

		CLI                         ;We can't be interrupted
		MOV EDX,pRunTSS             ;Get who's running
		CMP [EDX.Priority],BL       ;Who got the highest Pri?
		JA NT0005                   ;New guy does (lowest num)
		CALL enQueueRdy             ;Just put new guy on the ReadyQue (EAX)
		XOR EAX,EAX                 ;ercOk
		JMP NTEnd                   ;Return to caller
NT0005:
        XCHG EAX,EDX                ;CrntTSS -> EAX, New TSS -> EDX
        PUSH EDX					;Save New TSS
		CALL enQueueRdy             ;
		POP EAX						;New TSS -> EAX
		MOV pRunTSS,EAX             ;Move new TSS into pRunTSS
		MOV BX,[EAX.Tid]            ;Put Selector/Offset in "TSS"
		MOV TSS_Sel,BX              ;
		INC _nSwitches
		JMP FWORD PTR [TSS]         ;Jump to new TSS
		XOR EAX,EAX                 ;ErcOk
NTEnd:
		STI                         ;
		MOV ESP,EBP                 ;
		POP EBP                     ;
		RETF 28						;
_NewTask ENDP

;====================================================================
; SpawnTask --- OS PUBLIC - Creates a new task in the current job
; and schedules it for execution
;
; Procedural Interface:
; SpawnTask(pEntry,	dPriority, fDebug, pStack, fOSCode);
;
;
pEntryST	EQU DWORD PTR [EBP+28]
dPriST		EQU DWORD PTR [EBP+24]
fDebugST	EQU DWORD PTR [EBP+20]
pStackST	EQU DWORD PTR [EBP+16]
fOSCodeST	EQU DWORD PTR [EBP+12]

NewExchST	EQU DWORD PTR [EBP-4]
NewTSSST	EQU DWORD PTR [EBP-8]

_SpawnTask PROC FAR                 ;
		PUSH EBP                    ;
		MOV EBP,ESP                 ;
		SUB ESP, 8					;two local DWORD vars
		CMP dPriST, nPRI-1			;Priority OK?
		JBE ST0001
		MOV EAX,ercBadPriority
		JMP STEnd
ST0001:
		LEA EAX, NewExchST			;Allocate exchange
		PUSH EAX
		CALL FAR PTR _AllocExch
		OR EAX, EAX					;see if we got an error
		JNZ STEnd					;Yup, bad news

		;Allocate a new TSS
		CLI                     ;we can't be interrupted
		MOV EAX,pFreeTSS        ; NewTSS <= pFreeTSS;
		OR EAX,EAX              ; IF pFreeTSS=NIL THEN Return;
		JNZ ST0002              ;
		STI

		;Dealloc Exch if we didn't get a TSS
		PUSH NewExchST
		CALL FAR PTR _DeAllocExch
		MOV EAX,ercNoMoreTSSs       ;No...
		JMP NTEnd
ST0002:
		MOV EBX,[EAX.NextTSS]   ; pFreeTSS <= pFreeTSS^.Next
		MOV pFreeTSS,EBX        ;
		DEC _nTSSLeft			;
		STI

		MOV NewTSSST, EAX			;Save new TSS
        MOV EBX, NewExchST			;mov exch into TSS
		MOV [EAX.TSS_Exch],EBX
		MOV [EAX.TSS_CS], OSCodeSel	;Defaults to OS code selector
		CMP fOSCodeST, 0
		JNE ST0003
		MOV [EAX.TSS_CS], JobCodeSel	;Make OS code selector
ST0003:
		MOV EBX,pEntryST			;mov EIP into TSS
		MOV [EAX.TSS_EIP],EBX
		MOV EBX, pStackST			;mov ESP into TSS
		MOV [EAX.TSS_ESP],EBX
		MOV [EAX.TSS_ESP0],EBX
		MOV EBX, pRunTSS
		MOV EDX, [EBX.TSS_pJCB]		;Get pJCB from Crnt Task
		MOV [EAX.TSS_pJCB],EDX
		MOV EDX, [EBX.TSS_CR3]		;Get CR3 from crnt task
		MOV [EAX.TSS_CR3],EDX		; move into new TSS
		MOV [EAX.TSS_EFlags],0202h  ;Load the Flags Register
		CMP fDebugST, 0				;Debug on entry?
		JE ST0004                   ;No
		MOV [EAX.TSS_TrapBit],1h    ;Yes
ST0004:
        MOV EBX, dPriST				;mov priority into BL
		MOV [EAX.Priority],BL       ;put in TSS

		CLI                         ;we can't be interrupted
		MOV EDX,pRunTSS             ;Get who's running
		CMP [EDX.Priority],BL       ;Who got the highest Pri?
		JA ST0005                   ;If crnt >, New guy does (lowest num)
		CALL enQueueRdy             ;Old guy does, just put new guy on Q.
		XOR EAX,EAX                 ;ercOk
		JMP STEnd                   ;Return to caller
ST0005:
        XCHG EAX,EDX                ;CrntTSS -> EAX, New TSS -> EDX
        PUSH EDX					;New TSS -> Stack
		CALL enQueueRdy             ;Place crnt TSS on Q
		POP EAX						;New TSS -> EAX
		MOV pRunTSS,EAX             ;Move new TSS into pRunTSS
		MOV BX,[EAX.Tid]            ;Put Selector/Offset in "TSS"
		MOV TSS_Sel,BX              ;
		INC _nSwitches
		JMP FWORD PTR [TSS]         ;Jump to new TSS
		XOR EAX,EAX                 ;ErcOk
STEnd:
		STI                         ;
		MOV ESP,EBP                 ;
		POP EBP                     ;
		RETF 20						;
_SpawnTask ENDP

;=============================================================================
;
; AllocExch - The kernel Allocate Exchange primitive. This procedure
; provides access to the operating system by allowing a TASK to
; allocate a message port for the transmission and reception of messages from
; another process.
;
; Procedural Interface :
;
;       AllocExch(pExchRet):dError
;
;          pExchRet is a pointer to where you want the Exchange Handle
;          returned.  The Exchange Handle is a DWORD (4 BYTES).
;
;=============================================================================

_AllocExch PROC FAR             ;
		PUSH EBP                ;
		MOV EBP,ESP             ;

		XOR ESI,ESI             ; Zero the Exch Index
		MOV EBX,prgExch         ; EBX <= ADR rgExch
		MOV ECX,nExch           ; Get number of exchanges in ECX
AE000:
		CLI                     ;
		CMP [EBX.Owner],NIL     ; Is this exchange free to use
		JE AE001                ; If we found a Free Exch, JUMP
		ADD EBX,sEXCH           ; Point to the next Exchange
		INC ESI                 ; Increment the Exchange Index
		LOOP AE000              ; Keep looping until we are done
		STI                     ;
		MOV EAX,ercNoMoreExch   ; There are no instances of the
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 4                  ;

AE001:
		MOV EDX,[EBP+0CH]       ; Get the pExchRet in EDX
		MOV [EDX],ESI			; Put Index of Exch at pExchRet
		MOV EDX,pRunTSS         ; Get pRunTSS in EDX
		MOV EAX,[EDX.TSS_pJCB]  ; Get the pJCB in EAX
		MOV [EBX.Owner],EAX     ; Make the Exch owner the Job
		STI                     ;
		MOV [EBX.EHead],NIL   	; Make the msg/TSS queue NIL
		MOV [EBX.ETail],NIL   	;
		DEC _nEXCHLeft			; Stats
		MOV EAX,ercOk           ;
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 4                  ;

_AllocExch	ENDP

;=============================================================================
;
; DeAllocExch - The kernel DeAllocate Exchange primitive. It allows a TASK
; to deallocate a "message port."  It also deQueues any messages, and frees
; up any Link Blocks attached to the exchange.
;
; Procedural Interface :
;
;       DeAllocExch(Exch):ercType
;
;           Exch is the Exchange Handle the process is asking to be released.
;
;=============================================================================
;
; DeAllocExch - The kernel DeAllocate Exchange primitive. It allows a TASK
; to deallocate a "message port."  It also deQueues any messages, and frees
; up any Link Blocks, TSSs, and RQBs, attached to the exchange
;
; Procedural Interface :
;
;       DeAllocExch(Exch):ercType
;
;           Exch is the Exchange Handle the process is asking to be released.
;
;=============================================================================

_DeAllocExch   PROC FAR                ;
		PUSH EBP                ;
		MOV EBP,ESP             ;

		MOV ESI,[EBP+0CH]       ; Load the Exchange Index in ESI
		MOV EAX,ESI             ; Get the Exchange Index in EAX
		MOV EDX,sEXCH           ; Compute offset of Exch in rgExch
		MUL EDX                 ;
		MOV EDX,prgExch         ; Add offset of rgExch => EAX
		ADD EAX,EDX             ;
		MOV ECX,EAX             ; Make a copy in ECX (ECX = pExch)

		MOV EDX,pRunTSS         ; Get the pRunTSS in EDX
		MOV EBX,[EDX.TSS_pJCB]  ; Get pJCB in EBX
		MOV EDX,[EAX.Owner]     ; Get the Exchange Owner in EDX
		CMP EBX,EDX             ; If the CurrProc owns the Exchange,
		JE DE000                ; yes
		CMP EBX, OFFSET MonJCB  ; if not owner, is this the OS???
		JE DE000                ; yes
		MOV EAX,ercNotOwner     ;
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 4                  ;

DE000:
		CLI                     ;
		CMP [ECX.fEMsg],NIL     ; Check to See if a message may be queued
		JE DE001                ; No. Go check for Task (TSS)
		MOV ESI, ECX			; ESI must point to Exch for deQueue
		CALL deQueueMsg         ; Yes, Get the message off of the Exchange
		OR EAX, EAX
		JZ DE002				; Nothing there. Go free the Exch.

		;Return the LB to the pool
		MOV EBX,pFreeLB         ; pLBin^.Next <= pFreeLB;
		MOV [EAX.NextLB],EBX    ;
		MOV pFreeLB,EAX         ; pFreeLB <= pLBin;
		INC _nLBLeft			;
		JMP DE000               ; Go And Check for more.

		; If we find an RqBlk on the exchange we must respond
		;with ErcInvalidExch before we continue! This will
		;only happen if a system service writer doesn't follow
		;instructions or a service crashes!
		;
DE001:
		CMP [ECX.EHead],NIL  	; Check to See if TSS is queued
		JE DE002                ; NIL = Empty, JUMP
		MOV ESI, ECX			; ESI must point to Exch for deQueue
		CALL deQueueTSS         ; Get the TSS off of the Exchange

		;Free up the TSS (add it to the free list)
		MOV EBX,pFreeTSS        ; pTSSin^.Next <= pFreeTSS;
		MOV [EAX.NextTSS],EBX   ;
		MOV [EAX.TSS_pJCB], 0	; Make TSS invalid
		MOV pFreeTSS,EAX        ; pFreeTSS <= pTSSin;
		INC _nTSSLeft			;

		JMP DE001               ; Go And Check for more.
DE002:
		MOV [ECX.Owner],NIL     ; Free up the exchange.
		MOV [ECX.fEMsg],NIL     ; Reset msg Flag.
		INC _nEXCHLeft			; Stats
		STI                     ;
		MOV EAX,ercOk           ;
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 4                  ;
_DeAllocExch   ENDP

;=============================================================================
;
; GetTSSExch - This returns the Exchange of the current TSS to the
; caller.  This is primarily provided for System Services that provide
; direct access blocking calls for customers.
;
; Procedural Interface :
;
;       GetTSSExch(pExchRet):dError
;
;          pExchRet is a pointer to where you want the Exchange Handle
;          returned.  The Exchange is a DWORD (4 BYTES).
;
_GetTSSExch PROC FAR            ;
		PUSH EBP                ;
		MOV EBP,ESP             ;
		MOV EAX,pRunTSS    		; Get the Ptr To the Running TSS
		MOV ESI,[EBP+0CH]       ; Get the pExchRet in EDX
		MOV EBX, [EAX.TSS_Exch] ; Get Exch in EBX
		MOV [ESI],EBX			; Put Index of Exch at pExchRet
		XOR EAX, EAX            ; ErcOK
		POP EBP                 ;
		RETF 4                  ;
_GetTSSExch ENDP

;======================== End of Module ======================

⌨️ 快捷键说明

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