memtest86plus/boot/header.S
Martin Whitaker b01c8e4388 Avoid sbverify warning about gap in section table.
We have a .setup section in the EFI image that contains the remainder of
the Linux boot header and the real-mode setup code to support booting via
an intermediate bootloader. This sits between the PE header and the .text
section. We don't want the EFI loader to load this section, so simply
increase the SizeOfHeader field in the PE header to cover it.
2023-02-02 14:01:13 +01:00

252 lines
6.5 KiB
ArmAsm

// SPDX-License-Identifier: GPL-2.0
//
// header.S supports booting directly from a UEFI BIOS or via an intermediate
// bootloader that supports the Linux boot protocol. When booted directly from
// the BIOS, it provides the MS-DOS & PE/COFF headers. When using an intermediate
// bootloader, it provides the first few bytes of the Linux boot header (at the
// end of the boot sector), with the remainder of the header being provided by
// setup.S.
//
// Copyright (C) 2020-2023 Martin Whitaker.
//
// Derived from Linux 5.6 arch/x86/boot/header.S:
//
// Copyright (C) 1991, 1992 Linus Torvalds
//
// Based on bootsect.S and setup.S
// modified by more people than can be counted
//
// Rewritten as a common file by H. Peter Anvin (Apr 2007)
#define __ASSEMBLY__
#include "boot.h"
#include "peimage.h"
# The EFI loader loads the header at ImageBase, so we have to locate the main program
# after that. This means we can't load the main program at HIGH_LOAD_ADDR. Pick a load
# address well away from HIGH_LOAD_ADDR, to avoid overlap when relocating the code.
#define IMAGE_BASE 0x200000
.section ".header", "ax", @progbits
.code16
.globl boot
boot:
# "MZ", the MS-DOS header signature.
.byte 0x4d
.byte 0x5a
# In case we are booted by a legacy BIOS, print an error message.
# Fortunately the MS-DOS header translates to harmless instructions.
ljmp $BOOT_SEG, $(error - boot)
error:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %sp, %sp
sti
cld
movw $error_msg, %si
0: lodsb
andb %al, %al
jz wait
movb $0xe, %ah
movw $7, %bx
int $0x10
jmp 0b
wait:
# Allow the user to press a key, then reboot.
xorw %ax, %ax
int $0x16
int $0x19
# int 0x19 should never return. In case it does, invoke the BIOS.
# reset code.
ljmp $0xf000,$0xfff0
# The PE header pointer.
.org 0x3c
.long pe_header
error_msg:
.ascii "This is a UEFI bootable image\r\n"
.ascii "\n"
.asciz "Press any key to reboot\r\n"
pe_header:
.ascii "PE"
.word 0
coff_header:
#ifdef __x86_64__
.word IMAGE_FILE_MACHINE_X64 # Machine (x86-64)
#else
.word IMAGE_FILE_MACHINE_I386 # Machine (i386)
#endif
.word 3 # NumberOfSections
.long 0 # TimeDateStamp
.long 0 # PointerToSymbolTable
.long 0 # NumberOfSymbols
.word section_table - optional_header # SizeOfOptionalHeader
#ifdef __x86_64__
.word IMAGE_FILE_DEBUG_STRIPPED \
| IMAGE_FILE_LOCAL_SYMS_STRIPPED \
| IMAGE_FILE_LINE_NUMS_STRIPPED \
| IMAGE_FILE_EXECUTABLE_IMAGE # Characteristics
#else
.word IMAGE_FILE_32BIT_MACHINE \
| IMAGE_FILE_DEBUG_STRIPPED \
| IMAGE_FILE_LOCAL_SYMS_STRIPPED \
| IMAGE_FILE_LINE_NUMS_STRIPPED \
| IMAGE_FILE_EXECUTABLE_IMAGE # Characteristics.
#endif
optional_header:
#ifdef __x86_64__
.word IMAGE_NT_OPTIONAL_HDR64_MAGIC # PE32+ format
#else
.word IMAGE_NT_OPTIONAL_HDR32_MAGIC # PE32 format
#endif
.byte 0x02 # MajorLinkerVersion
.byte 0x14 # MinorLinkerVersion
.long _virt_text_size # SizeOfCode
.long _virt_sbat_size # SizeOfInitializedData
.long 0 # SizeOfUninitializedData
.long _virt_text_start + 0x1e0 # AddressOfEntryPoint
.long _virt_text_start # BaseOfCode
#ifndef __x86_64__
.long _virt_sbat_start # BaseOfData
#endif
extra_header_fields:
#ifdef __x86_64__
.quad IMAGE_BASE # ImageBase
#else
.long IMAGE_BASE # ImageBase
#endif
.long 4096 # SectionAlignment
.long 512 # FileAlignment
.word 0 # MajorOperatingSystemVersion
.word 0 # MinorOperatingSystemVersion
.word 0 # MajorImageVersion
.word 0 # MinorImageVersion
.word 0 # MajorSubsystemVersion
.word 0 # MinorSubsystemVersion
.long 0 # Win32VersionValue
.long _virt_img_size # SizeOfImage
.long _file_head_size # SizeOfHeaders
.long 0 # CheckSum
.word 10 # Subsystem (EFI application)
.word 0 # DllCharacteristics
#ifdef __x86_64__
.quad 0 # SizeOfStackReserve
.quad 0 # SizeOfStackCommit
.quad 0 # SizeOfHeapReserve
.quad 0 # SizeOfHeapCommit
#else
.long 0 # SizeOfStackReserve
.long 0 # SizeOfStackCommit
.long 0 # SizeOfHeapReserve
.long 0 # SizeOfHeapCommit
#endif
.long 0 # LoaderFlags
.long IMAGE_DIRECTORY_ENTRY_DEBUG # NumberOfRvaAndSizes
.long 0 # DataDirectory.Export.VirtualAddress
.long 0 # DataDirectory.Export.Size
.long 0 # DataDirectory.Import.VirtualAddress
.long 0 # DataDirectory.Import.Size
.long 0 # DataDirectory.Resource.VirtualAddress
.long 0 # DataDirectory.Resource.Size
.long 0 # DataDirectory.Exception.VirtualAddress
.long 0 # DataDirectory.Exception.Size
.long 0 # DataDirectory.Certs.VirtualAddress
.long 0 # DataDirectory.Certs.Size
.long _virt_reloc_start # DataDirectory.BaseReloc.VirtualAddress
.long _real_reloc_size # DataDirectory.BaseReloc.Size
# Section table
section_table:
.ascii ".text"
.byte 0
.byte 0
.byte 0
.long _virt_text_size # VirtualSize
.long _virt_text_start # VirtualAddress
.long _file_text_size # SizeOfRawData
.long _file_text_start # PointerToRawData
.long 0 # PointerToRelocations
.long 0 # PointerToLineNumbers
.word 0 # NumberOfRelocations
.word 0 # NumberOfLineNumbers
.long IMAGE_SCN_MEM_READ \
| IMAGE_SCN_MEM_EXECUTE \
| IMAGE_SCN_CNT_CODE # Characteristics (section flags)
.ascii ".reloc"
.byte 0
.byte 0
.long _virt_reloc_size # VirtualSize
.long _virt_reloc_start # VirtualAddress
.long _file_reloc_size # SizeOfRawData
.long _file_reloc_start # PointerToRawData
.long 0 # PointerToRelocations
.long 0 # PointerToLineNumbers
.word 0 # NumberOfRelocations
.word 0 # NumberOfLineNumbers
.long IMAGE_SCN_MEM_READ \
| IMAGE_SCN_CNT_INITIALIZED_DATA # Characteristics (section flags)
.ascii ".sbat"
.byte 0
.byte 0
.byte 0
.long _virt_sbat_size # VirtualSize
.long _virt_sbat_start # VirtualAddress
.long _file_sbat_size # SizeOfRawData
.long _file_sbat_start # PointerToRawData
.long 0 # PointerToRelocations
.long 0 # PointerToLineNumbers
.word 0 # NumberOfRelocations
.word 0 # NumberOfLineNumbers
.long IMAGE_SCN_MEM_READ \
| IMAGE_SCN_CNT_INITIALIZED_DATA # Characteristics (section flags)
# Emulate the Linux boot header, to allow loading by intermediate boot loaders.
.org 497
setup_sects:
.byte SETUP_SECS
root_flags:
.word 0
sys_size:
.long _sys_size
ram_size:
.word 0
vid_mode:
.word 0
root_dev:
.word 0
boot_flag:
.word 0xAA55
.org 512
.section ".reloc"
.long 0 // Page RVA
.long 10 // Block Size (2*4+2)
.word (IMAGE_REL_BASED_ABSOLUTE << 12) + 0 // reloc 0 -> 0
.section ".sbat", "a", @progbits
.incbin "../boot/sbat.csv"