Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
3e04f0791e
2 changed files with 46 additions and 11 deletions
  1. 38
    11
      src/arch/i386/prefix/libprefix.S
  2. 8
    0
      src/arch/i386/scripts/i386.lds

+ 38
- 11
src/arch/i386/prefix/libprefix.S View File

296
  * Zero bytes
296
  * Zero bytes
297
  *
297
  *
298
  * Parameters:
298
  * Parameters:
299
- *   %ds:esi : source address
300
  *   %es:edi : destination address
299
  *   %es:edi : destination address
301
  *   %ecx : length
300
  *   %ecx : length
302
  * Returns:
301
  * Returns:
303
- *   %ds:esi : next source address
304
  *   %es:edi : next destination address
302
  *   %es:edi : next destination address
305
  * Corrupts:
303
  * Corrupts:
306
  *   None
304
  *   None
678
 	.globl install_prealloc
676
 	.globl install_prealloc
679
 install_prealloc:
677
 install_prealloc:
680
 	progress "install_prealloc:\n"
678
 	progress "install_prealloc:\n"
681
-	/* Save registers */
679
+	/* Save registers on external stack */
682
 	pushal
680
 	pushal
683
 	pushw	%ds
681
 	pushw	%ds
684
 	pushw	%es
682
 	pushw	%es
685
 	cld			/* Sanity: clear the direction flag asap */
683
 	cld			/* Sanity: clear the direction flag asap */
686
 
684
 
685
+	/* Switch to temporary stack in .bss16 */
686
+	pushw	%ss
687
+	popw	%ds
688
+	movl	%esp, %ecx
689
+	movw	%bx, %ss
690
+	movl	$_data16_memsz, %esp
691
+	pushw	%ds
692
+	pushl	%ecx
693
+
687
 	/* Set up %ds for (read-only) access to .prefix */
694
 	/* Set up %ds for (read-only) access to .prefix */
688
 	pushw	%cs
695
 	pushw	%cs
689
 	popw	%ds
696
 	popw	%ds
710
 	popl	%esi
717
 	popl	%esi
711
 
718
 
712
 #ifndef KEEP_IT_REAL
719
 #ifndef KEEP_IT_REAL
720
+
713
 	/* Access high memory by enabling the A20 gate.  (We will
721
 	/* Access high memory by enabling the A20 gate.  (We will
714
 	 * already have 4GB segment limits as a result of calling
722
 	 * already have 4GB segment limits as a result of calling
715
 	 * install_block.)
723
 	 * install_block.)
778
 	movzwl	%bx, %edi
786
 	movzwl	%bx, %edi
779
 	shll	$4, %edi
787
 	shll	$4, %edi
780
 	movl	$_data16_filesz, %ecx
788
 	movl	$_data16_filesz, %ecx
781
-	movl	$_data16_memsz, %edx
789
+	movl	$_data16_filesz, %edx	/* do not zero our temporary stack */
782
 	call	install_block		/* .data16 */
790
 	call	install_block		/* .data16 */
783
 
791
 
784
 	/* Set up %ds for access to .data16 */
792
 	/* Set up %ds for access to .data16 */
787
 	/* Restore decompression temporary area physical address */
795
 	/* Restore decompression temporary area physical address */
788
 	popl	%edi
796
 	popl	%edi
789
 
797
 
790
-#ifdef KEEP_IT_REAL
791
-	/* Initialise libkir */
792
-	movw	%ax, (init_libkir_vector+2)
793
-	lcall	*init_libkir_vector
794
-#else
798
+#ifndef KEEP_IT_REAL
799
+
795
 	/* Find a suitable decompression temporary area, if none specified */
800
 	/* Find a suitable decompression temporary area, if none specified */
796
 	pushl	%eax
801
 	pushl	%eax
797
 	testl	%edi, %edi
802
 	testl	%edi, %edi
823
 	call	install_block
828
 	call	install_block
824
 	popl	%edi
829
 	popl	%edi
825
 
830
 
831
+#endif /* KEEP_IT_REAL */
832
+
833
+	/* Switch back to original stack and zero .bss16 */
834
+	lss	%ss:(%esp), %esp
835
+	pushl	%edi
836
+	pushw	%es
837
+	movw	%bx, %es
838
+	movl	$_data16_filesz, %edi
839
+	movl	$_data16_memsz, %ecx
840
+	subl	%edi, %ecx
841
+	call	zero_bytes
842
+	popw	%es
843
+	popl	%edi
844
+
845
+#ifndef KEEP_IT_REAL
846
+
826
 	/* Initialise librm at current location */
847
 	/* Initialise librm at current location */
827
 	progress "  init_librm\n"
848
 	progress "  init_librm\n"
828
 	movw	%ax, (init_librm_vector+2)
849
 	movw	%ax, (init_librm_vector+2)
834
 	incb	memmap_post
855
 	incb	memmap_post
835
 	decl	%ebp
856
 	decl	%ebp
836
 1:
857
 1:
837
-
838
 	/* Call relocate() to determine target address for relocation.
858
 	/* Call relocate() to determine target address for relocation.
839
 	 * relocate() will return with %esi, %edi and %ecx set up
859
 	 * relocate() will return with %esi, %edi and %ecx set up
840
 	 * ready for the copy to the new location.
860
 	 * ready for the copy to the new location.
857
 	/* Initialise librm at new location */
877
 	/* Initialise librm at new location */
858
 	progress "  init_librm\n"
878
 	progress "  init_librm\n"
859
 	lcall	*init_librm_vector
879
 	lcall	*init_librm_vector
860
-#endif
880
+
881
+#else /* KEEP_IT_REAL */
882
+
883
+	/* Initialise libkir */
884
+	movw	%ax, (init_libkir_vector+2)
885
+	lcall	*init_libkir_vector
886
+
887
+#endif /* KEEP_IT_REAL */
861
 
888
 
862
 	/* Close access to payload */
889
 	/* Close access to payload */
863
 	progress "  close_payload\n"
890
 	progress "  close_payload\n"

+ 8
- 0
src/arch/i386/scripts/i386.lds View File

26
 
26
 
27
     PROVIDE ( _max_align = 16 );
27
     PROVIDE ( _max_align = 16 );
28
 
28
 
29
+    /*
30
+     * Allow decompressor to require a minimum amount of temporary stack
31
+     * space.
32
+     *
33
+     */
34
+    PROVIDE ( _min_decompress_stack = 0 );
35
+
29
     /*
36
     /*
30
      * The prefix
37
      * The prefix
31
      *
38
      *
87
 	*(.bss16.*)
94
 	*(.bss16.*)
88
 	*(.stack16)
95
 	*(.stack16)
89
 	*(.stack16.*)
96
 	*(.stack16.*)
97
+	. = MAX ( ., _mdata16 + _min_decompress_stack );
90
 	_edata16 = .;
98
 	_edata16 = .;
91
     }
99
     }
92
     _data16_filesz	= ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
100
     _data16_filesz	= ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );

Loading…
Cancel
Save