|
@@ -21,6 +21,7 @@
|
21
|
21
|
|
22
|
22
|
.arch i386
|
23
|
23
|
.section ".prefix.lib", "awx", @progbits
|
|
24
|
+ .section ".data16", "aw", @progbits
|
24
|
25
|
|
25
|
26
|
/****************************************************************************
|
26
|
27
|
* install_block (real-mode near call)
|
|
@@ -164,6 +165,47 @@ install_basemem:
|
164
|
165
|
ret
|
165
|
166
|
.size install_basemem, . - install_basemem
|
166
|
167
|
|
|
168
|
+/****************************************************************************
|
|
169
|
+ * install_highmem (flat real-mode near call)
|
|
170
|
+ *
|
|
171
|
+ * Install .text and .data into high memory
|
|
172
|
+ *
|
|
173
|
+ * Parameters:
|
|
174
|
+ * %es:edi : address in high memory
|
|
175
|
+ * Returns:
|
|
176
|
+ * none
|
|
177
|
+ * Corrupts:
|
|
178
|
+ * none
|
|
179
|
+ ****************************************************************************
|
|
180
|
+ */
|
|
181
|
+
|
|
182
|
+#ifndef KEEP_IT_REAL
|
|
183
|
+
|
|
184
|
+ .section ".prefix.lib"
|
|
185
|
+ .code16
|
|
186
|
+install_highmem:
|
|
187
|
+ /* Preserve registers */
|
|
188
|
+ pushl %esi
|
|
189
|
+ pushl %edi
|
|
190
|
+ pushl %ecx
|
|
191
|
+ pushl %edx
|
|
192
|
+
|
|
193
|
+ /* Install .text and .data to specified address */
|
|
194
|
+ movl $_textdata_load_offset, %esi
|
|
195
|
+ movl $_textdata_progbits_size, %ecx
|
|
196
|
+ movl $_textdata_size, %edx
|
|
197
|
+ call install_block
|
|
198
|
+
|
|
199
|
+ /* Restore registers and interrupt status */
|
|
200
|
+ popl %edx
|
|
201
|
+ popl %ecx
|
|
202
|
+ popl %edi
|
|
203
|
+ popl %esi
|
|
204
|
+ ret
|
|
205
|
+ .size install_highmem, . - install_highmem
|
|
206
|
+
|
|
207
|
+#endif /* KEEP_IT_REAL */
|
|
208
|
+
|
167
|
209
|
/****************************************************************************
|
168
|
210
|
* GDT for flat real mode
|
169
|
211
|
*
|
|
@@ -183,11 +225,6 @@ gdt_limit: .word gdt_length - 1
|
183
|
225
|
gdt_base: .long 0
|
184
|
226
|
.word 0 /* padding */
|
185
|
227
|
|
186
|
|
-real_ds: /* Genuine real mode data segment */
|
187
|
|
- .equ REAL_DS, real_ds - gdt
|
188
|
|
- .word 0xffff, 0
|
189
|
|
- .byte 0, 0x93, 0, 0
|
190
|
|
-
|
191
|
228
|
flat_ds: /* Flat real mode data segment */
|
192
|
229
|
.equ FLAT_DS, flat_ds - gdt
|
193
|
230
|
.word 0xffff, 0
|
|
@@ -200,12 +237,12 @@ gdt_end:
|
200
|
237
|
#endif /* KEEP_IT_REAL */
|
201
|
238
|
|
202
|
239
|
/****************************************************************************
|
203
|
|
- * set_segment_limits (real-mode near call)
|
|
240
|
+ * flatten_real_mode (real-mode near call)
|
204
|
241
|
*
|
205
|
|
- * Sets limits on the data segments %ds and %es.
|
|
242
|
+ * Sets 4GB limits on the data segments %ds and %es.
|
206
|
243
|
*
|
207
|
244
|
* Parameters:
|
208
|
|
- * %cx : Segment limit ($REAL_DS or $FLAT_DS)
|
|
245
|
+ * none
|
209
|
246
|
****************************************************************************
|
210
|
247
|
*/
|
211
|
248
|
|
|
@@ -213,7 +250,7 @@ gdt_end:
|
213
|
250
|
|
214
|
251
|
.section ".prefix.lib"
|
215
|
252
|
.code16
|
216
|
|
-set_segment_limits:
|
|
253
|
+flatten_real_mode:
|
217
|
254
|
/* Preserve real-mode segment values and temporary registers */
|
218
|
255
|
pushw %es
|
219
|
256
|
pushw %ds
|
|
@@ -227,12 +264,18 @@ set_segment_limits:
|
227
|
264
|
movl %eax, %cs:gdt_base
|
228
|
265
|
lgdt %cs:gdt
|
229
|
266
|
|
230
|
|
- /* Switch to protected mode, set segment limits, switch back */
|
|
267
|
+ /* Switch to protected mode */
|
231
|
268
|
movl %cr0, %eax
|
232
|
269
|
orb $CR0_PE, %al
|
233
|
270
|
movl %eax, %cr0
|
234
|
|
- movw %cx, %ds
|
235
|
|
- movw %cx, %es
|
|
271
|
+
|
|
272
|
+ /* Set flat segment limits */
|
|
273
|
+ movw $FLAT_DS, %ax
|
|
274
|
+ movw %ax, %ds
|
|
275
|
+ movw %ax, %es
|
|
276
|
+
|
|
277
|
+ /* Switch back to real mode */
|
|
278
|
+ movl %cr0, %eax
|
236
|
279
|
andb $0!CR0_PE, %al
|
237
|
280
|
movl %eax, %cr0
|
238
|
281
|
|
|
@@ -241,61 +284,7 @@ set_segment_limits:
|
241
|
284
|
popw %ds
|
242
|
285
|
popw %es
|
243
|
286
|
ret
|
244
|
|
- .size set_segment_limits, . - set_segment_limits
|
245
|
|
-
|
246
|
|
-#endif /* KEEP_IT_REAL */
|
247
|
|
-
|
248
|
|
-/****************************************************************************
|
249
|
|
- * install_highmem (real-mode near call)
|
250
|
|
- *
|
251
|
|
- * Install .text and .data into high memory
|
252
|
|
- *
|
253
|
|
- * Parameters:
|
254
|
|
- * %edi : physical address in high memory
|
255
|
|
- * Returns:
|
256
|
|
- * none
|
257
|
|
- * Corrupts:
|
258
|
|
- * none
|
259
|
|
- ****************************************************************************
|
260
|
|
- */
|
261
|
|
-
|
262
|
|
-#ifndef KEEP_IT_REAL
|
263
|
|
-
|
264
|
|
- .section ".prefix.lib"
|
265
|
|
- .code16
|
266
|
|
-install_highmem:
|
267
|
|
- /* Preserve registers and interrupt status */
|
268
|
|
- pushfl
|
269
|
|
- pushl %esi
|
270
|
|
- pushl %edi
|
271
|
|
- pushl %ecx
|
272
|
|
- pushl %edx
|
273
|
|
-
|
274
|
|
- /* Disable interrupts and flatten real mode */
|
275
|
|
- cli
|
276
|
|
- movw $FLAT_DS, %cx
|
277
|
|
- call set_segment_limits
|
278
|
|
-
|
279
|
|
- /* Install .text and .data to specified address */
|
280
|
|
- xorw %cx, %cx
|
281
|
|
- movw %cx, %es
|
282
|
|
- movl $_textdata_load_offset, %esi
|
283
|
|
- movl $_textdata_progbits_size, %ecx
|
284
|
|
- movl $_textdata_size, %edx
|
285
|
|
- call install_block
|
286
|
|
-
|
287
|
|
- /* Unflatten real mode */
|
288
|
|
- movw $REAL_DS, %cx
|
289
|
|
- call set_segment_limits
|
290
|
|
-
|
291
|
|
- /* Restore registers and interrupt status */
|
292
|
|
- popl %edx
|
293
|
|
- popl %ecx
|
294
|
|
- popl %edi
|
295
|
|
- popl %esi
|
296
|
|
- popfl
|
297
|
|
- ret
|
298
|
|
- .size install_highmem, . - install_highmem
|
|
287
|
+ .size flatten_real_mode, . - flatten_real_mode
|
299
|
288
|
|
300
|
289
|
#endif /* KEEP_IT_REAL */
|
301
|
290
|
|
|
@@ -329,32 +318,71 @@ install_prealloc:
|
329
|
318
|
call install_basemem
|
330
|
319
|
|
331
|
320
|
#ifndef KEEP_IT_REAL
|
|
321
|
+ /* Preserve registers and interrupt status, and disable interrupts */
|
|
322
|
+ pushfw
|
|
323
|
+ pushw %ds
|
|
324
|
+ pushw %es
|
|
325
|
+ pushl %esi
|
|
326
|
+ pushl %ecx
|
|
327
|
+ cli
|
|
328
|
+
|
|
329
|
+ /* Load up %ds and %es, and set up vectors for far calls to .text16 */
|
|
330
|
+ movw %bx, %ds
|
|
331
|
+ xorw %si, %si
|
|
332
|
+ movw %si, %es
|
|
333
|
+ movw %ax, (init_librm_vector+2)
|
|
334
|
+ movw %ax, (prot_call_vector+2)
|
|
335
|
+
|
332
|
336
|
/* Install .text and .data to 2MB mark. Use 2MB to avoid
|
333
|
337
|
* problems with A20.
|
334
|
338
|
*/
|
|
339
|
+ call flatten_real_mode
|
335
|
340
|
movl $(2<<20), %edi
|
336
|
341
|
call install_highmem
|
337
|
342
|
|
338
|
|
- /* Continue executing in .text16 segment */
|
339
|
|
- movw %bx, %ds
|
340
|
|
- pushw %cs
|
341
|
|
- pushw $2f
|
342
|
|
- pushw %ax
|
343
|
|
- pushw $1f
|
344
|
|
- lret
|
345
|
|
- .section ".text16", "awx", @progbits
|
346
|
|
-1:
|
347
|
|
- /* Set up protected-mode GDT, call relocate(), reset GDT */
|
348
|
|
- call init_librm
|
|
343
|
+ /* Set up initial protected-mode GDT, call relocate().
|
|
344
|
+ * relocate() will return with %esi, %edi and %ecx set up
|
|
345
|
+ * ready for the copy to the new location.
|
|
346
|
+ */
|
|
347
|
+ lcall *init_librm_vector
|
349
|
348
|
pushl $relocate
|
350
|
|
- data32 call prot_call
|
|
349
|
+ lcall *prot_call_vector
|
351
|
350
|
addw $4, %sp
|
352
|
|
- call init_librm
|
353
|
351
|
|
354
|
|
- /* Return to executing in .prefix section */
|
355
|
|
- lret
|
356
|
|
- .section ".prefix.lib"
|
357
|
|
-2:
|
|
352
|
+ /* Move code to new location, set up new protected-mode GDT */
|
|
353
|
+ call flatten_real_mode
|
|
354
|
+ pushl %edi
|
|
355
|
+ es rep addr32 movsb
|
|
356
|
+ popl %edi
|
|
357
|
+ lcall *init_librm_vector
|
|
358
|
+
|
|
359
|
+ /* Hide Etherboot from BIOS memory map. Note that making this
|
|
360
|
+ * protected-mode call will also restore normal (non-flat)
|
|
361
|
+ * real mode, as part of the protected-to-real transition.
|
|
362
|
+ */
|
|
363
|
+ pushl $hide_etherboot
|
|
364
|
+ lcall *prot_call_vector
|
|
365
|
+ addw $4, %sp
|
|
366
|
+
|
|
367
|
+ /* Restore registers and interrupt status */
|
|
368
|
+ popl %ecx
|
|
369
|
+ popl %esi
|
|
370
|
+ popw %es
|
|
371
|
+ popw %ds
|
|
372
|
+ popfw
|
358
|
373
|
#endif
|
359
|
374
|
ret
|
360
|
375
|
.size install_prealloc, . - install_prealloc
|
|
376
|
+
|
|
377
|
+#ifndef KEEP_IT_REAL
|
|
378
|
+ /* Vectors for far calls to .text16 functions */
|
|
379
|
+ .section ".data16"
|
|
380
|
+init_librm_vector:
|
|
381
|
+ .word init_librm
|
|
382
|
+ .word 0
|
|
383
|
+ .size init_librm_vector, . - init_librm_vector
|
|
384
|
+prot_call_vector:
|
|
385
|
+ .word prot_call
|
|
386
|
+ .word 0
|
|
387
|
+ .size prot_call_vector, . - prot_call_vector
|
|
388
|
+#endif
|