linux/arch/x86/boot/header.S
<<
>>
Prefs
   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 <generated/utsrelease.h>
  20#include <asm/boot.h>
  21#include <asm/e820.h>
  22#include <asm/page_types.h>
  23#include <asm/setup.h>
  24#include <asm/bootparam.h>
  25#include "boot.h"
  26#include "voffset.h"
  27#include "zoffset.h"
  28
  29BOOTSEG         = 0x07C0                /* original address of boot-sector */
  30SYSSEG          = 0x1000                /* historical load address >> 4 */
  31
  32#ifndef SVGA_MODE
  33#define SVGA_MODE ASK_VGA
  34#endif
  35
  36#ifndef ROOT_RDONLY
  37#define ROOT_RDONLY 1
  38#endif
  39
  40        .code16
  41        .section ".bstext", "ax"
  42
  43        .global bootsect_start
  44bootsect_start:
  45#ifdef CONFIG_EFI_STUB
  46        # "MZ", MS-DOS header
  47        .byte 0x4d
  48        .byte 0x5a
  49#endif
  50
  51        # Normalize the start address
  52        ljmp    $BOOTSEG, $start2
  53
  54start2:
  55        movw    %cs, %ax
  56        movw    %ax, %ds
  57        movw    %ax, %es
  58        movw    %ax, %ss
  59        xorw    %sp, %sp
  60        sti
  61        cld
  62
  63        movw    $bugger_off_msg, %si
  64
  65msg_loop:
  66        lodsb
  67        andb    %al, %al
  68        jz      bs_die
  69        movb    $0xe, %ah
  70        movw    $7, %bx
  71        int     $0x10
  72        jmp     msg_loop
  73
  74bs_die:
  75        # Allow the user to press a key, then reboot
  76        xorw    %ax, %ax
  77        int     $0x16
  78        int     $0x19
  79
  80        # int 0x19 should never return.  In case it does anyway,
  81        # invoke the BIOS reset code...
  82        ljmp    $0xf000,$0xfff0
  83
  84#ifdef CONFIG_EFI_STUB
  85        .org    0x3c
  86        #
  87        # Offset to the PE header.
  88        #
  89        .long   pe_header
  90#endif /* CONFIG_EFI_STUB */
  91
  92        .section ".bsdata", "a"
  93bugger_off_msg:
  94        .ascii  "Direct floppy boot is not supported. "
  95        .ascii  "Use a boot loader program instead.\r\n"
  96        .ascii  "\n"
  97        .ascii  "Remove disk and press any key to reboot ...\r\n"
  98        .byte   0
  99
 100#ifdef CONFIG_EFI_STUB
 101pe_header:
 102        .ascii  "PE"
 103        .word   0
 104
 105coff_header:
 106#ifdef CONFIG_X86_32
 107        .word   0x14c                           # i386
 108#else
 109        .word   0x8664                          # x86-64
 110#endif
 111        .word   3                               # nr_sections
 112        .long   0                               # TimeDateStamp
 113        .long   0                               # PointerToSymbolTable
 114        .long   1                               # NumberOfSymbols
 115        .word   section_table - optional_header # SizeOfOptionalHeader
 116#ifdef CONFIG_X86_32
 117        .word   0x306                           # Characteristics.
 118                                                # IMAGE_FILE_32BIT_MACHINE |
 119                                                # IMAGE_FILE_DEBUG_STRIPPED |
 120                                                # IMAGE_FILE_EXECUTABLE_IMAGE |
 121                                                # IMAGE_FILE_LINE_NUMS_STRIPPED
 122#else
 123        .word   0x206                           # Characteristics
 124                                                # IMAGE_FILE_DEBUG_STRIPPED |
 125                                                # IMAGE_FILE_EXECUTABLE_IMAGE |
 126                                                # IMAGE_FILE_LINE_NUMS_STRIPPED
 127#endif
 128
 129optional_header:
 130#ifdef CONFIG_X86_32
 131        .word   0x10b                           # PE32 format
 132#else
 133        .word   0x20b                           # PE32+ format
 134#endif
 135        .byte   0x02                            # MajorLinkerVersion
 136        .byte   0x14                            # MinorLinkerVersion
 137
 138        # Filled in by build.c
 139        .long   0                               # SizeOfCode
 140
 141        .long   0                               # SizeOfInitializedData
 142        .long   0                               # SizeOfUninitializedData
 143
 144        # Filled in by build.c
 145        .long   0x0000                          # AddressOfEntryPoint
 146
 147        .long   0x0200                          # BaseOfCode
 148#ifdef CONFIG_X86_32
 149        .long   0                               # data
 150#endif
 151
 152extra_header_fields:
 153#ifdef CONFIG_X86_32
 154        .long   0                               # ImageBase
 155#else
 156        .quad   0                               # ImageBase
 157#endif
 158        .long   0x20                            # SectionAlignment
 159        .long   0x20                            # FileAlignment
 160        .word   0                               # MajorOperatingSystemVersion
 161        .word   0                               # MinorOperatingSystemVersion
 162        .word   0                               # MajorImageVersion
 163        .word   0                               # MinorImageVersion
 164        .word   0                               # MajorSubsystemVersion
 165        .word   0                               # MinorSubsystemVersion
 166        .long   0                               # Win32VersionValue
 167
 168        #
 169        # The size of the bzImage is written in tools/build.c
 170        #
 171        .long   0                               # SizeOfImage
 172
 173        .long   0x200                           # SizeOfHeaders
 174        .long   0                               # CheckSum
 175        .word   0xa                             # Subsystem (EFI application)
 176        .word   0                               # DllCharacteristics
 177#ifdef CONFIG_X86_32
 178        .long   0                               # SizeOfStackReserve
 179        .long   0                               # SizeOfStackCommit
 180        .long   0                               # SizeOfHeapReserve
 181        .long   0                               # SizeOfHeapCommit
 182#else
 183        .quad   0                               # SizeOfStackReserve
 184        .quad   0                               # SizeOfStackCommit
 185        .quad   0                               # SizeOfHeapReserve
 186        .quad   0                               # SizeOfHeapCommit
 187#endif
 188        .long   0                               # LoaderFlags
 189        .long   0x6                             # NumberOfRvaAndSizes
 190
 191        .quad   0                               # ExportTable
 192        .quad   0                               # ImportTable
 193        .quad   0                               # ResourceTable
 194        .quad   0                               # ExceptionTable
 195        .quad   0                               # CertificationTable
 196        .quad   0                               # BaseRelocationTable
 197
 198        # Section table
 199section_table:
 200        #
 201        # The offset & size fields are filled in by build.c.
 202        #
 203        .ascii  ".setup"
 204        .byte   0
 205        .byte   0
 206        .long   0
 207        .long   0x0                             # startup_{32,64}
 208        .long   0                               # Size of initialized data
 209                                                # on disk
 210        .long   0x0                             # startup_{32,64}
 211        .long   0                               # PointerToRelocations
 212        .long   0                               # PointerToLineNumbers
 213        .word   0                               # NumberOfRelocations
 214        .word   0                               # NumberOfLineNumbers
 215        .long   0x60500020                      # Characteristics (section flags)
 216
 217        #
 218        # The EFI application loader requires a relocation section
 219        # because EFI applications must be relocatable. The .reloc
 220        # offset & size fields are filled in by build.c.
 221        #
 222        .ascii  ".reloc"
 223        .byte   0
 224        .byte   0
 225        .long   0
 226        .long   0
 227        .long   0                               # SizeOfRawData
 228        .long   0                               # PointerToRawData
 229        .long   0                               # PointerToRelocations
 230        .long   0                               # PointerToLineNumbers
 231        .word   0                               # NumberOfRelocations
 232        .word   0                               # NumberOfLineNumbers
 233        .long   0x42100040                      # Characteristics (section flags)
 234
 235        #
 236        # The offset & size fields are filled in by build.c.
 237        #
 238        .ascii  ".text"
 239        .byte   0
 240        .byte   0
 241        .byte   0
 242        .long   0
 243        .long   0x0                             # startup_{32,64}
 244        .long   0                               # Size of initialized data
 245                                                # on disk
 246        .long   0x0                             # startup_{32,64}
 247        .long   0                               # PointerToRelocations
 248        .long   0                               # PointerToLineNumbers
 249        .word   0                               # NumberOfRelocations
 250        .word   0                               # NumberOfLineNumbers
 251        .long   0x60500020                      # Characteristics (section flags)
 252
 253#endif /* CONFIG_EFI_STUB */
 254
 255        # Kernel attributes; used by setup.  This is part 1 of the
 256        # header, from the old boot sector.
 257
 258        .section ".header", "a"
 259        .globl  sentinel
 260sentinel:       .byte 0xff, 0xff        /* Used to detect broken loaders */
 261
 262        .globl  hdr
 263hdr:
 264setup_sects:    .byte 0                 /* Filled in by build.c */
 265root_flags:     .word ROOT_RDONLY
 266syssize:        .long 0                 /* Filled in by build.c */
 267ram_size:       .word 0                 /* Obsolete */
 268vid_mode:       .word SVGA_MODE
 269root_dev:       .word 0                 /* Filled in by build.c */
 270boot_flag:      .word 0xAA55
 271
 272        # offset 512, entry point
 273
 274        .globl  _start
 275_start:
 276                # Explicitly enter this as bytes, or the assembler
 277                # tries to generate a 3-byte jump here, which causes
 278                # everything else to push off to the wrong offset.
 279                .byte   0xeb            # short (2-byte) jump
 280                .byte   start_of_setup-1f
 2811:
 282
 283        # Part 2 of the header, from the old setup.S
 284
 285                .ascii  "HdrS"          # header signature
 286                .word   0x020c          # header version number (>= 0x0105)
 287                                        # or else old loadlin-1.5 will fail)
 288                .globl realmode_swtch
 289realmode_swtch: .word   0, 0            # default_switch, SETUPSEG
 290start_sys_seg:  .word   SYSSEG          # obsolete and meaningless, but just
 291                                        # in case something decided to "use" it
 292                .word   kernel_version-512 # pointing to kernel version string
 293                                        # above section of header is compatible
 294                                        # with loadlin-1.5 (header v1.5). Don't
 295                                        # change it.
 296
 297type_of_loader: .byte   0               # 0 means ancient bootloader, newer
 298                                        # bootloaders know to change this.
 299                                        # See Documentation/x86/boot.txt for
 300                                        # assigned ids
 301
 302# flags, unused bits must be zero (RFU) bit within loadflags
 303loadflags:
 304                .byte   LOADED_HIGH     # The kernel is to be loaded high
 305
 306setup_move_size: .word  0x8000          # size to move, when setup is not
 307                                        # loaded at 0x90000. We will move setup
 308                                        # to 0x90000 then just before jumping
 309                                        # into the kernel. However, only the
 310                                        # loader knows how much data behind
 311                                        # us also needs to be loaded.
 312
 313code32_start:                           # here loaders can put a different
 314                                        # start address for 32-bit code.
 315                .long   0x100000        # 0x100000 = default for big kernel
 316
 317ramdisk_image:  .long   0               # address of loaded ramdisk image
 318                                        # Here the loader puts the 32-bit
 319                                        # address where it loaded the image.
 320                                        # This only will be read by the kernel.
 321
 322ramdisk_size:   .long   0               # its size in bytes
 323
 324bootsect_kludge:
 325                .long   0               # obsolete
 326
 327heap_end_ptr:   .word   _end+STACK_SIZE-512
 328                                        # (Header version 0x0201 or later)
 329                                        # space from here (exclusive) down to
 330                                        # end of setup code can be used by setup
 331                                        # for local heap purposes.
 332
 333ext_loader_ver:
 334                .byte   0               # Extended boot loader version
 335ext_loader_type:
 336                .byte   0               # Extended boot loader type
 337
 338cmd_line_ptr:   .long   0               # (Header version 0x0202 or later)
 339                                        # If nonzero, a 32-bit pointer
 340                                        # to the kernel command line.
 341                                        # The command line should be
 342                                        # located between the start of
 343                                        # setup and the end of low
 344                                        # memory (0xa0000), or it may
 345                                        # get overwritten before it
 346                                        # gets read.  If this field is
 347                                        # used, there is no longer
 348                                        # anything magical about the
 349                                        # 0x90000 segment; the setup
 350                                        # can be located anywhere in
 351                                        # low memory 0x10000 or higher.
 352
 353ramdisk_max:    .long 0x7fffffff
 354                                        # (Header version 0x0203 or later)
 355                                        # The highest safe address for
 356                                        # the contents of an initrd
 357                                        # The current kernel allows up to 4 GB,
 358                                        # but leave it at 2 GB to avoid
 359                                        # possible bootloader bugs.
 360
 361kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN  #physical addr alignment
 362                                                #required for protected mode
 363                                                #kernel
 364#ifdef CONFIG_RELOCATABLE
 365relocatable_kernel:    .byte 1
 366#else
 367relocatable_kernel:    .byte 0
 368#endif
 369min_alignment:          .byte MIN_KERNEL_ALIGN_LG2      # minimum alignment
 370
 371xloadflags:
 372#ifdef CONFIG_X86_64
 373# define XLF0 XLF_KERNEL_64                     /* 64-bit kernel */
 374#else
 375# define XLF0 0
 376#endif
 377
 378#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
 379   /* kernel/boot_param/ramdisk could be loaded above 4g */
 380# define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
 381#else
 382# define XLF1 0
 383#endif
 384
 385#ifdef CONFIG_EFI_STUB
 386# ifdef CONFIG_X86_64
 387#  define XLF23 XLF_EFI_HANDOVER_64             /* 64-bit EFI handover ok */
 388# else
 389#  define XLF23 XLF_EFI_HANDOVER_32             /* 32-bit EFI handover ok */
 390# endif
 391#else
 392# define XLF23 0
 393#endif
 394                        .word XLF0 | XLF1 | XLF23
 395
 396cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
 397                                                #added with boot protocol
 398                                                #version 2.06
 399
 400hardware_subarch:       .long 0                 # subarchitecture, added with 2.07
 401                                                # default to 0 for normal x86 PC
 402
 403hardware_subarch_data:  .quad 0
 404
 405payload_offset:         .long ZO_input_data
 406payload_length:         .long ZO_z_input_len
 407
 408setup_data:             .quad 0                 # 64-bit physical pointer to
 409                                                # single linked list of
 410                                                # struct setup_data
 411
 412pref_address:           .quad LOAD_PHYSICAL_ADDR        # preferred load addr
 413
 414#define ZO_INIT_SIZE    (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
 415#define VO_INIT_SIZE    (VO__end - VO__text)
 416#if ZO_INIT_SIZE > VO_INIT_SIZE
 417#define INIT_SIZE ZO_INIT_SIZE
 418#else
 419#define INIT_SIZE VO_INIT_SIZE
 420#endif
 421init_size:              .long INIT_SIZE         # kernel initialization size
 422handover_offset:
 423#ifdef CONFIG_EFI_STUB
 424                        .long 0x30              # offset to the handover
 425                                                # protocol entry point
 426#else
 427                        .long 0
 428#endif
 429
 430# End of setup header #####################################################
 431
 432        .section ".entrytext", "ax"
 433start_of_setup:
 434# Force %es = %ds
 435        movw    %ds, %ax
 436        movw    %ax, %es
 437        cld
 438
 439# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
 440# which happened to work by accident for the old code.  Recalculate the stack
 441# pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
 442# stack behind its own code, so we can't blindly put it directly past the heap.
 443
 444        movw    %ss, %dx
 445        cmpw    %ax, %dx        # %ds == %ss?
 446        movw    %sp, %dx
 447        je      2f              # -> assume %sp is reasonably set
 448
 449        # Invalid %ss, make up a new stack
 450        movw    $_end, %dx
 451        testb   $CAN_USE_HEAP, loadflags
 452        jz      1f
 453        movw    heap_end_ptr, %dx
 4541:      addw    $STACK_SIZE, %dx
 455        jnc     2f
 456        xorw    %dx, %dx        # Prevent wraparound
 457
 4582:      # Now %dx should point to the end of our stack space
 459        andw    $~3, %dx        # dword align (might as well...)
 460        jnz     3f
 461        movw    $0xfffc, %dx    # Make sure we're not zero
 4623:      movw    %ax, %ss
 463        movzwl  %dx, %esp       # Clear upper half of %esp
 464        sti                     # Now we should have a working stack
 465
 466# We will have entered with %cs = %ds+0x20, normalize %cs so
 467# it is on par with the other segments.
 468        pushw   %ds
 469        pushw   $6f
 470        lretw
 4716:
 472
 473# Check signature at end of setup
 474        cmpl    $0x5a5aaa55, setup_sig
 475        jne     setup_bad
 476
 477# Zero the bss
 478        movw    $__bss_start, %di
 479        movw    $_end+3, %cx
 480        xorl    %eax, %eax
 481        subw    %di, %cx
 482        shrw    $2, %cx
 483        rep; stosl
 484
 485# Jump to C code (should not return)
 486        calll   main
 487
 488# Setup corrupt somehow...
 489setup_bad:
 490        movl    $setup_corrupt, %eax
 491        calll   puts
 492        # Fall through...
 493
 494        .globl  die
 495        .type   die, @function
 496die:
 497        hlt
 498        jmp     die
 499
 500        .size   die, .-die
 501
 502        .section ".initdata", "a"
 503setup_corrupt:
 504        .byte   7
 505        .string "No setup signature found...\n"
 506