x86: boot protocol updates
[sfrench/cifs-2.6.git] / arch / x86 / boot / header.S
1 /*
2  *      header.S
3  *
4  *      Copyright (C) 1991, 1992 Linus Torvalds
5  *
6  *      Based on bootsect.S and setup.S
7  *      modified by more people than can be counted
8  *
9  *      Rewritten as a common file by H. Peter Anvin (Apr 2007)
10  *
11  * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
12  * addresses must be multiplied by 16 to obtain their respective linear
13  * addresses. To avoid confusion, linear addresses are written using leading
14  * hex while segment addresses are written as segment:offset.
15  *
16  */
17
18 #include <asm/segment.h>
19 #include <linux/utsrelease.h>
20 #include <asm/boot.h>
21 #include <asm/e820.h>
22 #include <asm/page.h>
23 #include <asm/setup.h>
24 #include "boot.h"
25 #include "offsets.h"
26
27 SETUPSECTS      = 4                     /* default nr of setup-sectors */
28 BOOTSEG         = 0x07C0                /* original address of boot-sector */
29 SYSSEG          = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
30 SYSSIZE         = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
31                                         /* to be loaded */
32 ROOT_DEV        = 0                     /* ROOT_DEV is now written by "build" */
33 SWAP_DEV        = 0                     /* SWAP_DEV is now written by "build" */
34
35 #ifndef SVGA_MODE
36 #define SVGA_MODE ASK_VGA
37 #endif
38
39 #ifndef RAMDISK
40 #define RAMDISK 0
41 #endif
42
43 #ifndef ROOT_RDONLY
44 #define ROOT_RDONLY 1
45 #endif
46
47         .code16
48         .section ".bstext", "ax"
49
50         .global bootsect_start
51 bootsect_start:
52
53         # Normalize the start address
54         ljmp    $BOOTSEG, $start2
55
56 start2:
57         movw    %cs, %ax
58         movw    %ax, %ds
59         movw    %ax, %es
60         movw    %ax, %ss
61         xorw    %sp, %sp
62         sti
63         cld
64
65         movw    $bugger_off_msg, %si
66
67 msg_loop:
68         lodsb
69         andb    %al, %al
70         jz      bs_die
71         movb    $0xe, %ah
72         movw    $7, %bx
73         int     $0x10
74         jmp     msg_loop
75
76 bs_die:
77         # Allow the user to press a key, then reboot
78         xorw    %ax, %ax
79         int     $0x16
80         int     $0x19
81
82         # int 0x19 should never return.  In case it does anyway,
83         # invoke the BIOS reset code...
84         ljmp    $0xf000,$0xfff0
85
86         .section ".bsdata", "a"
87 bugger_off_msg:
88         .ascii  "Direct booting from floppy is no longer supported.\r\n"
89         .ascii  "Please use a boot loader program instead.\r\n"
90         .ascii  "\n"
91         .ascii  "Remove disk and press any key to reboot . . .\r\n"
92         .byte   0
93
94
95         # Kernel attributes; used by setup.  This is part 1 of the
96         # header, from the old boot sector.
97
98         .section ".header", "a"
99         .globl  hdr
100 hdr:
101 setup_sects:    .byte SETUPSECTS
102 root_flags:     .word ROOT_RDONLY
103 syssize:        .long SYSSIZE
104 ram_size:       .word RAMDISK
105 vid_mode:       .word SVGA_MODE
106 root_dev:       .word ROOT_DEV
107 boot_flag:      .word 0xAA55
108
109         # offset 512, entry point
110
111         .globl  _start
112 _start:
113                 # Explicitly enter this as bytes, or the assembler
114                 # tries to generate a 3-byte jump here, which causes
115                 # everything else to push off to the wrong offset.
116                 .byte   0xeb            # short (2-byte) jump
117                 .byte   start_of_setup-1f
118 1:
119
120         # Part 2 of the header, from the old setup.S
121
122                 .ascii  "HdrS"          # header signature
123                 .word   0x0208          # header version number (>= 0x0105)
124                                         # or else old loadlin-1.5 will fail)
125                 .globl realmode_swtch
126 realmode_swtch: .word   0, 0            # default_switch, SETUPSEG
127 start_sys_seg:  .word   SYSSEG
128                 .word   kernel_version-512 # pointing to kernel version string
129                                         # above section of header is compatible
130                                         # with loadlin-1.5 (header v1.5). Don't
131                                         # change it.
132
133 type_of_loader: .byte   0               # = 0, old one (LILO, Loadlin,
134                                         #      Bootlin, SYSLX, bootsect...)
135                                         # See Documentation/i386/boot.txt for
136                                         # assigned ids
137
138 # flags, unused bits must be zero (RFU) bit within loadflags
139 loadflags:
140 LOADED_HIGH     = 1                     # If set, the kernel is loaded high
141 CAN_USE_HEAP    = 0x80                  # If set, the loader also has set
142                                         # heap_end_ptr to tell how much
143                                         # space behind setup.S can be used for
144                                         # heap purposes.
145                                         # Only the loader knows what is free
146 #ifndef __BIG_KERNEL__
147                 .byte   0
148 #else
149                 .byte   LOADED_HIGH
150 #endif
151
152 setup_move_size: .word  0x8000          # size to move, when setup is not
153                                         # loaded at 0x90000. We will move setup
154                                         # to 0x90000 then just before jumping
155                                         # into the kernel. However, only the
156                                         # loader knows how much data behind
157                                         # us also needs to be loaded.
158
159 code32_start:                           # here loaders can put a different
160                                         # start address for 32-bit code.
161 #ifndef __BIG_KERNEL__
162                 .long   0x1000          #   0x1000 = default for zImage
163 #else
164                 .long   0x100000        # 0x100000 = default for big kernel
165 #endif
166
167 ramdisk_image:  .long   0               # address of loaded ramdisk image
168                                         # Here the loader puts the 32-bit
169                                         # address where it loaded the image.
170                                         # This only will be read by the kernel.
171
172 ramdisk_size:   .long   0               # its size in bytes
173
174 bootsect_kludge:
175                 .long   0               # obsolete
176
177 heap_end_ptr:   .word   _end+STACK_SIZE-512
178                                         # (Header version 0x0201 or later)
179                                         # space from here (exclusive) down to
180                                         # end of setup code can be used by setup
181                                         # for local heap purposes.
182
183 pad1:           .word   0
184 cmd_line_ptr:   .long   0               # (Header version 0x0202 or later)
185                                         # If nonzero, a 32-bit pointer
186                                         # to the kernel command line.
187                                         # The command line should be
188                                         # located between the start of
189                                         # setup and the end of low
190                                         # memory (0xa0000), or it may
191                                         # get overwritten before it
192                                         # gets read.  If this field is
193                                         # used, there is no longer
194                                         # anything magical about the
195                                         # 0x90000 segment; the setup
196                                         # can be located anywhere in
197                                         # low memory 0x10000 or higher.
198
199 ramdisk_max:    .long 0x7fffffff
200                                         # (Header version 0x0203 or later)
201                                         # The highest safe address for
202                                         # the contents of an initrd
203                                         # The current kernel allows up to 4 GB,
204                                         # but leave it at 2 GB to avoid
205                                         # possible bootloader bugs.
206
207 kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN  #physical addr alignment
208                                                 #required for protected mode
209                                                 #kernel
210 #ifdef CONFIG_RELOCATABLE
211 relocatable_kernel:    .byte 1
212 #else
213 relocatable_kernel:    .byte 0
214 #endif
215 pad2:                   .byte 0
216 pad3:                   .word 0
217
218 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
219                                                 #added with boot protocol
220                                                 #version 2.06
221
222 hardware_subarch:       .long 0                 # subarchitecture, added with 2.07
223                                                 # default to 0 for normal x86 PC
224
225 hardware_subarch_data:  .quad 0
226
227 payload_offset:         .long input_data
228 payload_length:         .long input_data_end-input_data
229
230 # End of setup header #####################################################
231
232         .section ".inittext", "ax"
233 start_of_setup:
234 #ifdef SAFE_RESET_DISK_CONTROLLER
235 # Reset the disk controller.
236         movw    $0x0000, %ax            # Reset disk controller
237         movb    $0x80, %dl              # All disks
238         int     $0x13
239 #endif
240
241 # Force %es = %ds
242         movw    %ds, %ax
243         movw    %ax, %es
244         cld
245
246 # Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
247 # which happened to work by accident for the old code.  Recalculate the stack
248 # pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
249 # stack behind its own code, so we can't blindly put it directly past the heap.
250
251         movw    %ss, %dx
252         cmpw    %ax, %dx        # %ds == %ss?
253         movw    %sp, %dx
254         je      2f              # -> assume %sp is reasonably set
255
256         # Invalid %ss, make up a new stack
257         movw    $_end, %dx
258         testb   $CAN_USE_HEAP, loadflags
259         jz      1f
260         movw    heap_end_ptr, %dx
261 1:      addw    $STACK_SIZE, %dx
262         jnc     2f
263         xorw    %dx, %dx        # Prevent wraparound
264
265 2:      # Now %dx should point to the end of our stack space
266         andw    $~3, %dx        # dword align (might as well...)
267         jnz     3f
268         movw    $0xfffc, %dx    # Make sure we're not zero
269 3:      movw    %ax, %ss
270         movzwl  %dx, %esp       # Clear upper half of %esp
271         sti                     # Now we should have a working stack
272
273 # We will have entered with %cs = %ds+0x20, normalize %cs so
274 # it is on par with the other segments.
275         pushw   %ds
276         pushw   $6f
277         lretw
278 6:
279
280 # Check signature at end of setup
281         cmpl    $0x5a5aaa55, setup_sig
282         jne     setup_bad
283
284 # Zero the bss
285         movw    $__bss_start, %di
286         movw    $_end+3, %cx
287         xorl    %eax, %eax
288         subw    %di, %cx
289         shrw    $2, %cx
290         rep; stosl
291
292 # Jump to C code (should not return)
293         calll   main
294
295 # Setup corrupt somehow...
296 setup_bad:
297         movl    $setup_corrupt, %eax
298         calll   puts
299         # Fall through...
300
301         .globl  die
302         .type   die, @function
303 die:
304         hlt
305         jmp     die
306
307         .size   die, .-die
308
309         .section ".initdata", "a"
310 setup_corrupt:
311         .byte   7
312         .string "No setup signature found...\n"