This includes both separate .md files, and documentation that was on the head of the .S source files. Retest everything as this was done, and fix a few easy things.
394 lines
6.6 KiB
NASM
394 lines
6.6 KiB
NASM
; TODO finish converting this to a text file that looks like the PDF...
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; ASSUMPTIONS:
|
||
;
|
||
; 1. The bottom 64K of memory is ram, and can be used for
|
||
; scratch space by this module.
|
||
;
|
||
; 2. The system has sufficient free usable ram to copy the
|
||
; initial GDT, IDT, and TSS
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
; configuration data - must match with build definition
|
||
|
||
CS_BASE EQU 0FFFF0000H
|
||
; CS_BASE is the linear address of the segment STARTUP_CODE
|
||
; - this is specified in the build language file
|
||
|
||
RAM_START EQU 400H
|
||
; RAM_START is the start of free, usable ram in the linear
|
||
; memory space. The GDT, IDT, and initial TSS will be
|
||
; copied above this space, and a small data segment will be
|
||
; discarded at this linear address. The 32-bit word at
|
||
; RAM_START will contain the linear address of the first
|
||
; free byte above the copied tables - this may be useful if
|
||
; a memory manager is used.
|
||
|
||
TSS_INDEX EQU 10
|
||
; TSS_INDEX is the index of the TSS of the first task to
|
||
; run after startup
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
; ------------------------- STRUCTURES and EQU ---------------
|
||
; structures for system data
|
||
|
||
; TSS structure
|
||
TASK_STATE STRUC
|
||
link DW ?
|
||
link_h DW ?
|
||
ESP0 DD ?
|
||
SS0 DW ?
|
||
SS0_h DW ?
|
||
ESP1 DD ?
|
||
SS1 DW ?
|
||
SS1_h DW ?
|
||
ESP2 DD ?
|
||
SS2 DW ?
|
||
SS2_h DW ?
|
||
CR3_reg DD ?
|
||
EIP_reg DD ?
|
||
EFLAGS_regDD ?
|
||
EAX_reg DD ?
|
||
ECX_reg DD ?
|
||
EDX_reg DD ?
|
||
EBX_reg DD ?
|
||
ESP_reg DD ?
|
||
EBP_reg DD ?
|
||
ESI_reg DD ?
|
||
EDI_reg DD ?
|
||
ES_reg DW ?
|
||
ES_h DW ?
|
||
CS_reg DW ?
|
||
CS_h DW ?
|
||
SS_reg DW ?
|
||
SS_h DW ?
|
||
DS_reg DW ?
|
||
DS_h DW ?
|
||
FS_reg DW ?
|
||
FS_h DW ?
|
||
GS_reg DW ?
|
||
GS_h DW ?
|
||
LDT_reg DW ?
|
||
LDT_h DW ?
|
||
TRAP_reg DW ?
|
||
IO_map_baseDW ?
|
||
TASK_STATE ENDS
|
||
|
||
; basic structure of a descriptor
|
||
DESC STRUC
|
||
lim_0_15 DW ?
|
||
bas_0_15 DW ?
|
||
bas_16_23 DB ?
|
||
access DB ?
|
||
gran DB ?
|
||
bas_24_31 DB ?
|
||
DESC ENDS
|
||
|
||
; structure for use with LGDT and LIDT instructions
|
||
TABLE_REG STRUC
|
||
table_lim DW ?
|
||
table_linearDD ?
|
||
TABLE_REG
|
||
ENDS
|
||
; offset of GDT and IDT descriptors in builder generated GDT
|
||
GDT_DESC_OFF
|
||
EQU 1*SIZE(DESC)
|
||
IDT_DESC_OFF
|
||
EQU 2*SIZE(DESC)
|
||
; equates for building temporary GDT in RAM
|
||
LINEAR_SEL
|
||
EQU
|
||
1*SIZE (DESC)
|
||
LINEAR_PROTO_LO
|
||
EQU
|
||
00000FFFFH ; LINEAR_ALIAS
|
||
LINEAR_PROTO_HI
|
||
EQU
|
||
000CF9200H
|
||
; Protection Enable Bit in CR0
|
||
PE_BIT EQU 1B
|
||
; ------------------------------------------------------------
|
||
; ------------------------- DATA SEGMENT----------------------
|
||
; Initially, this data segment starts at linear 0, according
|
||
; to the processor’s power-up state.
|
||
STARTUP_DATA
|
||
SEGMENT RW
|
||
free_mem_linear_base
|
||
LABEL
|
||
DWORD
|
||
TEMP_GDT
|
||
LABEL
|
||
BYTE ; must be first in segment
|
||
TEMP_GDT_NULL_DESC
|
||
DESC
|
||
<>
|
||
TEMP_GDT_LINEAR_DESC DESC
|
||
<>
|
||
; scratch areas for LGDT and
|
||
LIDT instructions
|
||
TEMP_GDT_SCRATCH TABLE_REG
|
||
<>
|
||
APP_GDT_RAM
|
||
TABLE_REG
|
||
<>
|
||
APP_IDT_RAM
|
||
TABLE_REG
|
||
<>
|
||
; align end_data
|
||
fill
|
||
DW
|
||
?
|
||
; last thing in this segment - should be on a dword boundary
|
||
end_data
|
||
LABEL
|
||
BYTE
|
||
STARTUP_DATA
|
||
ENDS
|
||
; ------------------------------------------------------------
|
||
; ------------------------- CODE SEGMENT----------------------
|
||
STARTUP_CODE SEGMENT ER PUBLIC USE16
|
||
; filled in by builder
|
||
PUBLIC GDT_EPROM
|
||
GDT_EPROM
|
||
TABLE_REG
|
||
<>
|
||
; filled in by builder
|
||
PUBLIC IDT_EPROM
|
||
IDT_EPROM
|
||
TABLE_REG
|
||
<>
|
||
; entry point into startup code - the bootstrap will vector
|
||
; here with a near JMP generated by the builder.
|
||
This
|
||
; label must be in the top 64K of linear memory.
|
||
PUBLIC
|
||
STARTUP
|
||
STARTUP:
|
||
; DS,ES address the bottom 64K of flat linear memory
|
||
ASSUME DS:STARTUP_DATA, ES:STARTUP_DATA
|
||
; See Figure 9-4
|
||
; load GDTR with temporary GDT
|
||
LEA
|
||
EBX,TEMP_GDT ; build the TEMP_GDT in low ram,
|
||
MOV
|
||
DWORD PTR [EBX],0
|
||
; where we can address
|
||
MOV
|
||
DWORD PTR [EBX]+4,0
|
||
MOV
|
||
DWORD PTR [EBX]+8, LINEAR_PROTO_LO
|
||
MOV
|
||
DWORD PTR [EBX]+12, LINEAR_PROTO_HI
|
||
MOV
|
||
TEMP_GDT_scratch.table_linear,EBX
|
||
MOV
|
||
TEMP_GDT_scratch.table_lim,15
|
||
DB 66H; execute a 32 bit LGDT
|
||
LGDT
|
||
TEMP_GDT_scratch
|
||
; enter protected mode
|
||
MOV
|
||
EBX,CR0
|
||
OR
|
||
EBX,PE_BIT
|
||
MOV
|
||
CR0,EBX
|
||
; clear prefetch queue
|
||
JMP
|
||
CLEAR_LABEL
|
||
CLEAR_LABEL:
|
||
; make DS and ES address 4G of linear memory
|
||
MOV
|
||
CX,LINEAR_SEL
|
||
MOV
|
||
DS,CX
|
||
MOV
|
||
ES,CX
|
||
; do board specific initialization
|
||
;
|
||
;
|
||
; ......
|
||
;
|
||
; See Figure 9-5
|
||
; copy EPROM GDT to ram at:
|
||
;
|
||
RAM_START + size (STARTUP_DATA)
|
||
MOV
|
||
EAX,RAM_START
|
||
ADD
|
||
EAX,OFFSET (end_data)
|
||
MOV
|
||
EBX,RAM_START
|
||
MOV
|
||
ECX, CS_BASE
|
||
ADD
|
||
ECX, OFFSET (GDT_EPROM)
|
||
MOV
|
||
ESI, [ECX].table_linear
|
||
MOV
|
||
EDI,EAX
|
||
MOVZX
|
||
ECX, [ECX].table_lim
|
||
MOV
|
||
APP_GDT_ram[EBX].table_lim,CX
|
||
INC
|
||
ECX
|
||
MOV
|
||
EDX,EAX
|
||
MOV
|
||
APP_GDT_ram[EBX].table_linear,EAX
|
||
ADD
|
||
EAX,ECX
|
||
REP MOVS
|
||
BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
|
||
; fixup
|
||
GDT base in descriptor
|
||
MOV
|
||
ECX,EDX
|
||
MOV
|
||
[EDX].bas_0_15+GDT_DESC_OFF,CX
|
||
ROR
|
||
ECX,16
|
||
|
||
; PAGE 4 TODO remove later.
|
||
|
||
MOV
|
||
[EDX].bas_16_23+GDT_DESC_OFF,CL
|
||
[EDX].bas_24_31+GDT_DESC_OFF,CH
|
||
; copy EPROM IDT to ram at:
|
||
; RAM_START+size(STARTUP_DATA)+SIZE (EPROM GDT)
|
||
MOV
|
||
ECX, CS_BASE
|
||
ADD
|
||
ECX, OFFSET (IDT_EPROM)
|
||
MOV
|
||
ESI, [ECX].table_linear
|
||
MOV
|
||
EDI,EAX
|
||
MOVZX
|
||
ECX, [ECX].table_lim
|
||
MOV
|
||
APP_IDT_ram[EBX].table_lim,CX
|
||
INC
|
||
ECX
|
||
MOV
|
||
APP_IDT_ram[EBX].table_linear,EAX
|
||
MOV
|
||
EBX,EAX
|
||
ADD
|
||
EAX,ECX
|
||
REP MOVS
|
||
BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
|
||
MOV
|
||
ROR
|
||
MOV
|
||
MOV
|
||
MOV
|
||
LGDT
|
||
LIDT
|
||
REPMOV
|
||
MOV
|
||
MOV
|
||
MOV
|
||
MOV
|
||
MOV
|
||
ROL
|
||
MOV
|
||
MOV
|
||
LSL
|
||
INC
|
||
MOV
|
||
ADD
|
||
MOVS
|
||
MOV
|
||
ROL
|
||
MOV
|
||
MOV
|
||
ROL
|
||
;save start
|
||
MOV
|
||
; fixup IDT pointer in GDT
|
||
[EDX].bas_0_15+IDT_DESC_OFF,BX
|
||
EBX,16
|
||
[EDX].bas_16_23+IDT_DESC_OFF,BL
|
||
[EDX].bas_24_31+IDT_DESC_OFF,BH
|
||
; load GDTR and IDTR
|
||
EBX,RAM_START
|
||
DB
|
||
66H
|
||
; execute a 32 bit LGDT
|
||
APP_GDT_ram[EBX]
|
||
DB
|
||
66H
|
||
; execute a 32 bit LIDT
|
||
APP_IDT_ram[EBX]
|
||
; move the TSS
|
||
EDI,EAX
|
||
EBX,TSS_INDEX*SIZE(DESC)
|
||
ECX,GDT_DESC_OFF ;build linear address for TSS
|
||
GS,CX
|
||
DH,GS:[EBX].bas_24_31
|
||
DL,GS:[EBX].bas_16_23
|
||
EDX,16
|
||
DX,GS:[EBX].bas_0_15
|
||
ESI,EDX
|
||
ECX,EBX
|
||
ECX
|
||
EDX,EAX
|
||
EAX,ECX
|
||
BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
|
||
; fixup TSS pointer
|
||
GS:[EBX].bas_0_15,DX
|
||
EDX,16
|
||
GS:[EBX].bas_24_31,DH
|
||
GS:[EBX].bas_16_23,DL
|
||
EDX,16
|
||
of free ram at linear location RAMSTART
|
||
free_mem_linear_base+RAM_START,EAX
|
||
|
||
|
||
;assume no LDT used in the initial task - if necessary,
|
||
;code to move the LDT could be added, and should resemble
|
||
;that used to move the TSS
|
||
; load task register
|
||
LTR
|
||
BX
|
||
; No task switch, only descriptor loading
|
||
; See Figure 9-6
|
||
; load minimal set of registers necessary to simulate task
|
||
; switch
|
||
MOV
|
||
AX,[EDX].SS_reg
|
||
; start loading registers
|
||
MOV
|
||
EDI,[EDX].ESP_reg
|
||
MOV
|
||
SS,AX
|
||
MOV
|
||
ESP,EDI
|
||
; stack now valid
|
||
PUSH
|
||
DWORD PTR [EDX].EFLAGS_reg
|
||
PUSH
|
||
DWORD PTR [EDX].CS_reg
|
||
PUSH
|
||
DWORD PTR [EDX].EIP_reg
|
||
MOV
|
||
AX,[EDX].DS_reg
|
||
MOV
|
||
BX,[EDX].ES_reg
|
||
MOV
|
||
DS,AX
|
||
; DS and ES no longer linear memory
|
||
MOV
|
||
ES,BX
|
||
; simulate far jump to initial task
|
||
IRETD
|
||
STARTUP_CODE ENDS
|
||
END STARTUP, DS:STARTUP_DATA, SS:STARTUP_DATA
|
||
|