Skip to content

Commit

Permalink
[pxeprefix] Work around bug in Etherboot 5.4 when loading undionly.kpxe
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Michael Brown committed Apr 30, 2009
1 parent 7c47ebd commit 4188d51
Showing 1 changed file with 55 additions and 5 deletions.
60 changes: 55 additions & 5 deletions src/arch/i386/prefix/pxeprefix.S
@@ -1,8 +1,11 @@
#define PXENV_UNDI_SHUTDOWN 0x0005
#define PXENV_UNDI_GET_NIC_TYPE 0x0012
#define PXENV_UNDI_GET_IFACE_INFO 0x0013
#define PXENV_STOP_UNDI 0x0015
#define PXENV_UNLOAD_STACK 0x0070

#define PXE_HACK_EB54 0x0001

.text
.arch i386
.org 0
Expand All @@ -11,6 +14,8 @@
#include <undi.h>

#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )

/*****************************************************************************
* Entry point: set operating context, print welcome message
Expand Down Expand Up @@ -307,8 +312,6 @@ pci_physical_device:
movw $10f, %si
call print_message
call print_pci_busdevfn
movb $0x0a, %al
call print_character
jmp 99f
.section ".prefix.data", "aw", @progbits
10: .asciz " UNDI device is PCI "
Expand All @@ -319,11 +322,46 @@ no_physical_device:
movw $10f, %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz " Unable to determine UNDI physical device\n"
10: .asciz " Unable to determine UNDI physical device"
.previous

99:

/*****************************************************************************
* Determine interface type
*****************************************************************************
*/
get_iface_type:
/* Issue PXENV_UNDI_GET_IFACE_INFO */
movw $PXENV_UNDI_GET_IFACE_INFO, %bx
call pxe_call
jnc 1f
call print_pxe_error
jmp 99f
1: /* Print interface type */
movw $10f, %si
call print_message
leaw ( pxe_parameter_structure + 0x02 ), %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz ", type "
.previous
/* Check for "Etherboot" interface type */
cmpl $EB_MAGIC_1, ( pxe_parameter_structure + 0x02 )
jne 99f
cmpl $EB_MAGIC_2, ( pxe_parameter_structure + 0x06 )
jne 99f
movw $10f, %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz " (workaround enabled)"
.previous
/* Flag Etherboot workarounds as required */
orw $PXE_HACK_EB54, pxe_hacks

99: movb $0x0a, %al
call print_character

/*****************************************************************************
* Leave NIC in a safe state
*****************************************************************************
Expand All @@ -337,6 +375,14 @@ shutdown_nic:
call print_pxe_error
1:
unload_base_code:
/* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so
* we must not issue this call if the underlying stack is
* Etherboot and we were not intending to issue a PXENV_STOP_UNDI.
*/
#ifdef PXELOADER_KEEP_UNDI
testw $PXE_HACK_EB54, pxe_hacks
jnz 99f
#endif /* PXELOADER_KEEP_UNDI */
/* Issue PXENV_UNLOAD_STACK */
movw $PXENV_UNLOAD_STACK, %bx
call pxe_call
Expand Down Expand Up @@ -549,7 +595,9 @@ pxe_call:
testw %ax, %ax
jz 1f
stc
1: /* Restore registers and return */
1: /* Clear direction flag, for the sake of sanity */
cld
/* Restore registers and return */
popw %es
popw %di
ret
Expand Down Expand Up @@ -593,7 +641,7 @@ print_pxe_error:
pxe_esp: .long 0
pxe_ss: .word 0

pxe_parameter_structure: .fill 20
pxe_parameter_structure: .fill 64

undi_code_segoff:
undi_code_size: .word 0
Expand All @@ -603,6 +651,8 @@ undi_data_segoff:
undi_data_size: .word 0
undi_data_segment: .word 0

pxe_hacks: .word 0

/* The following fields are part of a struct undi_device */

undi_device:
Expand Down

0 comments on commit 4188d51

Please sign in to comment.