david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[prefix] Use .bss16 as temporary stack space for calls to install_block

Some decompression algorithms (e.g. LZMA) require large amounts of
temporary stack space, which may not be made available by all
prefixes.  Use .bss16 as a temporary stack for the duration of the
calls to install_block (switching back to the external stack before we
start making calls into code which might access variables in .bss16),
and allow the decompressor to define a global symbol to force a
minimum value on the size of .bss16.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2015-02-24 16:13:55 +00:00
parent b6889eaa1e
commit 3e04f0791e
2 changed files with 46 additions and 11 deletions

View File

@ -296,11 +296,9 @@ copy_bytes:
* Zero bytes
*
* Parameters:
* %ds:esi : source address
* %es:edi : destination address
* %ecx : length
* Returns:
* %ds:esi : next source address
* %es:edi : next destination address
* Corrupts:
* None
@ -678,12 +676,21 @@ install:
.globl install_prealloc
install_prealloc:
progress "install_prealloc:\n"
/* Save registers */
/* Save registers on external stack */
pushal
pushw %ds
pushw %es
cld /* Sanity: clear the direction flag asap */
/* Switch to temporary stack in .bss16 */
pushw %ss
popw %ds
movl %esp, %ecx
movw %bx, %ss
movl $_data16_memsz, %esp
pushw %ds
pushl %ecx
/* Set up %ds for (read-only) access to .prefix */
pushw %cs
popw %ds
@ -710,6 +717,7 @@ install_prealloc:
popl %esi
#ifndef KEEP_IT_REAL
/* Access high memory by enabling the A20 gate. (We will
* already have 4GB segment limits as a result of calling
* install_block.)
@ -778,7 +786,7 @@ payload_death_message:
movzwl %bx, %edi
shll $4, %edi
movl $_data16_filesz, %ecx
movl $_data16_memsz, %edx
movl $_data16_filesz, %edx /* do not zero our temporary stack */
call install_block /* .data16 */
/* Set up %ds for access to .data16 */
@ -787,11 +795,8 @@ payload_death_message:
/* Restore decompression temporary area physical address */
popl %edi
#ifdef KEEP_IT_REAL
/* Initialise libkir */
movw %ax, (init_libkir_vector+2)
lcall *init_libkir_vector
#else
#ifndef KEEP_IT_REAL
/* Find a suitable decompression temporary area, if none specified */
pushl %eax
testl %edi, %edi
@ -823,6 +828,22 @@ payload_death_message:
call install_block
popl %edi
#endif /* KEEP_IT_REAL */
/* Switch back to original stack and zero .bss16 */
lss %ss:(%esp), %esp
pushl %edi
pushw %es
movw %bx, %es
movl $_data16_filesz, %edi
movl $_data16_memsz, %ecx
subl %edi, %ecx
call zero_bytes
popw %es
popl %edi
#ifndef KEEP_IT_REAL
/* Initialise librm at current location */
progress " init_librm\n"
movw %ax, (init_librm_vector+2)
@ -834,7 +855,6 @@ payload_death_message:
incb memmap_post
decl %ebp
1:
/* Call relocate() to determine target address for relocation.
* relocate() will return with %esi, %edi and %ecx set up
* ready for the copy to the new location.
@ -857,7 +877,14 @@ payload_death_message:
/* Initialise librm at new location */
progress " init_librm\n"
lcall *init_librm_vector
#endif
#else /* KEEP_IT_REAL */
/* Initialise libkir */
movw %ax, (init_libkir_vector+2)
lcall *init_libkir_vector
#endif /* KEEP_IT_REAL */
/* Close access to payload */
progress " close_payload\n"

View File

@ -26,6 +26,13 @@ SECTIONS {
PROVIDE ( _max_align = 16 );
/*
* Allow decompressor to require a minimum amount of temporary stack
* space.
*
*/
PROVIDE ( _min_decompress_stack = 0 );
/*
* The prefix
*
@ -87,6 +94,7 @@ SECTIONS {
*(.bss16.*)
*(.stack16)
*(.stack16.*)
. = MAX ( ., _mdata16 + _min_decompress_stack );
_edata16 = .;
}
_data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );