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