mirror of https://github.com/ipxe/ipxe.git
[pxeprefix] Search for the PXE entry points through all methods
Search for the PXE entry points (via the !PXE or PXENV+ structures) through all known combinations of search methods. Furthermore, if we find a PXENV+ structure, attempt to use it to find the !PXE structure if at all possible.pull/1/head
parent
4dd746a725
commit
6a3f5d6db7
|
@ -31,18 +31,10 @@
|
||||||
pushl $STACK_MAGIC
|
pushl $STACK_MAGIC
|
||||||
movw %ss, %cs:pxe_ss
|
movw %ss, %cs:pxe_ss
|
||||||
movl %esp, %cs:pxe_esp
|
movl %esp, %cs:pxe_esp
|
||||||
movw %sp, %bp
|
|
||||||
movl (10*4+4*2+4)(%bp),%ebp /* !PXE address */
|
|
||||||
|
|
||||||
/* Set up %ds */
|
/* Set up segments */
|
||||||
movw %cs, %ax
|
movw %cs, %ax
|
||||||
movw %ax, %ds
|
movw %ax, %ds
|
||||||
/* Record PXENV+ and !PXE nominal addresses */
|
|
||||||
movw %es, pxenv_segment /* PXENV+ address */
|
|
||||||
movw %bx, pxenv_offset
|
|
||||||
movl %ebp, ppxe_segoff /* !PXE address */
|
|
||||||
/* Set up %es and %fs */
|
|
||||||
movw %ax, %es
|
|
||||||
movw $0x40, %ax /* BIOS data segment access */
|
movw $0x40, %ax /* BIOS data segment access */
|
||||||
movw %ax, %fs
|
movw %ax, %fs
|
||||||
/* Set up stack just below 0x7c00 */
|
/* Set up stack just below 0x7c00 */
|
||||||
|
@ -60,16 +52,57 @@
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Verify PXENV+ structure and record parameters of interest
|
* Find us a usable !PXE or PXENV+ entry point
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
detect_pxenv:
|
detect_pxe:
|
||||||
/* Signature check */
|
/* Plan A: !PXE pointer from the stack */
|
||||||
les pxenv_segoff, %bx
|
lgsl pxe_esp, %ebp /* %gs:%bp -> original stack */
|
||||||
cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
|
lesw %gs:52(%bp), %bx
|
||||||
jne no_pxenv
|
call is_valid_ppxe
|
||||||
cmpw $0x2b56, %es:4(%bx) /* 'V+' signature */
|
je have_ppxe
|
||||||
jne no_pxenv
|
|
||||||
|
/* Plan B: PXENV+ pointer from initial ES:BX */
|
||||||
|
movw %gs:32(%bp),%bx
|
||||||
|
movw %gs:8(%bp),%es
|
||||||
|
call is_valid_pxenv
|
||||||
|
je have_pxenv
|
||||||
|
|
||||||
|
/* Plan C: PXENV+ structure via INT 1Ah */
|
||||||
|
movw $0x5650, %ax
|
||||||
|
int $0x1a
|
||||||
|
jc 1f
|
||||||
|
cmpw $0x564e, %ax
|
||||||
|
jne 1f
|
||||||
|
call is_valid_pxenv
|
||||||
|
je have_pxenv
|
||||||
|
1:
|
||||||
|
/* Plan D: scan base memory for !PXE */
|
||||||
|
call memory_scan_ppxe
|
||||||
|
je have_ppxe
|
||||||
|
|
||||||
|
/* Plan E: scan base memory for PXENV+ */
|
||||||
|
call memory_scan_pxenv
|
||||||
|
jne stack_not_found
|
||||||
|
|
||||||
|
have_pxenv:
|
||||||
|
movw %bx, pxenv_offset
|
||||||
|
movw %es, pxenv_segment
|
||||||
|
|
||||||
|
cmpw $0x201, %es:6(%bx) /* API version >= 2.01 */
|
||||||
|
jb 1f
|
||||||
|
cmpb $0x2c, %es:8(%bx) /* ... and structure long enough */
|
||||||
|
jb 2f
|
||||||
|
|
||||||
|
lesw %es:0x28(%bx), %bx /* Find !PXE from PXENV+ */
|
||||||
|
call is_valid_ppxe
|
||||||
|
je have_ppxe
|
||||||
|
2:
|
||||||
|
call memory_scan_ppxe /* We are *supposed* to have !PXE... */
|
||||||
|
je have_ppxe
|
||||||
|
1:
|
||||||
|
lesw pxenv_segoff, %bx /* Nope, we're stuck with PXENV+ */
|
||||||
|
|
||||||
/* Record entry point and UNDI segments */
|
/* Record entry point and UNDI segments */
|
||||||
pushl %es:0x0a(%bx) /* Entry point */
|
pushl %es:0x0a(%bx) /* Entry point */
|
||||||
popl entry_segoff
|
popl entry_segoff
|
||||||
|
@ -79,36 +112,22 @@ detect_pxenv:
|
||||||
pushw %es:0x20(%bx) /* UNDI data segment */
|
pushw %es:0x20(%bx) /* UNDI data segment */
|
||||||
pushw %es:0x22(%bx) /* UNDI data size */
|
pushw %es:0x22(%bx) /* UNDI data size */
|
||||||
popl undi_data_segoff
|
popl undi_data_segoff
|
||||||
|
|
||||||
/* Print "PXENV+ at <address>" */
|
/* Print "PXENV+ at <address>" */
|
||||||
movw $10f, %si
|
movw $10f, %si
|
||||||
call print_message
|
call print_message
|
||||||
call print_segoff
|
call print_segoff
|
||||||
movb $( ',' ), %al
|
movb $( ',' ), %al
|
||||||
call print_character
|
call print_character
|
||||||
jmp 99f
|
jmp check_have_stack
|
||||||
.section ".prefix.data", "aw", @progbits
|
.section ".prefix.data", "aw", @progbits
|
||||||
10: .asciz " PXENV+ at "
|
10: .asciz " PXENV+ at "
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
no_pxenv:
|
have_ppxe:
|
||||||
xorl %eax, %eax
|
|
||||||
movl %eax, pxenv_segoff
|
|
||||||
|
|
||||||
99:
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Verify !PXE structure and record parameters of interest
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
detect_ppxe:
|
|
||||||
/* Signature check */
|
|
||||||
les ppxe_segoff, %bx
|
|
||||||
cmpl $0x45585021, %es:(%bx) /* '!PXE' signature */
|
|
||||||
jne no_ppxe
|
|
||||||
/* Record structure address, entry point, and UNDI segments */
|
|
||||||
pushw %es
|
|
||||||
popw ppxe_segment
|
|
||||||
movw %bx, ppxe_offset
|
movw %bx, ppxe_offset
|
||||||
|
movw %es, ppxe_segment
|
||||||
|
|
||||||
pushl %es:0x10(%bx) /* Entry point */
|
pushl %es:0x10(%bx) /* Entry point */
|
||||||
popl entry_segoff
|
popl entry_segoff
|
||||||
pushw %es:0x30(%bx) /* UNDI code segment */
|
pushw %es:0x30(%bx) /* UNDI code segment */
|
||||||
|
@ -123,16 +142,59 @@ detect_ppxe:
|
||||||
call print_segoff
|
call print_segoff
|
||||||
movb $( ',' ), %al
|
movb $( ',' ), %al
|
||||||
call print_character
|
call print_character
|
||||||
jmp 99f
|
jmp check_have_stack
|
||||||
.section ".prefix.data", "aw", @progbits
|
.section ".prefix.data", "aw", @progbits
|
||||||
10: .asciz " !PXE at "
|
10: .asciz " !PXE at "
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
no_ppxe:
|
is_valid_ppxe:
|
||||||
xorl %eax, %eax
|
cmpl $0x45585021, %es:(%bx)
|
||||||
movl %eax, ppxe_segoff
|
jne 1f
|
||||||
|
movzbw %es:4(%bx), %cx
|
||||||
|
cmpw $0x58, %cx
|
||||||
|
jae is_valid_checksum
|
||||||
|
1:
|
||||||
|
ret
|
||||||
|
|
||||||
99:
|
is_valid_pxenv:
|
||||||
|
cmpl $0x4e455850, %es:(%bx)
|
||||||
|
jne 1b
|
||||||
|
cmpw $0x2b56, %es:4(%bx)
|
||||||
|
jne 1b
|
||||||
|
movzbw %es:8(%bx), %cx
|
||||||
|
cmpw $0x28, %cx
|
||||||
|
jb 1b
|
||||||
|
|
||||||
|
is_valid_checksum:
|
||||||
|
pushw %ax
|
||||||
|
movw %bx, %si
|
||||||
|
xorw %ax, %ax
|
||||||
|
2:
|
||||||
|
es lodsb
|
||||||
|
addb %al, %ah
|
||||||
|
loopw 2b
|
||||||
|
popw %ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
memory_scan_ppxe:
|
||||||
|
movw $is_valid_ppxe, %dx
|
||||||
|
jmp memory_scan_common
|
||||||
|
|
||||||
|
memory_scan_pxenv:
|
||||||
|
movw $is_valid_pxenv, %dx
|
||||||
|
|
||||||
|
memory_scan_common:
|
||||||
|
movw %fs:(0x13), %ax
|
||||||
|
shlw $6, %ax
|
||||||
|
decw %ax
|
||||||
|
1: incw %ax
|
||||||
|
cmpw $( 0xa000 - 1 ), %ax
|
||||||
|
ja 2f
|
||||||
|
movw %ax, %es
|
||||||
|
xorw %bx, %bx
|
||||||
|
call *%dx
|
||||||
|
jne 1b
|
||||||
|
2: ret
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Sanity check: we must have an entry point
|
* Sanity check: we must have an entry point
|
||||||
|
@ -144,6 +206,7 @@ check_have_stack:
|
||||||
testl %eax, %eax
|
testl %eax, %eax
|
||||||
jnz 99f
|
jnz 99f
|
||||||
/* No entry point: print message and skip everything else */
|
/* No entry point: print message and skip everything else */
|
||||||
|
stack_not_found:
|
||||||
movw $10f, %si
|
movw $10f, %si
|
||||||
call print_message
|
call print_message
|
||||||
jmp finished
|
jmp finished
|
||||||
|
@ -529,8 +592,8 @@ print_pxe_error:
|
||||||
*/
|
*/
|
||||||
.section ".prefix.data"
|
.section ".prefix.data"
|
||||||
|
|
||||||
pxe_ss: .word 0
|
|
||||||
pxe_esp: .long 0
|
pxe_esp: .long 0
|
||||||
|
pxe_ss: .word 0
|
||||||
|
|
||||||
pxe_parameter_structure: .fill 20
|
pxe_parameter_structure: .fill 20
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue