📄 mos.asm
字号:
.386P
; MMURTL Operating System Source Code
; Copyright 1991,1992,1993, Richard A. Burgess
; ALL RIGHTS RESERVED
; Version x0.8
OSDummySeg SEGMENT BYTE PUBLIC USE32
ASSUME CS:OSDummySeg, DS:Nothing, ES:Nothing
ASSUME FS:OSDummySeg, GS:Nothing
;This segment is used to pad the front end of the EXE so we don't
;overwrite ourself when we copy the data & code down to the low
;end of memory. We will overwrite this segment instead.
DummyPad DB 10000h DUP (0)
OSDummySeg ENDS
;
;This is the main source file for the MMURTL OS.
;This file is assembled into two segments that the Loader Code
;moves into place. See the InitCode Segment at the end of the file.
;
;=============================================================================
;
; OS KERNEL Data Structures
;=============================================================================
OSDSeg SEGMENT DWORD PUBLIC USE32
ASSUME CS:OSCSeg, DS:OSDSeg,ES:OSDSeg
ASSUME FS:OSDSeg,GS:OSDSeg
ORG 0000h
OSDataBegin LABEL BYTE
INCLUDE MOSEDF.INC ; These first 4 items MUST be in this order!
IDT DQ 256 DUP (0) ;2K for IDT (0.5 pages, 1K) @ 00000000h Physcial
INCLUDE MOSGDT.INC ; 6K for GDT @ 00000800h Physical (1.5 Pages, 6K)
INCLUDE MOSPDR.INC ; OS Page Directory & 1st Table (8k)
; Directory @ 02000h Physical
; Page Table @ 03000h Physical
;=============================================================================
; Kernel Structures - See MOSEDF.INC for structure details.
;=============================================================================
MonTSS TSSTYPE 1 dup (<>) ; Initial TSS for OS/Monitor
DbgTSS TSSTYPE 1 dup (<>) ; Initial TSS for Debugger
pFreeTSS DD NIL ; Pointer to Free List of Task State Segs
pDynTSSs DD 0 ; ptr to alloced mem for dynamic TSSs
pRunTSS DD NIL ; Pointer to the Running TSS
_nTSSLeft DD nTSS-2 ; For Monitor stats (less static TSSs)
;------------------
rgLBs LINKBLOCK nLB dup (<>) ; pool of LBs
pFreeLB DD NIL ; Pointer to Free List of Link Block
_nLBLeft DD nLB ; For Monitor stats
;------------------
;The RUN Queue for Ready to Run tasks
RdyQ QUEUE nPRI dup (<>) ; Setup the priority Ready Queue
;------------------
;Two static Job Control blocks to get us kick-started.
;The rest of them are in allocated memory
MonJCB JCBType 1 dup (<>) ; Monitor JCB
DbgJCB JCBType 1 dup (<>) ; Debugger JCB
pFreeJCB DD NIL ; Ptr to free Job Control Blocks
pJCBs DD 0 ; JCBs are in allocated memory
_nJCBLeft DD nJCBs ; For Monitor stats
;------------------
;Request Block control variables
pFreeRQB DD NIL ; Ptr to free Request Blocks
pRQBs DD 0 ; RQBs are in allocated memory
_nRQBLeft DD nRQBs ; For Monitor stats
;------------------
rgSVC SVCDESC nSVC dup (<>) ; Setup an array of Service Descriptors
;------------------
;Exchanges take up a fair amount of memory. In order to use certain kernel
;primitives, we need exchanges before they are allocated dynamically.
;We have an array of 3 exchanges set aside for this purpose. After
;the dynamic array is allocated an initialized, we copy these into
;the first three dynamic exchanges. These static exchanges are used
;by the Monitor TSS, Debugger TSS, and memory Management.
nExch DD 3 ; This will be changed after allocation
; of dynamic exchanges.
rgExchTmp WAITQUEUE 3 dup (<>) ; Setup three static temporary Exchanges
; for Monitor and Debugger TSSs
; These are moved to dynamic rgExchs
; as soon as they are allocated.
prgExch DD OFFSET rgExchTmp ; Pointer to current array of Exchanges.
pExchTmp DD 0 ; Pointer to dynamic array Exchanges.
_nEXCHLeft DD nDynEXCH ; For Monitor stats
;-------------------
TSS DD 00000000h ; Used for jumping to next
TSS_Sel DW 0000h ; MMURTL Task
_nSwitches DD 0
;=============================================================================
; Memory Management Data - See MEMORY Management calls for details
;=============================================================================
;Page Allocation Map
rgPAM DB 2048 DUP (0) ;1 bit/4Kbytes - 2048 bytes = 64Mb
sPAM DD 32 ;Deafult is 32 (1Mb)
sPAMmax EQU 2048 ;Max is 2048 (64Mb)
_nPagesFree DD 0 ;Number of free physical pages left
_oMemMax DD 000FFFFFh ;Default to 1 MB
GDTLimit DW 0000h ;Global Descriptor Table Limit
GDTBase DD 00000000h ;base
IDTLimit DW 0000h ;Interrupt Descriptor Table Limit
IDTBase DD 00000000h ;base
MemExch DD 00000000h ;Semaphore exchange for Mem Mgmt
pNextPT DD 00000000h ;We alloc the "next" page table
;in advance (MANDATORY)
;-----------------
rgNewJob DB 'New Job' ;Placed in New JCBs
cbNewJob EQU 7
rgOSJob DB 'MMOS Monitor' ;Placed in first JCB
cbOSJob EQU 12
;THESE USED TO BE THE INITIAL STACKS FOR THE OS Monitor AND Debugger
;We may use these again when we go do dynamic allocation of
;OS stacks for tasks.
OSStack DD 0FFh DUP (00000000h) ;1K OS Monitor Stack
OSStackTop DD 00000000h
OSStackSize EQU OSStackTop-OSStack
Stack1 DD 0FFh DUP (00000000h) ;1K Debugger Stack
Stack1Top DD 00000000h
Stack1Size EQU Stack1Top-Stack1
dJunk DD 0
;=============================================================================
; TIMER INTERRUPT COUNTER and TimerBlocks
;=============================================================================
TimerTick DD 0 ;Incremented every 10ms (0 on bootup).
nTmrBlksUsed DD 0 ;Number of timer blocks in use
rgTmrBlks TmrBlk nTmrBlks DUP (<>)
;=============================================================================
; Keyboard Data Module
;=============================================================================
INCLUDE KBDData.INC
;=============================================================================
;Video Data Module is INCLUDED here
;=============================================================================
INCLUDE VidData.inc
;=============================================================================
; INCLUDE Debugger variables and buffers here
;=============================================================================
INCLUDE DBGData.inc ;Data for Debugger
INCLUDE UASM.DAS ;Data for disassembler
;=============================================================================
; INCLUDE Device Driver Entry equates, variables and buffers here
;=============================================================================
INCLUDE DvDrData.inc
;=============================================================================
; INCLUDE Floppy/Hard Disk Driver equates, variables and buffers here
;=============================================================================
INCLUDE FDD.DAS
INCLUDE HDD.DAS
;=============================================================================
; INCLUDE Comms Driver Data here (serial & parallel)
;=============================================================================
INCLUDE CommDrv.DAS
;=============================================================================
; INCLUDE File System Data here
;=============================================================================
INCLUDE FSys.DAS
;=============================================================================
; INCLUDE Monitor Data here...
;=============================================================================
INCLUDE Monitor.DAS
;=============================================================================
; INCLUDE JobC Data here...
;=============================================================================
INCLUDE JOBC.DAS
;=============================================================================
;This Ends the Data Segment
;
OSDataEnd LABEL BYTE
OSDSeg ENDS
;
;
;=============================================================================
;=============================================================================
;Create a small segment we can search for to build RUN image file
;
OSDummySeg2 SEGMENT BYTE PUBLIC USE32
ASSUME CS:OSDummySeg, DS:Nothing, ES:Nothing
ASSUME FS:OSDummySeg, GS:Nothing
DummyPad2 DB 'MMURTLCODEXX'
OSDummySeg2 ENDS
;=============================================================================
;=============================================================================
;
; This begins the OS Code Segment
;
;
OSCSeg SEGMENT DWORD PUBLIC USE32
ASSUME CS:OSCSeg, DS:OSDSeg,ES:OSDSeg
ASSUME FS:OSDSeg,GS:OSDSeg
;
OSCodebase EQU 0h ;OS code is moved to 64K boundary
;
ORG 10000h ;64K boundry
;
OSCodeBegin LABEL BYTE
;
;BEGIN OS PROTECTED MODE INITIALIZATION CODE
;
;This code is used to initialize the permanent OS structures.
;
; "Will Robinson, WARNING, WARNING!! Dr. Smith is approaching!!!"
; BEWARE ON INITIALIZATION. The kernel structures and their
; initilization routines are so interdependent, you better pay
; close attention before you change the order of ANYTHING.
; (Anything before we jump to the monitor code that is)
;
;=============================================================================
; Set up MMURTL Stack Pointer (SS = DS already).
;=============================================================================
OSInitBegin:
LEA EAX,OSStackTop ; Setup initial OS Stack
MOV ESP,EAX ; FIRST THING IN OS CODE.
;=============================================================================
; Set up OS Common Public for IDT and GDT Base and Limits - SECOND THING IN OS
;=============================================================================
SGDT FWORD PTR GDTLimit ;
SIDT FWORD PTR IDTLimit ;
;=============================================================================
; Setup Operating System Structures and motherboard hardware
; THIS IS RIGHT AFTER WE GET A STACK.
; YOU CAN'T ALLOCATE ANY OS RESOURCES UNTIL THIS CODE EXECUTES!!!
;=============================================================================
CALL InitIDT ;Sets up default Interrupt table
MOV ECX,nLB ; count of Link Blocks
MOV EDX,sLinkBlock ; EDX is size of a Link Block
CALL InitFreeLB ; Init the array of Link Blocks
CALL InitCallGates ; Sets up all call gates as DUMMYs
CALL InitOSPublics ; Sets up OS PUBLIC call gates
CALL InitDMA ; Sets up DMA with defaults
CALL Set8259 ; Set up 8259s for ints (before KBD)
CALL InitKBD ; Initialize the Kbd hardware
PUSH 0 ; Highest IRQ number (all IRQs)
CALL FAR PTR _EndOfIRQ ; Tell em to work
;Set time counter divisor to 11938 - 10ms ticks
;Freq in is 1.193182 Mhz/11932 = 100 per second
;or 1 every 10 ms. (2E9Ch = 11932d)
MOV AL,9Ch ; Makes the timer Tick (lo)
OUT 40h,AL ; 10 ms apart by setting
MOV AL,02Eh ; clock divisior to (hi byte)
OUT 40h,AL ; 11,932
STI ; We are ready to GO (for now)
;=============================================================================
; The following code finishes the initialization procedures BEFORE the
; OS goes into paged memory mode.
; We set up an initial Task by filling a static TSS, creating and loading
; a descriptor entry for it in the GDT and we do the same for the debugger.
;=============================================================================
; Make the default TSS for the CPU to switch from a valid one.
; This TSS is a valid TSS after the first task switch.
; IMPORTANT - Allocate Exch and InitMemMgmt calls depend on
; pRunTSS being valid. They can not be called before
; this next block of code!!! Note that this TSS does NOT
; get placed in the linked list with the rest of the TSSs.
; It will never be free. We also have to manaully make it's
; entry in the GDT.
;The following code section builds a descriptor entry for
;the initial TSS (for Montitor program) and places it into the GDT
MOV EAX, sTSS ; Limit of TSS (TSS + SOFTSTATE)
MOV EBX, 0089h ; G(0),AV(0),LIM(0),P(1),DPL(0),B(0)
MOV EDX, OFFSET MonTSS ; Address of TSS
MOV EDI, OFFSET rgTSSDesc ; Address of GDT entry to fill
CALL AddTSSDesc
;Now that we have valid Descriptor, we set up the TSS itself
;and Load Task Register with the descriptor (selector)
;Note that none of the TSS register values need to be filled in
;because they will be filled by the processor on the first
;task switch.
MOV EBX, OFFSET MonTSS ; Get ptr to initial TSS in EBX
MOV pRunTSS,EBX ; this IS our task now!!!
MOV EAX, OFFSET rgTSSDesc ; ptr to initial TSS descriptor
SUB EAX, OFFSET GDT ; Sub offset of GDT Base to get Sel of TSS
MOV [EBX.Tid],AX ; Store TSS Selector in TSS (Task ID)
LTR [EBX.Tid] ; Setup the Task Register
MOV [EBX.Priority], 25 ; Priority 25 (monitor is another APP)
MOV [EBX.TSS_CR3], OFFSET PDir1 ;Physical address of PDir1
MOV [EBX.TSSNum], 1 ;Number of first TSS (Duh)
;Set up Job Control Block for Monitor (always Job 1)
;JOB 0 is not allowed. First JCB IS job 1!
MOV EAX, OFFSET MonJCB ;
MOV [EAX.JobNum], 1 ;Number the JCB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -