316 lines
9.9 KiB
HTML
316 lines
9.9 KiB
HTML
<html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
|
<html>
|
|
|
|
<head>
|
|
<title>80386 Programmer's Reference Manual -- Section 10.5</title>
|
|
</head>
|
|
|
|
<body>
|
|
<b>up:</b> <a href="C10.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/C10.HTM">Chapter 10 -- Initialization</a><br>
|
|
<b>prev:</b> <a href="S10_04.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/S10_04.HTM">10.4 Software Initialization for Protected Mode</a><br>
|
|
<b>next:</b> <a href="S10_06.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/S10_06.HTM">10.6 TLB Testing</a>
|
|
<p>
|
|
<hr>
|
|
<p>
|
|
<h1>10.5 Initialization Example</h1>
|
|
<pre>
|
|
|
|
|
|
|
|
$TITLE ('Initial Task')
|
|
NAME INIT
|
|
init_stack SEGMENT RW
|
|
DW 20 DUP(?)
|
|
tos LABEL WORD
|
|
init_stack ENDS
|
|
init_data SEGMENT RW PUBLIC
|
|
DW 20 DUP(?)
|
|
init_data ENDS
|
|
init_code SEGMENT ER PUBLIC
|
|
ASSUME DS:init_data
|
|
nop
|
|
nop
|
|
nop
|
|
init_start:
|
|
; set up stack
|
|
mov ax, init_stack
|
|
mov ss, ax
|
|
mov esp, offset tos
|
|
mov a1,1
|
|
blink:
|
|
xor a1,1
|
|
out 0e4h,a1
|
|
mov cx,3FFFh
|
|
here:
|
|
dec cx
|
|
jnz here
|
|
jmp SHORT blink
|
|
hlt
|
|
init_code ends
|
|
END init_start, SS:init_stack, DS:init_data
|
|
$TITLE('Protected Mode Transition -- 386 initialization')
|
|
NAME RESET
|
|
;*****************************************************************
|
|
; Upon reset the 386 starts executing at address 0FFFFFFF0H. The
|
|
; upper 12 address bits remain high until a FAR call or jump is
|
|
; executed.
|
|
;
|
|
; Assume the following:
|
|
;
|
|
;
|
|
; - a short jump at address 0FFFFFFF0H (placed there by the
|
|
; system builder) causes execution to begin at START in segment
|
|
; RESET_CODE.
|
|
;
|
|
;
|
|
; - segment RESET_CODE is based at physical address 0FFFF0000H,
|
|
; i.e. at the start of the last 64K in the 4G address space.
|
|
; Note that this is the base of the CS register at reset. If
|
|
; you locate ROMcode above this address, you will need to
|
|
; figure out an adjustment factor to address things within this
|
|
; segment.
|
|
;
|
|
;*****************************************************************
|
|
$EJECT ;
|
|
; Define addresses to locate GDT and IDT in RAM.
|
|
; These addresses are also used in the BLD386 file that defines
|
|
; the GDT and IDT. If you change these addresses, make sure you
|
|
; change the base addresses specified in the build file.
|
|
GDTbase EQU 00001000H ; physical address for GDT base
|
|
IDTbase EQU 00000400H ; physical address for IDT base
|
|
PUBLIC GDT_EPROM
|
|
PUBLIC IDT_EPROM
|
|
PUBLIC START
|
|
DUMMY segment rw ; ONLY for ASM386 main module stack init
|
|
DW 0
|
|
DUMMY ends
|
|
;*****************************************************************
|
|
;
|
|
; Note: RESET CODE must be USEl6 because the 386 initally executes
|
|
; in real mode.
|
|
;
|
|
RESET_CODE segment er PUBLIC USE16
|
|
ASSUME DS:nothing, ES:nothing
|
|
;
|
|
; 386 Descriptor template
|
|
DESC STRUC
|
|
lim_0_15 DW 0 ; limit bits (0..15)
|
|
bas_0_15 DW 0 ; base bits (0..15)
|
|
bas_16_23 DB 0 ; base bits (16..23)
|
|
access DB 0 ; access byte
|
|
gran DB 0 ; granularity byte
|
|
bas_24_31 DB 0 ; base bits (24..31)
|
|
DESC ENDS
|
|
; The following is the layout of the real GDT created by BLD386.
|
|
; It is located in EPROM and will be copied to RAM.
|
|
;
|
|
; GDT[O] ... NULL
|
|
; GDT[1] ... Alias for RAM GDT
|
|
; GDT[2] ... Alias for RAM IDT
|
|
; GDT[2] ... initial task TSS
|
|
; GDT[3] ... initial task TSS alias
|
|
; GDT[4] ... initial task LDT
|
|
; GDT[5] ... initial task LDT alias
|
|
;
|
|
; define entries in GDT and IDT.
|
|
GDT_ENTRIES EQU 8
|
|
IDT_ENTRIES EQU 32
|
|
; define some constants to index into the real GDT
|
|
GDT_ALIAS EQU 1*SIZE DESC
|
|
IDT_ALIAS EQU 2*SIZE DESC
|
|
INIT_TSS EQU 3*SIZE DESC
|
|
INIT_TSS_A EQU 4*SIZE DESC
|
|
INIT_LDT EQU 5*SIZE DESC
|
|
INIT_LDT_A EQU 6*SIZE DESC
|
|
;
|
|
; location of alias in INIT_LDT
|
|
INIT_LDT_ALIAS EQU 1*SIZE DESC
|
|
;
|
|
; access rights byte for DATA and TSS descriptors
|
|
DS_ACCESS EQU 010010010B
|
|
TSS_ACCESS EQU 010001001B
|
|
;
|
|
; This temporary GDT will be used to set up the real GDT in RAM.
|
|
Temp_GDT LABEL BYTE ; tag for begin of scratch GDT
|
|
NULL_DES DESC <> ; NULL descriptor
|
|
; 32-Gigabyte data segment based at 0
|
|
FLAT_DES DESC <0ffffh,0,0,92h,0cfh,0>
|
|
GDT_eprom DP ? ; Builder places GDT address and limit
|
|
; in this 6 byte area.
|
|
IDT_eprom DP ? ; Builder places IDT address and limit
|
|
; in this 6 byte area.
|
|
;
|
|
; Prepare operand for loadings GDTR and LDTR.
|
|
TGDT_pword LABEL PWORD ; for temp GDT
|
|
DW end_Temp_GDT_Temp_GDT -1
|
|
DD 0
|
|
GDT_pword LABEL PWORD ; for GDT in RAM
|
|
DW GDT_ENTRIES * SIZE DESC -1
|
|
DD GDTbase
|
|
IDT_pword LABEL PWORD ; for IDT in RAM
|
|
DW IDT_ENTRIES * SIZE DESC -1
|
|
DD IDTbase
|
|
end_Temp_GDT LABEL BYTE
|
|
;
|
|
; Define equates for addressing convenience.
|
|
GDT_DES_FLAT EQU DS:GDT_ALIAS +GDTbase
|
|
IDT_DES_FLAT EQU DS:IDT_ALIAS +GDTbase
|
|
INIT_TSS_A_OFFSET EQU DS:INIT_TSS_A
|
|
INIT_TSS_OFFSET EQU DS:INIT_TSS
|
|
INIT_LDT_A_OFFSET EQU DS:INIT_LDT_A
|
|
INIT_LDT_OFFSET EQU DS:INIT_LDT
|
|
; define pointer for first task switch
|
|
ENTRY POINTER LABEL DWORD
|
|
DW 0, INIT_TSS
|
|
;******************************************************************
|
|
;
|
|
; Jump from reset vector to here.
|
|
START:
|
|
CLI ;disable interrupts
|
|
CLD ;clear direction flag
|
|
LIDT NULL_des ;force shutdown on errors
|
|
;
|
|
; move scratch GDT to RAM at physical 0
|
|
XOR DI,DI
|
|
MOV ES,DI ;point ES:DI to physical location 0
|
|
MOV SI,OFFSET Temp_GDT
|
|
MOV CX,end_Temp_GDT-Temp_GDT ;set byte count
|
|
INC CX
|
|
;
|
|
; move table
|
|
REP MOVS BYTE PTR ES:[DI],BYTE PTR CS:[SI]
|
|
LGDT tGDT_pword ;load GDTR for Temp. GDT
|
|
;(located at 0)
|
|
; switch to protected mode
|
|
MOV EAX,CR0 ;get current CRO
|
|
MOV EAX,1 ;set PE bit
|
|
MOV CRO,EAX ;begin protected mode
|
|
;
|
|
; clear prefetch queue
|
|
JMP SHORT flush
|
|
flush:
|
|
; set DS,ES,SS to address flat linear space (0 ... 4GB)
|
|
MOV BX,FLAT_DES-Temp_GDT
|
|
MOV US,BX
|
|
MOV ES,BX
|
|
MOV SS,BX
|
|
;
|
|
; initialize stack pointer to some (arbitrary) RAM location
|
|
MOV ESP, OFFSET end_Temp_GDT
|
|
;
|
|
; copy eprom GDT to RAM
|
|
MOV ESI,DWORD PTR GDT_eprom +2 ; get base of eprom GDT
|
|
; (put here by builder).
|
|
MOV EDI,GDTbase ; point ES:EDI to GDT base in RAM.
|
|
MOV CX,WORD PTR gdt_eprom +0 ; limit of eprom GDT
|
|
INC CX
|
|
SHR CX,1 ; easier to move words
|
|
CLD
|
|
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
|
|
;
|
|
; copy eprom IDT to RAM
|
|
;
|
|
MOV ESI,DWORD PTR IDT_eprom +2 ; get base of eprom IDT
|
|
; (put here by builder)
|
|
MOV EDI,IDTbase ; point ES:EDI to IDT base in RAM.
|
|
MOV CX,WORD PTR idt_eprom +0 ; limit of eprom IDT
|
|
INC CX
|
|
SHR CX,1
|
|
CLD
|
|
REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
|
|
; switch to RAM GDT and IDT
|
|
;
|
|
LIDT IDT_pword
|
|
LGDT GDT_pword
|
|
;
|
|
MOV BX,GDT_ALIAS ; point DS to GDT alias
|
|
MOV DS,BX
|
|
;
|
|
; copy eprom TSS to RAM
|
|
;
|
|
MOV BX,INIT_TSS_A ; INIT TSS A descriptor base
|
|
; has RAM location of INIT TSS.
|
|
MOV ES,BX ; ES points to TSS in RAM
|
|
MOV BX,INIT_TSS ; get inital task selector
|
|
LAR DX,BX ; save access byte
|
|
MOV [BX].access,DS_ACCESS ; set access as data segment
|
|
MOV FS,BX ; FS points to eprom TSS
|
|
XOR si,si ; FS:si points to eprom TSS
|
|
XOR di,di ; ES:di points to RAM TSS
|
|
MOV CX,[BX].lim_0_15 ; get count to move
|
|
INC CX
|
|
;
|
|
; move INIT_TSS to RAM.
|
|
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
|
|
MOV [BX].access,DH ; restore access byte
|
|
;
|
|
; change base of INIT TSS descriptor to point to RAM.
|
|
MOV AX,INIT_TSS_A_OFFSET.bas_0_15
|
|
MOV INIT_TSS_OFFSET.bas_0_15,AX
|
|
MOV AL,INIT_TSS_A_OFFSET.bas_16_23
|
|
MOV INIT_TSS_OFFSET.bas_16_23,AL
|
|
MOV AL,INIT_TSS_A_OFFSET.bas_24_31
|
|
MOV INIT_TSS_OFFSET.bas_24_31,AL
|
|
;
|
|
; change INIT TSS A to form a save area for TSS on first task
|
|
; switch. Use RAM at location 0.
|
|
MOV BX,INIT_TSS_A
|
|
MOV WORD PTR [BX].bas_0_15,0
|
|
MOV [BX].bas_16_23,0
|
|
MOV [BX].bas_24_31,0
|
|
MOV [BX].access,TSS_ACCESS
|
|
MOV [BX].gran,O
|
|
LTR BX ; defines save area for TSS
|
|
;
|
|
; copy eprom LDT to RAM
|
|
MOV BX,INIT_LDT_A ; INIT_LDT_A descriptor has
|
|
; base address in RAM for INIT_LDT.
|
|
MOV ES,BX ; ES points LDT location in RAM.
|
|
MOV AH,[BX].bas_24_31
|
|
MOV AL,[BX].bas_16_23
|
|
SHL EAX,16
|
|
MOV AX,[BX].bas_0_15 ; save INIT_LDT base (ram) in EAX
|
|
MOV BX,INIT_LDT ; get inital LDT selector
|
|
LAR DX,BX ; save access rights
|
|
MOV [BX].access,DS_ACCESS ; set access as data segment
|
|
MOV FS,BX ; FS points to eprom LDT
|
|
XOR si,si ; FS:SI points to eprom LDT
|
|
XOR di,di ; ES:DI points to RAM LDT
|
|
MOV CX,[BX].lim_0_15 ; get count to move
|
|
INC CX
|
|
;
|
|
; move initial LDT to RAM
|
|
REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
|
|
MOV [BX].access,DH ; restore access rights in
|
|
; INIT_LDT descriptor
|
|
;
|
|
; change base of alias (of INIT_LDT) to point to location in RAM.
|
|
MOV ES:[INIT_LDT_ALIAS].bas_0_15,AX
|
|
SHR EAX,16
|
|
MOV ES:[INIT_LDT_ALIAS].bas_16_23,AL
|
|
MOV ES:[INIT_LDT_ALIAS].bas_24_31,AH
|
|
;
|
|
; now set the base value in INIT_LDT descriptor
|
|
MOV AX,INIT_LDT_A_OFFSET.bas_0_15
|
|
MOV INIT_LDT_OFFSET.bas_0_15,AX
|
|
MOV AL,INIT_LDT_A_OFFSET.bas_16_23
|
|
MOV INIT_LDT_OFFSET.bas_16_23,AL
|
|
MOV AL,INIT_LDT_A_OFFSET.bas_24_31
|
|
MOV INIT_LDT_OFFSET.bas_24_31,AL
|
|
;
|
|
; Now GDT, IDT, initial TSS and initial LDT are all set up.
|
|
;
|
|
; Start the first task!
|
|
'
|
|
JMP ENTRY_POINTER
|
|
RESET_CODE ends
|
|
END START, SS:DUMMY,DS:DUMMY
|
|
</pre>
|
|
<p>
|
|
<hr>
|
|
<p><b>up:</b> <a href="C10.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/C10.HTM">Chapter 10 -- Initialization</a><br>
|
|
<b>prev:</b> <a href="S10_04.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/S10_04.HTM">10.4 Software Initialization for Protected Mode</a><br>
|
|
<b>next:</b> <a href="S10_06.HTM" tppabs="http://webster.cs.ucr.edu/Page_TechDocs/Doc386/S10_06.HTM">10.6 TLB Testing</a>
|
|
</body>
|
|
|