diff options
author | Michael Brown <mcb30@ipxe.org> | 2015-02-24 16:13:55 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2015-02-24 16:33:14 +0000 |
commit | 3e04f0791e614772f3ffe3663e4c8da71e2bc981 (patch) | |
tree | 541275eaab72461b99f646c2e1876595199dad3e /src/arch | |
parent | b6889eaa1ea5685a06b13a03337c0e0d7e3bd251 (diff) | |
download | ipxe-3e04f0791e614772f3ffe3663e4c8da71e2bc981.tar.gz |
[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>
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/i386/prefix/libprefix.S | 49 | ||||
-rw-r--r-- | src/arch/i386/scripts/i386.lds | 8 |
2 files changed, 46 insertions, 11 deletions
diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 7c1ece79..0be96798 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -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" diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 98f95cb2..348dfefa 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -27,6 +27,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 ); |