Browse Source

[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 years ago
parent
commit
4188d51753
1 changed files with 55 additions and 5 deletions
  1. 55
    5
      src/arch/i386/prefix/pxeprefix.S

+ 55
- 5
src/arch/i386/prefix/pxeprefix.S View File

1
 #define PXENV_UNDI_SHUTDOWN		0x0005
1
 #define PXENV_UNDI_SHUTDOWN		0x0005
2
 #define	PXENV_UNDI_GET_NIC_TYPE		0x0012
2
 #define	PXENV_UNDI_GET_NIC_TYPE		0x0012
3
+#define PXENV_UNDI_GET_IFACE_INFO	0x0013
3
 #define	PXENV_STOP_UNDI			0x0015
4
 #define	PXENV_STOP_UNDI			0x0015
4
 #define PXENV_UNLOAD_STACK		0x0070
5
 #define PXENV_UNLOAD_STACK		0x0070
5
 
6
 
7
+#define PXE_HACK_EB54			0x0001
8
+
6
 	.text
9
 	.text
7
 	.arch i386
10
 	.arch i386
8
 	.org 0
11
 	.org 0
11
 #include <undi.h>
14
 #include <undi.h>
12
 
15
 
13
 #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
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
  * Entry point:	set operating context, print welcome message
21
  * Entry point:	set operating context, print welcome message
307
 	movw	$10f, %si
312
 	movw	$10f, %si
308
 	call	print_message
313
 	call	print_message
309
 	call	print_pci_busdevfn
314
 	call	print_pci_busdevfn
310
-	movb	$0x0a, %al
311
-	call	print_character
312
 	jmp	99f
315
 	jmp	99f
313
 	.section ".prefix.data", "aw", @progbits
316
 	.section ".prefix.data", "aw", @progbits
314
 10:	.asciz	"         UNDI device is PCI "
317
 10:	.asciz	"         UNDI device is PCI "
319
 	movw	$10f, %si
322
 	movw	$10f, %si
320
 	call	print_message
323
 	call	print_message
321
 	.section ".prefix.data", "aw", @progbits
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
 	.previous
326
 	.previous
324
 
327
 
325
 99:
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
  * Leave NIC in a safe state
366
  * Leave NIC in a safe state
329
  *****************************************************************************
367
  *****************************************************************************
337
 	call	print_pxe_error
375
 	call	print_pxe_error
338
 1:
376
 1:
339
 unload_base_code:
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
 	/* Issue PXENV_UNLOAD_STACK */
386
 	/* Issue PXENV_UNLOAD_STACK */
341
 	movw	$PXENV_UNLOAD_STACK, %bx
387
 	movw	$PXENV_UNLOAD_STACK, %bx
342
 	call	pxe_call
388
 	call	pxe_call
549
 	testw	%ax, %ax
595
 	testw	%ax, %ax
550
 	jz	1f
596
 	jz	1f
551
 	stc
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
 	popw	%es
601
 	popw	%es
554
 	popw	%di
602
 	popw	%di
555
 	ret
603
 	ret
593
 pxe_esp:		.long 0
641
 pxe_esp:		.long 0
594
 pxe_ss:			.word 0
642
 pxe_ss:			.word 0
595
 
643
 
596
-pxe_parameter_structure: .fill 20
644
+pxe_parameter_structure: .fill 64
597
 
645
 
598
 undi_code_segoff:
646
 undi_code_segoff:
599
 undi_code_size:		.word 0
647
 undi_code_size:		.word 0
603
 undi_data_size:		.word 0
651
 undi_data_size:		.word 0
604
 undi_data_segment:	.word 0
652
 undi_data_segment:	.word 0
605
 
653
 
654
+pxe_hacks:		.word 0
655
+
606
 /* The following fields are part of a struct undi_device */
656
 /* The following fields are part of a struct undi_device */
607
 
657
 
608
 undi_device:
658
 undi_device:

Loading…
Cancel
Save