x86: boot protocol updates
[sfrench/cifs-2.6.git] / arch / x86 / boot / header.S
index 8353c81c41c02865384e227b24e4af8e0879bcee..6d2df8d61c54089a553c0cdee879dde6f421130c 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/page.h>
 #include <asm/setup.h>
 #include "boot.h"
+#include "offsets.h"
 
 SETUPSECTS     = 4                     /* default nr of setup-sectors */
 BOOTSEG                = 0x07C0                /* original address of boot-sector */
@@ -119,7 +120,7 @@ _start:
        # Part 2 of the header, from the old setup.S
 
                .ascii  "HdrS"          # header signature
-               .word   0x0207          # header version number (>= 0x0105)
+               .word   0x0208          # header version number (>= 0x0105)
                                        # or else old loadlin-1.5 will fail)
                .globl realmode_swtch
 realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
@@ -173,7 +174,8 @@ ramdisk_size:       .long   0               # its size in bytes
 bootsect_kludge:
                .long   0               # obsolete
 
-heap_end_ptr:  .word   _end+1024       # (Header version 0x0201 or later)
+heap_end_ptr:  .word   _end+STACK_SIZE-512
+                                       # (Header version 0x0201 or later)
                                        # space from here (exclusive) down to
                                        # end of setup code can be used by setup
                                        # for local heap purposes.
@@ -194,10 +196,13 @@ cmd_line_ptr:     .long   0               # (Header version 0x0202 or later)
                                        # can be located anywhere in
                                        # low memory 0x10000 or higher.
 
-ramdisk_max:   .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
+ramdisk_max:   .long 0x7fffffff
                                        # (Header version 0x0203 or later)
                                        # The highest safe address for
                                        # the contents of an initrd
+                                       # The current kernel allows up to 4 GB,
+                                       # but leave it at 2 GB to avoid
+                                       # possible bootloader bugs.
 
 kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
                                                #required for protected mode
@@ -219,6 +224,9 @@ hardware_subarch:   .long 0                 # subarchitecture, added with 2.07
 
 hardware_subarch_data: .quad 0
 
+payload_offset:                .long input_data
+payload_length:                .long input_data_end-input_data
+
 # End of setup header #####################################################
 
        .section ".inittext", "ax"
@@ -230,28 +238,44 @@ start_of_setup:
        int     $0x13
 #endif
 
-# We will have entered with %cs = %ds+0x20, normalize %cs so
-# it is on par with the other segments.
-       pushw   %ds
-       pushw   $setup2
-       lretw
-
-setup2:
 # Force %es = %ds
        movw    %ds, %ax
        movw    %ax, %es
        cld
 
-# Stack paranoia: align the stack and make sure it is good
-# for both 16- and 32-bit references.  In particular, if we
-# were meant to have been using the full 16-bit segment, the
-# caller might have set %sp to zero, which breaks %esp-based
-# references.
-       andw    $~3, %sp        # dword align (might as well...)
-       jnz     1f
-       movw    $0xfffc, %sp    # Make sure we're not zero
-1:     movzwl  %sp, %esp       # Clear upper half of %esp
-       sti
+# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
+# which happened to work by accident for the old code.  Recalculate the stack
+# pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
+# stack behind its own code, so we can't blindly put it directly past the heap.
+
+       movw    %ss, %dx
+       cmpw    %ax, %dx        # %ds == %ss?
+       movw    %sp, %dx
+       je      2f              # -> assume %sp is reasonably set
+
+       # Invalid %ss, make up a new stack
+       movw    $_end, %dx
+       testb   $CAN_USE_HEAP, loadflags
+       jz      1f
+       movw    heap_end_ptr, %dx
+1:     addw    $STACK_SIZE, %dx
+       jnc     2f
+       xorw    %dx, %dx        # Prevent wraparound
+
+2:     # Now %dx should point to the end of our stack space
+       andw    $~3, %dx        # dword align (might as well...)
+       jnz     3f
+       movw    $0xfffc, %dx    # Make sure we're not zero
+3:     movw    %ax, %ss
+       movzwl  %dx, %esp       # Clear upper half of %esp
+       sti                     # Now we should have a working stack
+
+# We will have entered with %cs = %ds+0x20, normalize %cs so
+# it is on par with the other segments.
+       pushw   %ds
+       pushw   $6f
+       lretw
+6:
 
 # Check signature at end of setup
        cmpl    $0x5a5aaa55, setup_sig