Преглед на файлове

[pxeprefix] Work around bug in Etherboot 5.4 when loading undionly.kpxe

Etherboot 5.4 erroneously treats PXENV_UNLOAD_STACK as the "final
shutdown" call, and unhooks INT15.  When using gPXE's undionly.kpxe,
this results in gPXE overwriting the portion of Etherboot located in
high memory, because it is no longer hidden from the system memory map
at the time that gPXE loads.

Work around this by explicitly testing for Etherboot as the underlying
PXE stack (as is already done in undinet.c) and skipping the call to
PXENV_UNLOAD_STACK if necessary.
tags/v0.9.8
Michael Brown преди 15 години
родител
ревизия
4188d51753
променени са 1 файла, в които са добавени 55 реда и са изтрити 5 реда
  1. 55
    5
      src/arch/i386/prefix/pxeprefix.S

+ 55
- 5
src/arch/i386/prefix/pxeprefix.S Целия файл

@@ -1,8 +1,11 @@
1 1
 #define PXENV_UNDI_SHUTDOWN		0x0005
2 2
 #define	PXENV_UNDI_GET_NIC_TYPE		0x0012
3
+#define PXENV_UNDI_GET_IFACE_INFO	0x0013
3 4
 #define	PXENV_STOP_UNDI			0x0015
4 5
 #define PXENV_UNLOAD_STACK		0x0070
5 6
 
7
+#define PXE_HACK_EB54			0x0001
8
+
6 9
 	.text
7 10
 	.arch i386
8 11
 	.org 0
@@ -11,6 +14,8 @@
11 14
 #include <undi.h>
12 15
 
13 16
 #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
17
+#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
18
+#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )
14 19
 
15 20
 /*****************************************************************************
16 21
  * Entry point:	set operating context, print welcome message
@@ -307,8 +312,6 @@ pci_physical_device:
307 312
 	movw	$10f, %si
308 313
 	call	print_message
309 314
 	call	print_pci_busdevfn
310
-	movb	$0x0a, %al
311
-	call	print_character
312 315
 	jmp	99f
313 316
 	.section ".prefix.data", "aw", @progbits
314 317
 10:	.asciz	"         UNDI device is PCI "
@@ -319,11 +322,46 @@ no_physical_device:
319 322
 	movw	$10f, %si
320 323
 	call	print_message
321 324
 	.section ".prefix.data", "aw", @progbits
322
-10:	.asciz	"         Unable to determine UNDI physical device\n"
325
+10:	.asciz	"         Unable to determine UNDI physical device"
323 326
 	.previous
324 327
 
325 328
 99:
326 329
 
330
+/*****************************************************************************
331
+ * Determine interface type
332
+ *****************************************************************************
333
+ */
334
+get_iface_type:
335
+	/* Issue PXENV_UNDI_GET_IFACE_INFO */
336
+	movw	$PXENV_UNDI_GET_IFACE_INFO, %bx
337
+	call	pxe_call
338
+	jnc	1f
339
+	call	print_pxe_error
340
+	jmp	99f
341
+1:	/* Print interface type */
342
+	movw	$10f, %si
343
+	call	print_message
344
+	leaw	( pxe_parameter_structure + 0x02 ), %si
345
+	call	print_message
346
+	.section ".prefix.data", "aw", @progbits
347
+10:	.asciz	", type "
348
+	.previous
349
+	/* Check for "Etherboot" interface type */
350
+	cmpl	$EB_MAGIC_1, ( pxe_parameter_structure + 0x02 )
351
+	jne	99f
352
+	cmpl	$EB_MAGIC_2, ( pxe_parameter_structure + 0x06 )
353
+	jne	99f
354
+	movw	$10f, %si
355
+	call	print_message
356
+	.section ".prefix.data", "aw", @progbits
357
+10:	.asciz	" (workaround enabled)"
358
+	.previous
359
+	/* Flag Etherboot workarounds as required */
360
+	orw	$PXE_HACK_EB54, pxe_hacks
361
+
362
+99:	movb	$0x0a, %al
363
+	call	print_character
364
+
327 365
 /*****************************************************************************
328 366
  * Leave NIC in a safe state
329 367
  *****************************************************************************
@@ -337,6 +375,14 @@ shutdown_nic:
337 375
 	call	print_pxe_error
338 376
 1:
339 377
 unload_base_code:
378
+	/* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so
379
+	 * we must not issue this call if the underlying stack is
380
+	 * Etherboot and we were not intending to issue a PXENV_STOP_UNDI.
381
+	 */
382
+#ifdef PXELOADER_KEEP_UNDI
383
+	testw	$PXE_HACK_EB54, pxe_hacks
384
+	jnz	99f
385
+#endif /* PXELOADER_KEEP_UNDI */
340 386
 	/* Issue PXENV_UNLOAD_STACK */
341 387
 	movw	$PXENV_UNLOAD_STACK, %bx
342 388
 	call	pxe_call
@@ -549,7 +595,9 @@ pxe_call:
549 595
 	testw	%ax, %ax
550 596
 	jz	1f
551 597
 	stc
552
-1:	/* Restore registers and return */
598
+1:	/* Clear direction flag, for the sake of sanity */
599
+	cld
600
+	/* Restore registers and return */
553 601
 	popw	%es
554 602
 	popw	%di
555 603
 	ret
@@ -593,7 +641,7 @@ print_pxe_error:
593 641
 pxe_esp:		.long 0
594 642
 pxe_ss:			.word 0
595 643
 
596
-pxe_parameter_structure: .fill 20
644
+pxe_parameter_structure: .fill 64
597 645
 
598 646
 undi_code_segoff:
599 647
 undi_code_size:		.word 0
@@ -603,6 +651,8 @@ undi_data_segoff:
603 651
 undi_data_size:		.word 0
604 652
 undi_data_segment:	.word 0
605 653
 
654
+pxe_hacks:		.word 0
655
+
606 656
 /* The following fields are part of a struct undi_device */
607 657
 
608 658
 undi_device:

Loading…
Отказ
Запис