david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

New strategy: always stop both base code and UNDI. Always free base code

memory (unless we get an error while stopping the base code).  Leave UNDI
resident (though stopped) for .kpxe.

Still need to add code to record the device identification parameters
prior to stopping UNDI.
This commit is contained in:
Michael Brown 2007-01-08 03:48:26 +00:00
parent 075d79f6d4
commit 8f8af10b22
2 changed files with 89 additions and 72 deletions

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* PXE prefix that keep the PXE stack present * PXE prefix that keep the UNDI portion of the PXE stack present
***************************************************************************** *****************************************************************************
*/ */
#define PXELOADER_KEEP_ALL #define PXELOADER_KEEP_UNDI
#include "pxeprefix.S" #include "pxeprefix.S"

View File

@ -1,5 +1,3 @@
#define PXENV_UNDI_CLEANUP 0x02
#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
@ -118,88 +116,76 @@ print_structure_information:
call print_segoff call print_segoff
/***************************************************************************** /*****************************************************************************
* Unload PXE base code and UNDI driver * Calculate base memory usage by UNDI
***************************************************************************** *****************************************************************************
*/ */
#ifdef PXELOADER_KEEP_ALL find_undi_basemem_usage:
xorw %ax, %ax /* Force zero flag to show success */ movw undi_code_segment, %ax
jmp do_not_free_base_mem /* Skip the unloading */ movw undi_code_size, %bx
#endif /* PXELOADER_KEEP_ALL */ movw undi_data_segment, %cx
movw undi_data_size, %dx
unload_pxe: cmpw %ax, %cx
ja 1f
xchgw %ax, %cx
xchgw %bx, %dx
1: /* %ax:%bx now describes the lower region, %cx:%dx the higher */
shrw $6, %ax /* Round down to nearest kB */
movw %ax, undi_fbms_start
addw $0x0f, %dx /* Round up to next segment */
shrw $4, %dx
addw %dx, %cx
addw $((1024 / 16) - 1), %cx /* Round up to next kB */
shrw $6, %cx
movw %cx, undi_fbms_end
/*****************************************************************************
* Unload PXE base code
*****************************************************************************
*/
unload_base_code:
movw $PXENV_STOP_BASE, %bx
call pxe_call
movw $PXENV_UNLOAD_STACK, %bx movw $PXENV_UNLOAD_STACK, %bx
call pxe_call call pxe_call
movw $PXENV_STOP_UNDI, %bx jnz do_not_free_base_code
call pxe_call free_base_code:
pushfw /* Ignore PXENV_UNDI_CLEANUP errors */ movw %fs:(0x13), %si
movw $PXENV_UNDI_CLEANUP, %bx movw undi_fbms_start, %di
call pxe_call call free_basemem
popfw do_not_free_base_code:
/* On exit, zero flag is set iff all calls were successful */
/***************************************************************************** /*****************************************************************************
* Free base memory * Unload UNDI driver
***************************************************************************** *****************************************************************************
*/ */
free_base_mem: unload_undi:
jnz do_not_free_base_mem /* Using zero flag from unload_pxe */ movw $PXENV_STOP_UNDI, %bx
call pxe_call
movw undi_code_segment, %bx #ifndef PXELOADER_KEEP_UNDI
movw undi_data_segment, %cx jnz do_not_free_undi
movw undi_code_size, %ax free_undi:
cmpw %bx, %cx movw undi_fbms_start, %si
jb 1f movw undi_fbms_end, %di
movw %cx, %bx call free_basemem
movw undi_data_size, %ax do_not_free_undi:
1: addw $0x0f, %ax /* Round up to next segment */ #endif /* PXELOADER_KEEP_UNDI */
shrw $4, %ax
addw %bx, %ax /* Highest segment address into %ax */
addw $(1024 / 16 - 1), %ax /* Round up to next kb */
shrw $6, %ax /* New free basemem size in %ax */
movw %fs:(0x13), %bx /* Old free base memory in %bx */
movw %ax, %fs:(0x13) /* Store new free base memory size */
/* Note that zero_mem_loop will also zero out our stack, so make
* sure the stack is empty at this point.
*/
movw %ax, %dx
subw %bx, %dx /* numberof kb to zero in %dx */
shlw $6, %bx /* Segment address into %bx */
zero_mem_loop:
movw %bx, %es /* kB boundary into %es:00 */
xorw %ax, %ax
xorw %di, %di
movw $0x400, %cx
rep stosb /* fill kB with zeroes */
addw $(1024 / 16), %bx
decw %dx
jnz zero_mem_loop
/* Will exit here with zero flag set, so no need to set it explicitly
* in order to indicate success.
*/
do_not_free_base_mem:
pushfw /* Save success (zero) flag status */
movw %fs:(0x13), %ax /* Free base memory in %ax */
call print_hex_word /* Print free base memory */
popfw /* Restore success (zero) flag */
/***************************************************************************** /*****************************************************************************
* Exit point * Exit point
* Jump to finished with the zero flag set to indicate success, or to
* finished_with_error to always report an error
***************************************************************************** *****************************************************************************
*/ */
finished: finished:
movw $10f, %si movw $10f, %si
movw pxe_overall_status, %ax
testw %ax, %ax
jz 1f jz 1f
finished_with_error: finished_with_error:
movw $20f, %si movw $20f, %si
1: 1:
call print_message call print_message
jmp run_etherboot jmp run_etherboot
10: .asciz " ok\n" 10: .asciz "ok\n"
20: .asciz " err\n" 20: .asciz "err\n"
/***************************************************************************** /*****************************************************************************
* Subroutine: print character in %al (with LF -> LF,CR translation) * Subroutine: print character in %al (with LF -> LF,CR translation)
@ -262,13 +248,40 @@ print_segoff:
movb $0x20, %al /* ' ' */ movb $0x20, %al /* ' ' */
call print_character call print_character
ret ret
/*****************************************************************************
* Subroutine: free and zero base memory from %si kB to %di kB
*****************************************************************************
*/
free_basemem:
movw %fs:(0x13), %ax /* Current FBMS to %ax */
cmpw %ax, %si /* Update FBMS only if "old" value */
jne 1f /* is correct */
movw %di, %fs:(0x13)
1: movw %di, %bx
zero_kb:
movw %si, %ax /* Zero kB at %si */
shlw $6, %ax
movw %ax, %es
xorw %ax, %ax
xorw %di, %di
movw $0x400, %cx
rep stosb
incw %si /* Move to next kB */
cmpw %si, %bx
jne zero_kb /* Loop until done */
movw %fs:(0x13), %ax /* Print free base memory */
call print_hex_word
movb $0x20, %al /* ' ' */
call print_character
ret
/***************************************************************************** /*****************************************************************************
* Make a PXE API call. Works with either !PXE or PXENV+ API. * Make a PXE API call. Works with either !PXE or PXENV+ API.
* Opcode in %bx. pxe_parameter_structure always used. * Opcode in %bx. pxe_parameter_structure always used.
* Returns status code (not exit code) in %bx and prints it. *
* ORs status code with overall status code in pxe_overall_status, returns * Returns status code (not exit code) in %bx and prints it. Returns
* with zero flag set iff all PXE API calls have been successful. * with zero flag set if status code is zero (PXENV_STATUS_SUCCESS).
***************************************************************************** *****************************************************************************
*/ */
pxe_call: pxe_call:
@ -291,6 +304,7 @@ pxe_call:
call print_character call print_character
popw %bx popw %bx
orw %bx, pxe_overall_status orw %bx, pxe_overall_status
testw %bx, %bx
ret ret
/***************************************************************************** /*****************************************************************************
@ -298,8 +312,6 @@ pxe_call:
***************************************************************************** *****************************************************************************
*/ */
pxe_overall_status: .word 0
pxe_entry_segoff: pxe_entry_segoff:
pxe_entry_offset: .word 0 pxe_entry_offset: .word 0
pxe_entry_segment: .word 0 pxe_entry_segment: .word 0
@ -312,10 +324,15 @@ undi_data_segoff:
undi_data_size: .word 0 undi_data_size: .word 0
undi_data_segment: .word 0 undi_data_segment: .word 0
undi_fbms_start: .word 0
undi_fbms_end: .word 0
pxe_parameter_structure: pxe_parameter_structure:
.word 0 .word 0
.word 0,0,0,0,0 .word 0,0,0,0,0
pxe_overall_status: .word 0
/***************************************************************************** /*****************************************************************************
* Run Etherboot main code * Run Etherboot main code
***************************************************************************** *****************************************************************************