linux/arch/x86/boot/header.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 *      header.S
   4 *
   5 *      Copyright (C) 1991, 1992 Linus Torvalds
   6 *
   7 *      Based on bootsect.S and setup.S
   8 *      modified by more people than can be counted
   9 *
  10 *      Rewritten as a common file by H. Peter Anvin (Apr 2007)
  11 *
  12 * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
  13 * addresses must be multiplied by 16 to obtain their respective linear
  14 * addresses. To avoid confusion, linear addresses are written using leading
  15 * hex while segment addresses are written as segment:offset.
  16 *
  17 */
  18
  19#include <asm/segment.h>
  20#include <asm/boot.h>
  21#include <asm/page_types.h>
  22#include <asm/setup.h>
  23#include <asm/bootparam.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 ROOT_RDONLY
  36#define ROOT_RDONLY 1
  37#endif
  38
  39        .code16
  40        .section ".bstext", "ax"
  41
  42        .global bootsect_start
  43bootsect_start:
  44#ifdef CONFIG_EFI_STUB
  45        # "MZ", MS-DOS header
  46        .byte 0x4d
  47        .byte 0x5a
  48#endif
  49
  50        # Normalize the start address
  51        ljmp    $BOOTSEG, $start2
  52
  53start2:
  54        movw    %cs, %ax
  55        movw    %ax, %ds
  56        movw    %ax, %es
  57        movw    %ax, %ss
  58        xorw    %sp, %sp
  59        sti
  60        cld
  61
  62        movw    $bugger_off_msg, %si
  63
  64msg_loop:
  65        lodsb
  66        andb    %al, %al
  67        jz      bs_die
  68        movb    $0xe, %ah
  69        movw    $7, %bx
  70        int     $0x10
  71        jmp     msg_loop
  72
  73bs_die:
  74        # Allow the user to press a key, then reboot
  75        xorw    %ax, %ax
  76        int     $0x16
  77        int     $0x19
  78
  79        # int 0x19 should never return.  In case it does anyway,
  80        # invoke the BIOS reset code...
  81        ljmp    $0xf000,$0xfff0
  82
  83#ifdef CONFIG_EFI_STUB
  84        .org    0x3c
  85        #
  86        # Offset to the PE header.
  87        #
  88        .long   pe_header
  89#endif /* CONFIG_EFI_STUB */
  90
  91        .section ".bsdata", "a"
  92bugger_off_msg:
  93        .ascii  "Use a boot loader.\r\n"
  94        .ascii  "\n"
  95        .ascii  "Remove disk and press any key to reboot...\r\n"
  96        .byte   0
  97
  98#ifdef CONFIG_EFI_STUB
  99pe_header:
 100        .ascii  "PE"
 101        .word   0
 102
 103coff_header:
 104#ifdef CONFIG_X86_32
 105        .word   0x14c                           # i386
 106#else
 107        .word   0x8664                          # x86-64
 108#endif
 109        .word   4                               # nr_sections
 110        .long   0                               # TimeDateStamp
 111        .long   0                               # PointerToSymbolTable
 112        .long   1                               # NumberOfSymbols
 113        .word   section_table - optional_header # SizeOfOptionalHeader
 114#ifdef CONFIG_X86_32
 115        .word   0x306                           # Characteristics.
 116                                                # IMAGE_FILE_32BIT_MACHINE |
 117                                                # IMAGE_FILE_DEBUG_STRIPPED |
 118                                                # IMAGE_FILE_EXECUTABLE_IMAGE |
 119                                                # IMAGE_FILE_LINE_NUMS_STRIPPED
 120#else
 121        .word   0x206                           # Characteristics
 122                                                # IMAGE_FILE_DEBUG_STRIPPED |
 123                                                # IMAGE_FILE_EXECUTABLE_IMAGE |
 124                                                # IMAGE_FILE_LINE_NUMS_STRIPPED
 125#endif
 126
 127optional_header:
 128#ifdef CONFIG_X86_32
 129        .word   0x10b                           # PE32 format
 130#else
 131        .word   0x20b                           # PE32+ format
 132#endif
 133        .byte   0x02                            # MajorLinkerVersion
 134        .byte   0x14                            # MinorLinkerVersion
 135
 136        # Filled in by build.c
 137        .long   0                               # SizeOfCode
 138
 139        .long   0                               # SizeOfInitializedData
 140        .long   0                               # SizeOfUninitializedData
 141
 142        # Filled in by build.c
 143        .long   0x0000                          # AddressOfEntryPoint
 144
 145        .long   0x0200                          # BaseOfCode
 146#ifdef CONFIG_X86_32
 147        .long   0                               # data
 148#endif
 149
 150extra_header_fields:
 151#ifdef CONFIG_X86_32
 152        .long   0                               # ImageBase
 153#else
 154        .quad   0                               # ImageBase
 155#endif
 156        .long   0x20                            # SectionAlignment
 157        .long   0x20                            # FileAlignment
 158        .word   0                               # MajorOperatingSystemVersion
 159        .word   0                               # MinorOperatingSystemVersion
 160        .word   0                               # MajorImageVersion
 161        .word   0                               # MinorImageVersion
 162        .word   0                               # MajorSubsystemVersion
 163        .word   0                               # MinorSubsystemVersion
 164        .long   0                               # Win32VersionValue
 165
 166        #
 167        # The size of the bzImage is written in tools/build.c
 168        #
 169        .long   0                               # SizeOfImage
 170
 171        .long   0x200                           # SizeOfHeaders
 172        .long   0                               # CheckSum
 173        .word   0xa                             # Subsystem (EFI application)
 174        .word   0                               # DllCharacteristics
 175#ifdef CONFIG_X86_32
 176        .long   0                               # SizeOfStackReserve
 177        .long   0                               # SizeOfStackCommit
 178        .long   0                               # SizeOfHeapReserve
 179        .long   0                               # SizeOfHeapCommit
 180#else
 181        .quad   0                               # SizeOfStackReserve
 182        .quad   0                               # SizeOfStackCommit
 183        .quad   0                               # SizeOfHeapReserve
 184        .quad   0                               # SizeOfHeapCommit
 185#endif
 186        .long   0                               # LoaderFlags
 187        .long   0x6                             # NumberOfRvaAndSizes
 188
 189        .quad   0                               # ExportTable
 190        .quad   0                               # ImportTable
 191        .quad   0                               # ResourceTable
 192        .quad   0                               # ExceptionTable
 193        .quad   0                               # CertificationTable
 194        .quad   0                               # BaseRelocationTable
 195
 196        # Section table
 197section_table:
 198        #
 199        # The offset & size fields are filled in by build.c.
 200        #
 201        .ascii  ".setup"
 202        .byte   0
 203        .byte   0
 204        .long   0
 205        .long   0x0                             # startup_{32,64}
 206        .long   0                               # Size of initialized data
 207                                                # on disk
 208        .long   0x0                             # startup_{32,64}
 209        .long   0                               # PointerToRelocations
 210        .long   0                               # PointerToLineNumbers
 211        .word   0                               # NumberOfRelocations
 212        .word   0                               # NumberOfLineNumbers
 213        .long   0x60500020                      # Characteristics (section flags)
 214
 215        #
 216        # The EFI application loader requires a relocation section
 217        # because EFI applications must be relocatable. The .reloc
 218        # offset & size fields are filled in by build.c.
 219        #
 220        .ascii  ".reloc"
 221        .byte   0
 222        .byte   0
 223        .long   0
 224        .long   0
 225        .long   0                               # SizeOfRawData
 226        .long   0                               # PointerToRawData
 227        .long   0                               # PointerToRelocations
 228        .long   0                               # PointerToLineNumbers
 229        .word   0                               # NumberOfRelocations
 230        .word   0                               # NumberOfLineNumbers
 231        .long   0x42100040                      # Characteristics (section flags)
 232
 233        #
 234        # The offset & size fields are filled in by build.c.
 235        #
 236        .ascii  ".text"
 237        .byte   0
 238        .byte   0
 239        .byte   0
 240        .long   0
 241        .long   0x0                             # startup_{32,64}
 242        .long   0                               # Size of initialized data
 243                                                # on disk
 244        .long   0x0                             # startup_{32,64}
 245        .long   0                               # PointerToRelocations
 246        .long   0                               # PointerToLineNumbers
 247        .word   0                               # NumberOfRelocations
 248        .word   0                               # NumberOfLineNumbers
 249        .long   0x60500020                      # Characteristics (section flags)
 250
 251        #
 252        # The offset & size fields are filled in by build.c.
 253        #
 254        .ascii  ".bss"
 255        .byte   0
 256        .byte   0
 257        .byte   0
 258        .byte   0
 259        .long   0
 260        .long   0x0
 261        .long   0                               # Size of initialized data
 262                                                # on disk
 263        .long   0x0
 264        .long   0                               # PointerToRelocations
 265        .long   0                               # PointerToLineNumbers
 266        .word   0                               # NumberOfRelocations
 267        .word   0                               # NumberOfLineNumbers
 268        .long   0xc8000080                      # Characteristics (section flags)
 269
 270#endif /* CONFIG_EFI_STUB */
 271
 272        # Kernel attributes; used by setup.  This is part 1 of the
 273        # header, from the old boot sector.
 274
 275        .section ".header", "a"
 276        .globl  sentinel
 277sentinel:       .byte 0xff, 0xff        /* Used to detect broken loaders */
 278
 279        .globl  hdr
 280hdr:
 281setup_sects:    .byte 0                 /* Filled in by build.c */
 282root_flags:     .word ROOT_RDONLY
 283syssize:        .long 0                 /* Filled in by build.c */
 284ram_size:       .word 0                 /* Obsolete */
 285vid_mode:       .word SVGA_MODE
 286root_dev:       .word 0                 /* Filled in by build.c */
 287boot_flag:      .word 0xAA55
 288
 289        # offset 512, entry point
 290
 291        .globl  _start
 292_start:
 293                # Explicitly enter this as bytes, or the assembler
 294                # tries to generate a 3-byte jump here, which causes
 295                # everything else to push off to the wrong offset.
 296                .byte   0xeb            # short (2-byte) jump
 297                .byte   start_of_setup-1f
 2981:
 299
 300        # Part 2 of the header, from the old setup.S
 301
 302                .ascii  "HdrS"          # header signature
 303                .word   0x020d          # header version number (>= 0x0105)
 304                                        # or else old loadlin-1.5 will fail)
 305                .globl realmode_swtch
 306realmode_swtch: .word   0, 0            # default_switch, SETUPSEG
 307start_sys_seg:  .word   SYSSEG          # obsolete and meaningless, but just
 308                                        # in case something decided to "use" it
 309                .word   kernel_version-512 # pointing to kernel version string
 310                                        # above section of header is compatible
 311                                        # with loadlin-1.5 (header v1.5). Don't
 312                                        # change it.
 313
 314type_of_loader: .byte   0               # 0 means ancient bootloader, newer
 315                                        # bootloaders know to change this.
 316                                        # See Documentation/x86/boot.txt for
 317                                        # assigned ids
 318
 319# flags, unused bits must be zero (RFU) bit within loadflags
 320loadflags:
 321                .byte   LOADED_HIGH     # The kernel is to be loaded high
 322
 323setup_move_size: .word  0x8000          # size to move, when setup is not
 324                                        # loaded at 0x90000. We will move setup
 325                                        # to 0x90000 then just before jumping
 326                                        # into the kernel. However, only the
 327                                        # loader knows how much data behind
 328                                        # us also needs to be loaded.
 329
 330code32_start:                           # here loaders can put a different
 331                                        # start address for 32-bit code.
 332                .long   0x100000        # 0x100000 = default for big kernel
 333
 334ramdisk_image:  .long   0               # address of loaded ramdisk image
 335                                        # Here the loader puts the 32-bit
 336                                        # address where it loaded the image.
 337                                        # This only will be read by the kernel.
 338
 339ramdisk_size:   .long   0               # its size in bytes
 340
 341bootsect_kludge:
 342                .long   0               # obsolete
 343
 344heap_end_ptr:   .word   _end+STACK_SIZE-512
 345                                        # (Header version 0x0201 or later)
 346                                        # space from here (exclusive) down to
 347                                        # end of setup code can be used by setup
 348                                        # for local heap purposes.
 349
 350ext_loader_ver:
 351                .byte   0               # Extended boot loader version
 352ext_loader_type:
 353                .byte   0               # Extended boot loader type
 354
 355cmd_line_ptr:   .long   0               # (Header version 0x0202 or later)
 356                                        # If nonzero, a 32-bit pointer
 357                                        # to the kernel command line.
 358                                        # The command line should be
 359                                        # located between the start of
 360                                        # setup and the end of low
 361                                        # memory (0xa0000), or it may
 362                                        # get overwritten before it
 363                                        # gets read.  If this field is
 364                                        # used, there is no longer
 365                                        # anything magical about the
 366                                        # 0x90000 segment; the setup
 367                                        # can be located anywhere in
 368                                        # low memory 0x10000 or higher.
 369
 370initrd_addr_max: .long 0x7fffffff
 371                                        # (Header version 0x0203 or later)
 372                                        # The highest safe address for
 373                                        # the contents of an initrd
 374                                        # The current kernel allows up to 4 GB,
 375                                        # but leave it at 2 GB to avoid
 376                                        # possible bootloader bugs.
 377
 378kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN  #physical addr alignment
 379                                                #required for protected mode
 380                                                #kernel
 381#ifdef CONFIG_RELOCATABLE
 382relocatable_kernel:    .byte 1
 383#else
 384relocatable_kernel:    .byte 0
 385#endif
 386min_alignment:          .byte MIN_KERNEL_ALIGN_LG2      # minimum alignment
 387
 388xloadflags:
 389#ifdef CONFIG_X86_64
 390# define XLF0 XLF_KERNEL_64                     /* 64-bit kernel */
 391#else
 392# define XLF0 0
 393#endif
 394
 395#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
 396   /* kernel/boot_param/ramdisk could be loaded above 4g */
 397# define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
 398#else
 399# define XLF1 0
 400#endif
 401
 402#ifdef CONFIG_EFI_STUB
 403# ifdef CONFIG_EFI_MIXED
 404#  define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
 405# else
 406#  ifdef CONFIG_X86_64
 407#   define XLF23 XLF_EFI_HANDOVER_64            /* 64-bit EFI handover ok */
 408#  else
 409#   define XLF23 XLF_EFI_HANDOVER_32            /* 32-bit EFI handover ok */
 410#  endif
 411# endif
 412#else
 413# define XLF23 0
 414#endif
 415
 416#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC_CORE)
 417# define XLF4 XLF_EFI_KEXEC
 418#else
 419# define XLF4 0
 420#endif
 421
 422                        .word XLF0 | XLF1 | XLF23 | XLF4
 423
 424cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
 425                                                #added with boot protocol
 426                                                #version 2.06
 427
 428hardware_subarch:       .long 0                 # subarchitecture, added with 2.07
 429                                                # default to 0 for normal x86 PC
 430
 431hardware_subarch_data:  .quad 0
 432
 433payload_offset:         .long ZO_input_data
 434payload_length:         .long ZO_z_input_len
 435
 436setup_data:             .quad 0                 # 64-bit physical pointer to
 437                                                # single linked list of
 438                                                # struct setup_data
 439
 440pref_address:           .quad LOAD_PHYSICAL_ADDR        # preferred load addr
 441
 442#
 443# Getting to provably safe in-place decompression is hard. Worst case
 444# behaviours need to be analyzed. Here let's take the decompression of
 445# a gzip-compressed kernel as example, to illustrate it:
 446#
 447# The file layout of gzip compressed kernel is:
 448#
 449#    magic[2]
 450#    method[1]
 451#    flags[1]
 452#    timestamp[4]
 453#    extraflags[1]
 454#    os[1]
 455#    compressed data blocks[N]
 456#    crc[4] orig_len[4]
 457#
 458# ... resulting in +18 bytes overhead of uncompressed data.
 459#
 460# (For more information, please refer to RFC 1951 and RFC 1952.)
 461#
 462# Files divided into blocks
 463# 1 bit (last block flag)
 464# 2 bits (block type)
 465#
 466# 1 block occurs every 32K -1 bytes or when there 50% compression
 467# has been achieved. The smallest block type encoding is always used.
 468#
 469# stored:
 470#    32 bits length in bytes.
 471#
 472# fixed:
 473#    magic fixed tree.
 474#    symbols.
 475#
 476# dynamic:
 477#    dynamic tree encoding.
 478#    symbols.
 479#
 480#
 481# The buffer for decompression in place is the length of the uncompressed
 482# data, plus a small amount extra to keep the algorithm safe. The
 483# compressed data is placed at the end of the buffer.  The output pointer
 484# is placed at the start of the buffer and the input pointer is placed
 485# where the compressed data starts. Problems will occur when the output
 486# pointer overruns the input pointer.
 487#
 488# The output pointer can only overrun the input pointer if the input
 489# pointer is moving faster than the output pointer.  A condition only
 490# triggered by data whose compressed form is larger than the uncompressed
 491# form.
 492#
 493# The worst case at the block level is a growth of the compressed data
 494# of 5 bytes per 32767 bytes.
 495#
 496# The worst case internal to a compressed block is very hard to figure.
 497# The worst case can at least be bounded by having one bit that represents
 498# 32764 bytes and then all of the rest of the bytes representing the very
 499# very last byte.
 500#
 501# All of which is enough to compute an amount of extra data that is required
 502# to be safe.  To avoid problems at the block level allocating 5 extra bytes
 503# per 32767 bytes of data is sufficient.  To avoid problems internal to a
 504# block adding an extra 32767 bytes (the worst case uncompressed block size)
 505# is sufficient, to ensure that in the worst case the decompressed data for
 506# block will stop the byte before the compressed data for a block begins.
 507# To avoid problems with the compressed data's meta information an extra 18
 508# bytes are needed.  Leading to the formula:
 509#
 510# extra_bytes = (uncompressed_size >> 12) + 32768 + 18
 511#
 512# Adding 8 bytes per 32K is a bit excessive but much easier to calculate.
 513# Adding 32768 instead of 32767 just makes for round numbers.
 514#
 515# Above analysis is for decompressing gzip compressed kernel only. Up to
 516# now 6 different decompressor are supported all together. And among them
 517# xz stores data in chunks and has maximum chunk of 64K. Hence safety
 518# margin should be updated to cover all decompressors so that we don't
 519# need to deal with each of them separately. Please check
 520# the description in lib/decompressor_xxx.c for specific information.
 521#
 522# extra_bytes = (uncompressed_size >> 12) + 65536 + 128
 523#
 524# LZ4 is even worse: data that cannot be further compressed grows by 0.4%,
 525# or one byte per 256 bytes. OTOH, we can safely get rid of the +128 as
 526# the size-dependent part now grows so fast.
 527#
 528# extra_bytes = (uncompressed_size >> 8) + 65536
 529
 530#define ZO_z_extra_bytes        ((ZO_z_output_len >> 8) + 65536)
 531#if ZO_z_output_len > ZO_z_input_len
 532# define ZO_z_extract_offset    (ZO_z_output_len + ZO_z_extra_bytes - \
 533                                 ZO_z_input_len)
 534#else
 535# define ZO_z_extract_offset    ZO_z_extra_bytes
 536#endif
 537
 538/*
 539 * The extract_offset has to be bigger than ZO head section. Otherwise when
 540 * the head code is running to move ZO to the end of the buffer, it will
 541 * overwrite the head code itself.
 542 */
 543#if (ZO__ehead - ZO_startup_32) > ZO_z_extract_offset
 544# define ZO_z_min_extract_offset ((ZO__ehead - ZO_startup_32 + 4095) & ~4095)
 545#else
 546# define ZO_z_min_extract_offset ((ZO_z_extract_offset + 4095) & ~4095)
 547#endif
 548
 549#define ZO_INIT_SIZE    (ZO__end - ZO_startup_32 + ZO_z_min_extract_offset)
 550
 551#define VO_INIT_SIZE    (VO__end - VO__text)
 552#if ZO_INIT_SIZE > VO_INIT_SIZE
 553# define INIT_SIZE ZO_INIT_SIZE
 554#else
 555# define INIT_SIZE VO_INIT_SIZE
 556#endif
 557
 558init_size:              .long INIT_SIZE         # kernel initialization size
 559handover_offset:        .long 0                 # Filled in by build.c
 560
 561# End of setup header #####################################################
 562
 563        .section ".entrytext", "ax"
 564start_of_setup:
 565# Force %es = %ds
 566        movw    %ds, %ax
 567        movw    %ax, %es
 568        cld
 569
 570# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
 571# which happened to work by accident for the old code.  Recalculate the stack
 572# pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
 573# stack behind its own code, so we can't blindly put it directly past the heap.
 574
 575        movw    %ss, %dx
 576        cmpw    %ax, %dx        # %ds == %ss?
 577        movw    %sp, %dx
 578        je      2f              # -> assume %sp is reasonably set
 579
 580        # Invalid %ss, make up a new stack
 581        movw    $_end, %dx
 582        testb   $CAN_USE_HEAP, loadflags
 583        jz      1f
 584        movw    heap_end_ptr, %dx
 5851:      addw    $STACK_SIZE, %dx
 586        jnc     2f
 587        xorw    %dx, %dx        # Prevent wraparound
 588
 5892:      # Now %dx should point to the end of our stack space
 590        andw    $~3, %dx        # dword align (might as well...)
 591        jnz     3f
 592        movw    $0xfffc, %dx    # Make sure we're not zero
 5933:      movw    %ax, %ss
 594        movzwl  %dx, %esp       # Clear upper half of %esp
 595        sti                     # Now we should have a working stack
 596
 597# We will have entered with %cs = %ds+0x20, normalize %cs so
 598# it is on par with the other segments.
 599        pushw   %ds
 600        pushw   $6f
 601        lretw
 6026:
 603
 604# Check signature at end of setup
 605        cmpl    $0x5a5aaa55, setup_sig
 606        jne     setup_bad
 607
 608# Zero the bss
 609        movw    $__bss_start, %di
 610        movw    $_end+3, %cx
 611        xorl    %eax, %eax
 612        subw    %di, %cx
 613        shrw    $2, %cx
 614        rep; stosl
 615
 616# Jump to C code (should not return)
 617        calll   main
 618
 619# Setup corrupt somehow...
 620setup_bad:
 621        movl    $setup_corrupt, %eax
 622        calll   puts
 623        # Fall through...
 624
 625        .globl  die
 626        .type   die, @function
 627die:
 628        hlt
 629        jmp     die
 630
 631        .size   die, .-die
 632
 633        .section ".initdata", "a"
 634setup_corrupt:
 635        .byte   7
 636        .string "No setup signature found...\n"
 637