]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[prefix] Use .bss16 as temporary stack space for calls to install_block
authorMichael Brown <mcb30@ipxe.org>
Tue, 24 Feb 2015 16:13:55 +0000 (16:13 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 24 Feb 2015 16:33:14 +0000 (16:33 +0000)
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>
src/arch/i386/prefix/libprefix.S
src/arch/i386/scripts/i386.lds

index 7c1ece791b54cd45987b0c57e1cd6611a56e7955..0be96798be89e8a1ee1f521577bdc071f80d8af3 100644 (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"
index 98f95cb23a4415b90a981e157168cd0180e18c34..348dfefae2217aebbd8fb085c1d769fdf63038b3 100644 (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 );