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