-
Notifications
You must be signed in to change notification settings - Fork 408
/
startup.asm
393 lines (378 loc) · 6.56 KB
/
startup.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
; 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