diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 7c1ece791..0be96798b 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 98f95cb23..348dfefae 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -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 );