瀏覽代碼

init_librm() and prot_call() are now real-mode far calls.

install() now calls relocate(), moves the protected-mode code to the new
location, and calls hide_etherboot().
tags/v0.9.3
Michael Brown 18 年之前
父節點
當前提交
89da833c5d

+ 2
- 1
src/arch/i386/interface/pcbios/int13.c 查看文件

@@ -393,7 +393,8 @@ static void hook_int13 ( void ) {
393 393
 				"\nint13_wrapper:\n\t"
394 394
 				"orb $0, %%al\n\t" /* clear CF and OF */
395 395
 				"pushl %0\n\t" /* call int13() */
396
-				"data32 call prot_call\n\t"
396
+				"pushw %%cs\n\t"
397
+				"call prot_call\n\t"
397 398
 				"jo 1f\n\t" /* chain if OF not set */
398 399
 				"pushfw\n\t"
399 400
 				"lcall *%%cs:int13_vector\n\t"

+ 2
- 1
src/arch/i386/prefix/dskprefix.S 查看文件

@@ -357,7 +357,8 @@ start_runtime:
357 357
 	.section ".text16", "awx", @progbits
358 358
 1:
359 359
 	pushl	$main
360
-	data32 call	prot_call
360
+	pushw	%cs
361
+	call	prot_call
361 362
 	popl	%eax /* discard */
362 363
 
363 364
 	/* Boot next device */

+ 112
- 84
src/arch/i386/prefix/libprefix.S 查看文件

@@ -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

+ 4
- 4
src/arch/i386/transitions/librm.S 查看文件

@@ -88,7 +88,7 @@ gdt_end:
88 88
 	.equ	gdt_length, gdt_end - gdt
89 89
 
90 90
 /****************************************************************************
91
- * init_librm (real-mode near call, 16-bit real-mode return address)
91
+ * init_librm (real-mode far call, 16-bit real-mode far return address)
92 92
  *
93 93
  * Initialise the GDT ready for transitions to protected mode.
94 94
  *
@@ -143,7 +143,7 @@ init_librm:
143 143
 	negl	%edi
144 144
 	popl	%ebx
145 145
 	popl	%eax
146
-	ret
146
+	lret
147 147
 
148 148
 	.section ".text16"
149 149
 	.code16
@@ -316,7 +316,7 @@ rm_cs:	.word 0
316 316
 rm_ds:	.word 0
317 317
 	
318 318
 /****************************************************************************
319
- * prot_call (real-mode near call, 32-bit real-mode return address)
319
+ * prot_call (real-mode far call, 16-bit real-mode far return address)
320 320
  *
321 321
  * Call a specific C function in the protected-mode code.  The
322 322
  * prototype of the C function must be
@@ -405,7 +405,7 @@ prot_call:
405 405
 				 * zeroes the high word of %esp, and interrupts
406 406
 				 * are still disabled at this point. */
407 407
 	popfl
408
-	data32 ret
408
+	lret
409 409
 
410 410
 /****************************************************************************
411 411
  * real_call (protected-mode near call, 32-bit virtual return address)

Loading…
取消
儲存