📄 mos.asm
字号:
;=============================================================================
;EnterDebug
;
; This piece of code sets up to enter the debugger. If we get here,
; one of the exceptions has activated and has done a little work based
; on which exception is was, then it jumped here to enter the debugger.
; This code effectively replaces the interrupted task with the debugger
; task (without going through the kernel). First we copy the Page Dir
; entry from the current job into the debuggers job, then copy the CR3
; register from the current TSS into the debugger's TSS. This makes the
; debugger operate in the current tasks memory space. All of the debugger's
; code and data are in OS protected pages (which are shared with all tasks),
; so this is OK to do even if the offending task referenced a bogus address.
; Next, we save the current pRunTSS and place the debugger's TSS in
; pRunTSS, then jump to the debugger's selector. This switches tasks.
;
EnterDebug:
PUSH EAX ;we MUST save caller's registers
PUSH EBX ; and restore them before the
PUSH EDX ; task switch into the debugger
MOV EAX, pRunTSS ;pRunTSS -> EAX
MOV EBX, [EAX.TSS_CR3] ;current CR3 -> EBX
MOV EDX, OFFSET DbgTSS ;pDebuggerTSS -> EDX
MOV [EDX.TSS_CR3], EBX ;CR3 -> DebuggerTSS
MOV EAX, [EAX.TSS_pJCB] ;pCrntJCB -> EAX
MOV EDX, [EDX.TSS_pJCB] ;pDebuggerJCB -> EDX
MOV EBX, [EAX.JcbPD] ;CrntJob Page Dir -> EBX
MOV [EDX.JcbPD], EBX ;Page Dir -> Debugger JCB
MOV EAX, pRunTSS ;Save the current pRunTSS
MOV DbgpTSSSave, EAX
MOV EAX, OFFSET DbgTSS ;Install Debugger's as current
MOV pRunTSS, EAX ;Set Dbgr as running task
MOV BX, [EAX.Tid]
MOV TSS_Sel, BX ;Set up debugger selector
POP EDX ;make his registers right!
POP EBX
POP EAX
JMP FWORD PTR [TSS] ;Switch tasks to debugger
PUSH dbgOldEFlgs ;Put the stack back
PUSH dbgOldCS ;
PUSH dbgOldEIP ;
IRETD ;Go back to the caller
;=============================================================================
; INTERRUPT PROCEDURES FOR FAULTS
;=============================================================================
; This is the general purpose "We didn't expect this interrupt" interrupt
; This will place "99" in the upper left corner of the screen so we
; can see there are SPURIOUS interrupts!!!!!
INTQ:
PUSH EAX
MOV EAX,07390739h ;99 - All unassigned ints come here
MOV DS:VGATextBase+00h,EAX
POP EAX
IRETD
;===================== Divide By ZERO (Int 0) ============================
IntDivBy0:
MOV EAX,07300730h ;00
MOV DS:VGATextBase+00h,EAX
CLI
HLT
;===================== Debugger Single Step (Int 1) ======================
IntDbgSS:
; MOV EAX,07310730h ;01 (for Serious Debugging)
; MOV DS:VGATextBase+00h,EAX
; CLI
; HLT
POP dbgOldEIP ; Get EIP of offender for debugger
POP dbgOldCS ;
POP dbgOldEFlgs ;
JMP EnterDebug ;Enter debugger
;===================== Debugger Entry (Int 3) ===========================
IntDebug:
; MOV EAX,07330730h ;03
; MOV DS:VGATextBase+00h,EAX
; CLI
; HLT
POP dbgOldEIP ; Get EIP of offender for debugger
POP dbgOldCS ; Get CS
POP dbgOldEFlgs ; Get Flags
JMP EnterDebug ;Enter debugger
;===================== OverFlow (Int 4) ==================================
IntOverFlow:
PUSH EAX
MOV EAX,07340730h ;04
MOV DS:VGATextBase+00h,EAX
CLI
HLT
;========================== Bad Opcode (Int 6) ================================
INTOpCode:
MOV EAX,07360730h ;06
MOV DS:VGATextBase+00h,EAX
HLT
MOV dbgFAULT,06h ; Invalid Opcode
POP dbgOldEIP ; Get EIP of offender for debugger
POP dbgOldCS ;
POP dbgOldEFlgs ;
JMP EnterDebug ;Enter debugger
;========================== Dbl Exception (Int 08)============================
IntDblExc:
MOV EAX,07380730h ;08
MOV DS:VGATextBase+00h,EAX
CLI
HLT
; MOV dbgFAULT,08h ; Double Exception
; POP dbgFltErc ; Error Code pushed last by processor
; POP dbgOldEIP
; POP dbgOldCS
; POP dbgOldEFlgs
; POP dbgOldEFlgs ;
; JMP EnterDebug ;Enter debugger
;========================= Invalid TSS 10 ====================================
INTInvTss:
MOV EAX,07300731h ;10
MOV DS:VGATextBase+00h,EAX
CLI
HLT
MOV dbgFAULT,0Ah ; Invalid TSS
POP dbgFltErc ; Error code pushed last by processor
POP dbgOldEIP
POP dbgOldCS
POP dbgOldEFlgs
JMP EnterDebug ;Enter debugger
;========================== Seg Not Present 11 ===============================
INTNoSeg:
MOV EAX,07310731h ;11
MOV DS:VGATextBase+00h,EAX
CLI
HLT
;========================== Stack Overflow 12 ================================
INTStkOvr:
; MOV EAX,07320731h ;12
; MOV DS:VGATextBase+00h,EAX
; CLI
; HLT
MOV dbgFAULT,0Ch ; Stack overflow
POP dbgFltErc
POP dbgOldEIP
POP dbgOldCS
POP dbgOldEFlgs
JMP EnterDebug ;Enter debugger
;========================== GP 13 ===========================================
IntGP:
; MOV EAX,07330731h ;13
; MOV DS:VGATextBase+00h,EAX
; CLI
; HLT
MOV dbgFAULT,0Dh ; GP Fault
POP dbgFltErc
POP dbgOldEIP
POP dbgOldCS
POP dbgOldEFlgs
JMP EnterDebug ;Enter debugger
;========================== Page Fault 14 ====================================
INTPgFlt:
; MOV EAX,07340731h ;14
; MOV DS:VGATextBase+00h,EAX
; CLI
; HLT
MOV dbgFAULT,0Eh ; Page Fault
POP dbgFltErc
POP dbgOldEIP
POP dbgOldCS
POP dbgOldEFlgs
JMP EnterDebug ;Enter debugger
;=============================================================================
; ISR for interrupt on PICU1 from Slave
;=============================================================================
IntPICU2: ; IRQ Line 2 from Slave 8259 (Int22)
PUSH EAX
MOV EAX,07320750h ; From PICU#2 (P2)
MOV DS:VGATextBase+100h,EAX
PUSH 2
CALL FAR PTR _EndOfIRQ
POP EAX
IRETD
;=============================================================================
; MONITOR Code is INCLUDED Here (at END of Segment)
;=============================================================================
INCLUDE Monitor.CAS
;=============================================================================
DummyTestPad DD 10 DUP(0);
OSCodeEnd LABEL BYTE
OSCSeg ENDS
;=============================================================================
;
; MMURTL IMAGE LOADER code:
; Clears interrupts
; Turn ON A20 adress line gate
; Moves the OS data to 00000000 physical.
; Moves the OS Code to 00010000 physical (64K Boundary)
; Jumps to the OS Code entry point.
; (This basically turns MS-DOS into a $79.00 loader)
;
;
; We define the GDT and IDT entries in MOS.gdt and MOS.idt.
;
; NOTE: This the last the processor sees of 16 bit real mode code
; (no great loss at all)
;
;=============================================================================
LoadSeg SEGMENT USE16
ASSUME CS:LoadSeg, DS:Nothing, ES:Nothing, SS:Nothing
IDTptr DW 7FFh ;LIMIT 256 IDT Slots
DD 0000h ;BASE (Linear)
GDTptr DW (nGDTSlots*8)-1 ;LIMIT 768 GDT Slots
DD 0800h ;BASE (Linear)
OSCodeSize EQU OSCodeEnd-OSCodeBegin
OSCodeMore EQU OSCodeSize - 10000h
OSDataSize EQU OSDataEnd-OSDataBegin
START: CLI ; first we clear interrupts
; Note: this next few lines of code turns on the address line 20 Gate!
; This must be done before we can physically address above 1 Meg!
XOR CX,CX ;check 64K times
IBEmm0:
IN AL,64h ;Read Status Byte into AL
TEST AL,02h ;Test The Input Buffer Full Bit
LOOPNZ IBEmm0
MOV AL,0D1h
OUT 64h,AL
XOR CX,CX ;check 64K times
IBEmm1:
IN AL,64h ;Read Status Byte into AL
TEST AL,02h ;Test The Input Buffer Full Bit
LOOPNZ IBEmm1
MOV AL,0DFh
OUT 60h,AL
XOR CX,CX ;check 64K times
IBEmm2:
IN AL,64h ;Read Status Byte into AL
TEST AL,02h ;Test The Input Buffer Full Bit
LOOPNZ IBEmm2
; Move OS data to Physical Address 0000h
MOV AX,SEG OSDSeg ; Move Data segment to 0000h
MOV DS,AX ;
XOR SI,SI ; Source DS:SI
MOV AX,0000h ;
MOV ES,AX ;
XOR DI,DI ; Destination ES:DI
MOV ECX, OSDataSize+3 ;
CLD ;
REP MOVSB ;
; Move OS Code to Physical Address 20000h (in 32K chunks)
MOV AX,SEG OSCSeg ; Move OS Code to 10000h
ADD AX, 1000h ; 10000h bytes into DOS segment
MOV DS,AX ;
XOR SI, SI ; Source DS:SI
MOV AX,1000h ; Segment 1000h (address 10000h)
MOV ES,AX ;
XOR DI,DI ; Destination ES:DI
MOV CX,8000h ; 64K Max (CODE is > 64K)
CLD ;
REP MOVSB ;
MOV AX,SEG OSCSeg ; Move OS Code to 10000h
ADD AX, 1800h ; 10000h bytes into DOS segment
MOV DS,AX ;
XOR SI, SI ; Source DS:SI
MOV AX,1800h ; Segment 1000h (address 10000h)
MOV ES,AX ;
XOR DI,DI ; Destination ES:DI
MOV CX,8000h ; 64K Max (CODE is > 64K)
CLD ;
REP MOVSB ;
MOV AX,SEG OSCSeg ; Move OS Code to 10000h
ADD AX, 2000h ;
MOV DS,AX ;
XOR SI, SI ; Source DS:SI
MOV AX,2000h ; Segment 1000h (address 10000h)
MOV ES,AX ;
XOR DI,DI ; Destination ES:DI
MOV CX, OSCodeMore+4;
CLD ;
REP MOVSB ;
LIDT CS:FWORD PTR IDTptr ; Load IDTR
LGDT CS:FWORD PTR GDTptr ; Load GDTR
MOV EAX,CR0 ; Set Protected Mode BIT
OR AL,1 ;
MOV CR0,EAX ;
JMP Next ; Clear Instruction Prefetch Queue
Next:
MOV BX,DataSel ; Setup Data Selectors
MOV DS,BX ; D Selector
MOV ES,BX ; E Selector
MOV FS,BX ; F Selector
MOV GS,BX ; G Selector
MOV SS,BX ; S Selector
;
; PROTECTED MODE FAR JUMP TO 8:Offset OS code
;
DB 066h ; 32 bit Data prefix
DB 067h ; 32 bit Address instruction prefix
DB 0EAh ; far jump opcode
DD OFFSET OSInitBegin ; 32 bit Offset ( Code Offset )
DW OSCodeSel ; 16 bit Selector ( Code Selector )
LoadSeg ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -