mirror of https://github.com/ipxe/ipxe.git
Updated to work with libprefix.
parent
29340d7728
commit
9f86754f90
|
@ -1,16 +1,9 @@
|
||||||
/* Offsets of words containing ROM's CS and size (in 512 byte blocks)
|
|
||||||
* from start of floppy boot block at 0x7c00
|
|
||||||
* Offsets must match those in etherboot.h
|
|
||||||
*/
|
|
||||||
#define FLOPPY_SEGMENT 0x7c0
|
|
||||||
|
|
||||||
#define PXENV_UNDI_CLEANUP 0x02
|
#define PXENV_UNDI_CLEANUP 0x02
|
||||||
#define PXENV_UNDI_SHUTDOWN 0x05
|
#define PXENV_UNDI_SHUTDOWN 0x05
|
||||||
#define PXENV_STOP_UNDI 0x15
|
#define PXENV_STOP_UNDI 0x15
|
||||||
#define PXENV_UNLOAD_STACK 0x70
|
#define PXENV_UNLOAD_STACK 0x70
|
||||||
#define PXENV_STOP_BASE 0x76
|
#define PXENV_STOP_BASE 0x76
|
||||||
|
|
||||||
#define PUSHA_SIZE 16
|
|
||||||
#define PXE_STACK_MAGIC 0x57ac /* 'STac' */
|
#define PXE_STACK_MAGIC 0x57ac /* 'STac' */
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
@ -22,21 +15,35 @@
|
||||||
* Entry point: set cs, ds, bp, print welcome message
|
* Entry point: set cs, ds, bp, print welcome message
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
_prefix:
|
jmp $0x7c0, $code_start
|
||||||
jmp $FLOPPY_SEGMENT, $code_start-_prefix
|
|
||||||
10: .asciz "PXE->EB "
|
10: .asciz "PXE->EB "
|
||||||
code_start:
|
code_start:
|
||||||
pusha /* Preserve all registers */
|
/* Preserve registers for return to PXE stack */
|
||||||
push %ds
|
pushfl
|
||||||
movw %sp, %bp /* %bp must be preserved, hence do
|
pushal
|
||||||
* this after the pusha */
|
pushw %gs
|
||||||
push $PXE_STACK_MAGIC /* PXE stack magic marker */
|
pushw %fs
|
||||||
|
pushw %es
|
||||||
push %cs /* Set up data segment */
|
pushw %ds
|
||||||
pop %ds
|
pushw %ss
|
||||||
mov $0x40, %cx /* Set up %fs for access to 40:13 */
|
pushw %cs
|
||||||
mov %cx, %fs
|
pushw $PXE_STACK_MAGIC /* PXE stack magic marker */
|
||||||
movw $10b-_prefix, %si /* Print welcome message */
|
/* Set up stack just below 0x7c00 */
|
||||||
|
pushw %ss
|
||||||
|
popw %es
|
||||||
|
movw %sp, %di
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %ss
|
||||||
|
movw $0x7c00, %sp
|
||||||
|
pushw %es /* Save old PXE stack pointer */
|
||||||
|
pushw %di
|
||||||
|
/* Set up our other segment registers */
|
||||||
|
pushw %cs
|
||||||
|
popw %ds
|
||||||
|
movw $0x40, %ax /* BIOS data segment access */
|
||||||
|
movw %ax, %fs
|
||||||
|
/* Print welcome message */
|
||||||
|
movw $10b, %si
|
||||||
call print_message
|
call print_message
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -44,12 +51,12 @@ code_start:
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
detect_pxe:
|
detect_pxe:
|
||||||
les 4+PUSHA_SIZE+2(%bp), %di /* !PXE structure */
|
les %es:54(%di), %di /* !PXE structure */
|
||||||
cmpl $0x45585021, %es:(%di) /* '!PXE' signature */
|
cmpl $0x45585021, %es:(%di) /* '!PXE' signature */
|
||||||
je detected_pxe
|
je detected_pxe
|
||||||
mov $0x5650, %ax
|
movw $0x5650, %ax
|
||||||
int $0x1a
|
int $0x1a
|
||||||
cmp $0x564e, %ax
|
cmpw $0x564e, %ax
|
||||||
jne detected_nothing
|
jne detected_nothing
|
||||||
cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
|
cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
|
||||||
jne detected_nothing
|
jne detected_nothing
|
||||||
|
@ -57,49 +64,45 @@ detect_pxe:
|
||||||
je detected_pxenv
|
je detected_pxenv
|
||||||
|
|
||||||
detected_nothing:
|
detected_nothing:
|
||||||
movw $10f-_prefix, %si
|
movw $10f, %si
|
||||||
call print_message
|
call print_message
|
||||||
jmp finished_with_error
|
jmp finished_with_error
|
||||||
10: .asciz "No PXE "
|
10: .asciz "No PXE "
|
||||||
|
|
||||||
detected_pxenv: /* es:bx points to PXENV+ structure */
|
detected_pxenv: /* es:bx points to PXENV+ structure */
|
||||||
push %es
|
pushw %es
|
||||||
push %bx
|
pushw %bx
|
||||||
push %es:0x24(%bx) /* UNDI code segment */
|
pushw %es:0x24(%bx) /* UNDI code segment */
|
||||||
push %es:0x26(%bx) /* UNDI code size */
|
pushw %es:0x26(%bx) /* UNDI code size */
|
||||||
push %es:0x20(%bx) /* UNDI data segment */
|
pushw %es:0x20(%bx) /* UNDI data segment */
|
||||||
push %es:0x22(%bx) /* UNDI data size */
|
pushw %es:0x22(%bx) /* UNDI data size */
|
||||||
les %es:0x0a(%bx), %di /* Entry point to %es:%di */
|
les %es:0x0a(%bx), %di /* Entry point to %es:%di */
|
||||||
movw $10f-_prefix, %si
|
movw $10f, %si
|
||||||
jmp pxe_setup_done
|
jmp pxe_setup_done
|
||||||
10: .asciz "PXENV+ "
|
10: .asciz "PXENV+ "
|
||||||
|
|
||||||
detected_pxe: /* es:di points to !PXE structure */
|
detected_pxe: /* es:di points to !PXE structure */
|
||||||
push %es
|
pushw %es
|
||||||
push %di
|
pushw %di
|
||||||
push %es:0x30(%di) /* UNDI code segment */
|
pushw %es:0x30(%di) /* UNDI code segment */
|
||||||
push %es:0x36(%di) /* UNDI code size */
|
pushw %es:0x36(%di) /* UNDI code size */
|
||||||
push %es:0x28(%di) /* UNDI data segment */
|
pushw %es:0x28(%di) /* UNDI data segment */
|
||||||
push %es:0x2e(%di) /* UNDI data size */
|
pushw %es:0x2e(%di) /* UNDI data size */
|
||||||
les %es:0x10(%di), %di /* Entry point to %es:%di */
|
les %es:0x10(%di), %di /* Entry point to %es:%di */
|
||||||
movw $10f-_prefix, %si
|
movw $10f, %si
|
||||||
jmp pxe_setup_done
|
jmp pxe_setup_done
|
||||||
10: .asciz "!PXE "
|
10: .asciz "!PXE "
|
||||||
|
|
||||||
pxe_setup_done:
|
pxe_setup_done:
|
||||||
mov %es, pxe_entry_segment - _prefix
|
movw %es, pxe_entry_segment
|
||||||
mov %di, pxe_entry_offset - _prefix
|
movw %di, pxe_entry_offset
|
||||||
pop %ax
|
popw undi_data_size
|
||||||
mov %ax, undi_data_size - _prefix
|
popw undi_data_segment
|
||||||
pop %ax
|
popw undi_code_size
|
||||||
mov %ax, undi_data_segment - _prefix
|
popw undi_code_segment
|
||||||
pop %ax
|
|
||||||
mov %ax, undi_code_size - _prefix
|
|
||||||
pop %ax
|
|
||||||
mov %ax, undi_code_segment - _prefix
|
|
||||||
call print_message
|
call print_message
|
||||||
pop %di
|
popw %di
|
||||||
pop %es /* Exit with %es:%di containing structure address */
|
popw %es /* Exit with %es:%di containing structure address */
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Print information about located structure
|
* Print information about located structure
|
||||||
|
@ -107,11 +110,11 @@ pxe_setup_done:
|
||||||
*/
|
*/
|
||||||
print_structure_information:
|
print_structure_information:
|
||||||
call print_segoff /* %es:%di contains address of structure */
|
call print_segoff /* %es:%di contains address of structure */
|
||||||
les %ds:(pxe_entry_segoff - _prefix), %di
|
les pxe_entry_segoff, %di
|
||||||
call print_segoff
|
call print_segoff
|
||||||
les %ds:(undi_code_segoff - _prefix), %di
|
les undi_code_segoff, %di
|
||||||
call print_segoff
|
call print_segoff
|
||||||
les %ds:(undi_data_segoff - _prefix), %di
|
les undi_data_segoff, %di
|
||||||
call print_segoff
|
call print_segoff
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -119,17 +122,17 @@ print_structure_information:
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
#ifdef PXELOADER_KEEP_ALL
|
#ifdef PXELOADER_KEEP_ALL
|
||||||
xor %ax, %ax /* Force zero flag to show success */
|
xorw %ax, %ax /* Force zero flag to show success */
|
||||||
jmp do_not_free_base_mem /* Skip the unloading */
|
jmp do_not_free_base_mem /* Skip the unloading */
|
||||||
#endif /* PXELOADER_KEEP_ALL */
|
#endif /* PXELOADER_KEEP_ALL */
|
||||||
|
|
||||||
unload_pxe:
|
unload_pxe:
|
||||||
mov $PXENV_UNLOAD_STACK, %bx
|
movw $PXENV_UNLOAD_STACK, %bx
|
||||||
call pxe_call
|
call pxe_call
|
||||||
mov $PXENV_STOP_UNDI, %bx
|
movw $PXENV_STOP_UNDI, %bx
|
||||||
call pxe_call
|
call pxe_call
|
||||||
pushfw /* Ignore PXENV_UNDI_CLEANUP errors */
|
pushfw /* Ignore PXENV_UNDI_CLEANUP errors */
|
||||||
mov $PXENV_UNDI_CLEANUP, %bx
|
movw $PXENV_UNDI_CLEANUP, %bx
|
||||||
call pxe_call
|
call pxe_call
|
||||||
popfw
|
popfw
|
||||||
/* On exit, zero flag is set iff all calls were successful */
|
/* On exit, zero flag is set iff all calls were successful */
|
||||||
|
@ -141,45 +144,45 @@ unload_pxe:
|
||||||
free_base_mem:
|
free_base_mem:
|
||||||
jnz do_not_free_base_mem /* Using zero flag from unload_pxe */
|
jnz do_not_free_base_mem /* Using zero flag from unload_pxe */
|
||||||
|
|
||||||
mov undi_code_segment - _prefix, %bx
|
movw undi_code_segment, %bx
|
||||||
mov undi_data_segment - _prefix, %cx
|
movw undi_data_segment, %cx
|
||||||
mov undi_code_size - _prefix, %ax
|
movw undi_code_size, %ax
|
||||||
cmp %bx, %cx
|
cmpw %bx, %cx
|
||||||
jb 1f
|
jb 1f
|
||||||
mov %cx, %bx
|
movw %cx, %bx
|
||||||
mov undi_data_size - _prefix, %ax
|
movw undi_data_size, %ax
|
||||||
1: add $0x0f, %ax /* Round up to next segment */
|
1: addw $0x0f, %ax /* Round up to next segment */
|
||||||
shr $4, %ax
|
shrw $4, %ax
|
||||||
add %bx, %ax /* Highest segment address into %ax */
|
addw %bx, %ax /* Highest segment address into %ax */
|
||||||
add $(1024 / 16 - 1), %ax /* Round up to next kb */
|
addw $(1024 / 16 - 1), %ax /* Round up to next kb */
|
||||||
shr $6, %ax /* New free basemem size in %ax */
|
shrw $6, %ax /* New free basemem size in %ax */
|
||||||
mov %fs:(0x13), %bx /* Old free base memory in %bx */
|
movw %fs:(0x13), %bx /* Old free base memory in %bx */
|
||||||
mov %ax, %fs:(0x13) /* Store new free base memory size */
|
movw %ax, %fs:(0x13) /* Store new free base memory size */
|
||||||
|
|
||||||
/* Note that zero_mem_loop will also zero out our stack, so make
|
/* Note that zero_mem_loop will also zero out our stack, so make
|
||||||
* sure the stack is empty at this point.
|
* sure the stack is empty at this point.
|
||||||
*/
|
*/
|
||||||
mov %ax, %dx
|
movw %ax, %dx
|
||||||
sub %bx, %dx /* numberof kb to zero in %dx */
|
subw %bx, %dx /* numberof kb to zero in %dx */
|
||||||
shl $6, %bx /* Segment address into %bx */
|
shlw $6, %bx /* Segment address into %bx */
|
||||||
zero_mem_loop:
|
zero_mem_loop:
|
||||||
mov %bx, %es /* kB boundary into %es:00 */
|
movw %bx, %es /* kB boundary into %es:00 */
|
||||||
xor %ax, %ax
|
xorw %ax, %ax
|
||||||
xor %di, %di
|
xorw %di, %di
|
||||||
mov $0x400, %cx
|
movw $0x400, %cx
|
||||||
rep stosb /* fill kB with zeroes */
|
rep stosb /* fill kB with zeroes */
|
||||||
add $(1024 / 16), %bx
|
addw $(1024 / 16), %bx
|
||||||
dec %dx
|
decw %dx
|
||||||
jnz zero_mem_loop
|
jnz zero_mem_loop
|
||||||
/* Will exit here with zero flag set, so no need to set it explicitly
|
/* Will exit here with zero flag set, so no need to set it explicitly
|
||||||
* in order to indicate success.
|
* in order to indicate success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
do_not_free_base_mem:
|
do_not_free_base_mem:
|
||||||
pushf /* Save success (zero) flag status */
|
pushfw /* Save success (zero) flag status */
|
||||||
mov %fs:(0x13), %ax /* Free base memory in %ax */
|
movw %fs:(0x13), %ax /* Free base memory in %ax */
|
||||||
call print_hex_word /* Print free base memory */
|
call print_hex_word /* Print free base memory */
|
||||||
popf /* Restore success (zero) flag */
|
popfw /* Restore success (zero) flag */
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Exit point
|
* Exit point
|
||||||
|
@ -188,92 +191,16 @@ do_not_free_base_mem:
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
finished:
|
finished:
|
||||||
movw $10f-_prefix, %si
|
movw $10f, %si
|
||||||
jz 1f
|
jz 1f
|
||||||
finished_with_error:
|
finished_with_error:
|
||||||
movw $20f-_prefix, %si
|
movw $20f, %si
|
||||||
1:
|
1:
|
||||||
call print_message
|
call print_message
|
||||||
jmp 99f
|
jmp run_etherboot
|
||||||
10: .asciz " ok\n"
|
10: .asciz " ok\n"
|
||||||
20: .asciz " err\n"
|
20: .asciz " err\n"
|
||||||
|
|
||||||
|
|
||||||
/* We place a stack here. It doesn't get used until after all
|
|
||||||
* the above code is finished, so we can happily write all
|
|
||||||
* over it. Putting the stack here ensures that it doesn't
|
|
||||||
* accidentally go over the 512 byte threshold, which would
|
|
||||||
* cause problems when returning via start32's prefix
|
|
||||||
* relocation mechanism.
|
|
||||||
*/
|
|
||||||
_estack:
|
|
||||||
99:
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Run Etherboot main code
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
run_etherboot:
|
|
||||||
/* Very temporarily switch stacks to one internal to the
|
|
||||||
* prefix. Do this because the stack provided by the PXE ROM
|
|
||||||
* could be absolutely anywhere, including in an area of
|
|
||||||
* memory that the call to prelocate will vapourise...
|
|
||||||
*/
|
|
||||||
pushw %ss /* PXE stack pointer to ES:DI */
|
|
||||||
popw %es
|
|
||||||
movw %sp, %di
|
|
||||||
pushw %ds /* Set up stack in "safe" area */
|
|
||||||
popw %ss
|
|
||||||
movw $_estack-_prefix, %sp
|
|
||||||
pushw %es /* Record PXE stack pointer */
|
|
||||||
pushw %di
|
|
||||||
/* Relocate payload and stack to claimed base memory */
|
|
||||||
pushw $4 /* Preserve old PXE stack pointer */
|
|
||||||
call prelocate
|
|
||||||
popw %ax /* Remove parameter */
|
|
||||||
pushl $4 /* Preserve old PXE stack pointer */
|
|
||||||
pushw $0 /* Indicate prefix exit mechanism */
|
|
||||||
jmp _start /* Run Etherboot */
|
|
||||||
|
|
||||||
.section ".text16", "ax", @progbits
|
|
||||||
prefix_exit:
|
|
||||||
pushw %cs /* Set %ds, %bp for access to text */
|
|
||||||
popw %ds
|
|
||||||
call 1f
|
|
||||||
1: popw %bp
|
|
||||||
popw %di /* Old PXE stack to %es:di */
|
|
||||||
popw %es
|
|
||||||
cmpw $PXE_STACK_MAGIC, %es:0(%di) /* See if PXE stack intact */
|
|
||||||
jne exit_via_int18
|
|
||||||
exit_via_pxe: /* Stack OK, return to PXE */
|
|
||||||
push %es /* Restore PXE stack pointer */
|
|
||||||
pop %ss
|
|
||||||
mov %di, %sp
|
|
||||||
pop %ax /* Discard PXE_STACK_MAGIC marker */
|
|
||||||
leaw (10f-1b)(%bp), %si
|
|
||||||
call print_exit_message
|
|
||||||
pop %ds /* Restore PXE's DS */
|
|
||||||
popa /* Restore PXE's other registers */
|
|
||||||
movw $0, %ax /* Return PXENV_STATUS_SUCCESS */
|
|
||||||
lret /* Return control to PXE ROM */
|
|
||||||
10: .asciz "EB->PXE\r\n"
|
|
||||||
exit_via_int18: /* Stack damaged, do int 18 */
|
|
||||||
leaw (10f-1b)(%bp), %si
|
|
||||||
call print_exit_message
|
|
||||||
int $0x18
|
|
||||||
10: .asciz "EB->BIOS\r\n"
|
|
||||||
print_exit_message:
|
|
||||||
movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
|
||||||
movb $0x0e, %ah /* write char, tty mode */
|
|
||||||
1: lodsb
|
|
||||||
testb %al, %al
|
|
||||||
je 2f
|
|
||||||
int $0x10
|
|
||||||
jmp 1b
|
|
||||||
2: ret
|
|
||||||
prefix_exit_end:
|
|
||||||
.previous
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Subroutine: print character in %al (with LF -> LF,CR translation)
|
* Subroutine: print character in %al (with LF -> LF,CR translation)
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
@ -305,17 +232,17 @@ print_message:
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
print_hex_word:
|
print_hex_word:
|
||||||
mov $4, %cx
|
movw $4, %cx
|
||||||
1:
|
1:
|
||||||
push %ax
|
pushw %ax
|
||||||
shr $12, %ax
|
shrw $12, %ax
|
||||||
/* Courtesy of Norbert Juffa <norbert.juffa@amd.com> */
|
/* Courtesy of Norbert Juffa <norbert.juffa@amd.com> */
|
||||||
cmp $10, %al
|
cmpb $10, %al
|
||||||
sbb $0x69, %al
|
sbbb $0x69, %al
|
||||||
das
|
das
|
||||||
call print_character
|
call print_character
|
||||||
pop %ax
|
popw %ax
|
||||||
shl $4, %ax
|
shlw $4, %ax
|
||||||
loop 1b
|
loop 1b
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -324,15 +251,15 @@ print_hex_word:
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*/
|
*/
|
||||||
print_segoff:
|
print_segoff:
|
||||||
push %di
|
pushw %di
|
||||||
push %es
|
pushw %es
|
||||||
pop %ax
|
popw %ax
|
||||||
call print_hex_word
|
call print_hex_word
|
||||||
movb $0x3a,%al /* ':' */
|
movb $0x3a,%al /* ':' */
|
||||||
call print_character
|
call print_character
|
||||||
pop %ax
|
popw %ax
|
||||||
call print_hex_word
|
call print_hex_word
|
||||||
mov $0x20, %al /* ' ' */
|
movb $0x20, %al /* ' ' */
|
||||||
call print_character
|
call print_character
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -346,24 +273,24 @@ print_segoff:
|
||||||
*/
|
*/
|
||||||
pxe_call:
|
pxe_call:
|
||||||
/* Set up registers for PXENV+ API. %bx already set up */
|
/* Set up registers for PXENV+ API. %bx already set up */
|
||||||
push %ds
|
pushw %ds
|
||||||
pop %es
|
popw %es
|
||||||
mov $pxe_parameter_structure - _prefix, %di
|
movw $pxe_parameter_structure, %di
|
||||||
/* Set up stack for !PXE API */
|
/* Set up stack for !PXE API */
|
||||||
pushw %cs
|
pushw %cs
|
||||||
pushw %di
|
pushw %di
|
||||||
pushw %bx
|
pushw %bx
|
||||||
/* Make the API call */
|
/* Make the API call */
|
||||||
lcall *(pxe_entry_segoff - _prefix)
|
lcall *pxe_entry_segoff
|
||||||
/* Reset the stack */
|
/* Reset the stack */
|
||||||
add $6, %sp
|
addw $6, %sp
|
||||||
mov pxe_parameter_structure - _prefix, %ax
|
movw pxe_parameter_structure, %ax
|
||||||
push %ax
|
pushw %ax
|
||||||
call print_hex_word
|
call print_hex_word
|
||||||
mov $0x20, %ax /* ' ' */
|
movw $0x20, %ax /* ' ' */
|
||||||
call print_character
|
call print_character
|
||||||
pop %bx
|
popw %bx
|
||||||
or %bx, pxe_overall_status - _prefix
|
orw %bx, pxe_overall_status
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -389,7 +316,73 @@ pxe_parameter_structure:
|
||||||
.word 0
|
.word 0
|
||||||
.word 0,0,0,0,0
|
.word 0,0,0,0,0
|
||||||
|
|
||||||
end_of_pxeloader:
|
/*****************************************************************************
|
||||||
|
* Run Etherboot main code
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
run_etherboot:
|
||||||
|
/* Install Etherboot */
|
||||||
|
call install
|
||||||
|
|
||||||
.balign 16, 0
|
/* Jump to .text16 segment with %ds pointing to .data16*/
|
||||||
payload:
|
movw %bx, %ds
|
||||||
|
pushw %ax
|
||||||
|
pushw $1f
|
||||||
|
lret
|
||||||
|
.section ".text16", "ax", @progbits
|
||||||
|
1:
|
||||||
|
/* Original PXE stack pointer to es:di. We must hold it in
|
||||||
|
* registers, because our current stack may be vapourised by
|
||||||
|
* the time main() returns. (main() will still be able to
|
||||||
|
* return, because prot_call() transfers the return address to
|
||||||
|
* the internal stack and back again).
|
||||||
|
*/
|
||||||
|
popw %di
|
||||||
|
popw %es
|
||||||
|
|
||||||
|
/* Run main program */
|
||||||
|
pushl $main
|
||||||
|
pushw %cs
|
||||||
|
call prot_call
|
||||||
|
popl %eax /* discard */
|
||||||
|
|
||||||
|
/* If original PXE stack is intact, return via PXE, else via INT 18 */
|
||||||
|
cmpw $PXE_STACK_MAGIC, %es:0(%di)
|
||||||
|
jne exit_via_int18
|
||||||
|
exit_via_pxe: /* Stack OK, return to PXE */
|
||||||
|
movw $exit_via_pxe_message, %si
|
||||||
|
call print_exit_message
|
||||||
|
pushw %es /* Restore original PXE stack */
|
||||||
|
popw %ss
|
||||||
|
movw %di, %sp
|
||||||
|
popw %ax /* discard PXE_STACK_MAGIC */
|
||||||
|
popw %ax /* discard %cs */
|
||||||
|
popw %ax /* discard %ss */
|
||||||
|
popw %ds
|
||||||
|
popw %es
|
||||||
|
popw %fs
|
||||||
|
popw %gs
|
||||||
|
popal
|
||||||
|
popfl
|
||||||
|
xorw %ax, %ax /* Return PXENV_STATUS_SUCCESS */
|
||||||
|
lret
|
||||||
|
exit_via_int18: /* Stack damaged, do int 18 */
|
||||||
|
movw $exit_via_int18_message, %si
|
||||||
|
call print_exit_message
|
||||||
|
int $0x18
|
||||||
|
|
||||||
|
print_exit_message:
|
||||||
|
movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
||||||
|
movb $0x0e, %ah /* write char, tty mode */
|
||||||
|
1: lodsb
|
||||||
|
testb %al, %al
|
||||||
|
je 2f
|
||||||
|
int $0x10
|
||||||
|
jmp 1b
|
||||||
|
2: ret
|
||||||
|
|
||||||
|
.section ".data16", "aw", @progbits
|
||||||
|
exit_via_pxe_message:
|
||||||
|
.asciz "EB->PXE\r\n"
|
||||||
|
exit_via_int18_message:
|
||||||
|
.asciz "EB->BIOS\r\n"
|
||||||
|
|
Loading…
Reference in New Issue