Skip to content

Commit

Permalink
[prefix] Use .bss16 as temporary stack space for calls to install_block
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mcb30 committed Feb 24, 2015
1 parent b6889ea commit 3e04f07
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
49 changes: 38 additions & 11 deletions src/arch/i386/prefix/libprefix.S
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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.)
Expand Down Expand Up @@ -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 */
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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.
Expand All @@ -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"
Expand Down
8 changes: 8 additions & 0 deletions src/arch/i386/scripts/i386.lds
Expand Up @@ -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
*
Expand Down Expand Up @@ -87,6 +94,7 @@ SECTIONS {
*(.bss16.*)
*(.stack16)
*(.stack16.*)
. = MAX ( ., _mdata16 + _min_decompress_stack );
_edata16 = .;
}
_data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
Expand Down

0 comments on commit 3e04f07

Please sign in to comment.