mirror of
https://github.com/grub4dos/ntloader.git
synced 2025-05-11 21:11:33 +08:00
364 lines
9.3 KiB
ArmAsm
364 lines
9.3 KiB
ArmAsm
/*
|
|
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* bzImage prefix
|
|
*
|
|
*/
|
|
|
|
#include <ntboot.h>
|
|
|
|
/* Refer to i386 symbols as needed */
|
|
#if __x86_64__
|
|
#define i386(symbol) __i386_ ## symbol
|
|
#else
|
|
#define i386(symbol) symbol
|
|
#endif
|
|
|
|
/** Standard number of setup sectors */
|
|
#define SETUP_SECTS 4
|
|
|
|
/** Sector size */
|
|
#define SECTOR_SIZE 512
|
|
|
|
/** Protected-mode code will be loaded high */
|
|
#define LOADED_HIGH 0x01
|
|
|
|
/** Protected-mode code will be loaded to this linear address */
|
|
#define LOADED_HIGH_ADDRESS 0x100000
|
|
|
|
/** Protected-mode bit in CR0 */
|
|
#define CR0_PE 0x01
|
|
|
|
/** 32-bit protected mode code segment based at real-mode %cs:0000 */
|
|
#define PREFIX_CS 0x08
|
|
|
|
/** 32 bit protected mode flat code segment */
|
|
#define PREFIX_FLAT_CS 0x10
|
|
|
|
/** 32 bit protected mode flat data segment */
|
|
#define PREFIX_FLAT_DS 0x18
|
|
|
|
/* PE header architecture-dependent values */
|
|
#if __x86_64__
|
|
.equ coff_machine, 0x8664
|
|
.equ coff_characteristics, 0x2022
|
|
.equ opt_magic, 0x20b
|
|
#else
|
|
.equ coff_machine, 0x014c
|
|
.equ coff_characteristics, 0x2102
|
|
.equ opt_magic, 0x10b
|
|
#endif
|
|
|
|
.text
|
|
.code16
|
|
.arch i386
|
|
.org 0
|
|
.section ".prefix", "ax", @progbits
|
|
|
|
.org 0
|
|
_prefix:
|
|
mz_header:
|
|
.ascii "MZ"
|
|
.org mz_header + 0x3c
|
|
mz_lfanew:
|
|
.word ( pe_header - _prefix )
|
|
.equ mz_header_len, . - mz_header
|
|
.size mz_header, . - mz_header
|
|
|
|
.org 0x40
|
|
pe_header:
|
|
.ascii "PE" /* Signature */
|
|
.byte 0, 0
|
|
.word coff_machine /* Machine */
|
|
.word 5 /* NumberOfSections */
|
|
.long 0x10d1a884 /* TimeDateStamp */
|
|
.long 0 /* PointerToSymbolTable */
|
|
.long 0 /* NumberOfSymbols */
|
|
.word ( opt_header_len + data_directory_len ) /*SizeOfOptionalHeader*/
|
|
.word coff_characteristics /* Characteristics */
|
|
.equ pe_header_len, . - pe_header
|
|
.size pe_header, . - pe_header
|
|
opt_header:
|
|
.word opt_magic /* Magic */
|
|
.byte 42 /* MajorLinkerVersion */
|
|
.byte 42 /* MinorLinkerVersion */
|
|
.long _text_total_len /* SizeOfCode */
|
|
.long _data_total_len /* SizeOfInitializedData */
|
|
.long _bss_total_len /* SizeOfUninitializedData */
|
|
.long ( efi_main - BASE_ADDRESS ) /* AddressOfEntryPoint */
|
|
.long ( _text - BASE_ADDRESS ) /* BaseOfCode */
|
|
#if __x86_64__
|
|
.quad BASE_ADDRESS /* ImageBase */
|
|
#else
|
|
.long ( _data - BASE_ADDRESS ) /* BaseOfData */
|
|
.long BASE_ADDRESS /* ImageBase */
|
|
#endif
|
|
.long 0x200 /* SectionAlignment */
|
|
.long 0x200 /* FileAlignment */
|
|
.word 0 /* MajorOperatingSystemVersion */
|
|
.word 0 /* MinorOperatingSystemVersion */
|
|
.word 1 /* MajorImageVersion */
|
|
.word 1 /* MinorImageVersion */
|
|
.word 0 /* MajorSubsystemVersion */
|
|
.word 0 /* MinorSubsystemVersion */
|
|
.long 0 /* Win32VersionValue */
|
|
.long ( _end - BASE_ADDRESS ) /* SizeOfImage */
|
|
.long _prefix_len /* SizeOfHeaders */
|
|
.long 0 /* Checksum */
|
|
.word 0x0a /* Subsystem */
|
|
.word 0 /* DllCharacteristics */
|
|
#if __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 8 /* NumberOfRvaAndSizes */
|
|
.equ opt_header_len, . - opt_header
|
|
.size opt_header, . - opt_header
|
|
data_directory:
|
|
.org data_directory + ( 8 * 5 )
|
|
directory_entry_reloc:
|
|
.long ( _reloc - BASE_ADDRESS )
|
|
.long 0
|
|
.org data_directory + ( 8 * 6 )
|
|
directory_entry_debug:
|
|
.long ( debug - _prefix )
|
|
.long debug_len
|
|
.org data_directory + ( 8 * 8 )
|
|
.equ data_directory_len, . - data_directory
|
|
.size data_directory, . - data_directory
|
|
coff_sections:
|
|
.ascii ".bss16" /* Name */
|
|
.byte 0, 0
|
|
.long _bss16_len /* Misc.VirtualSize */
|
|
.long ( _bss16 - BASE_ADDRESS ) /* VirtualAddress */
|
|
.long 0 /* SizeOfRawData */
|
|
.long 0 /* PointerToRawData */
|
|
.long 0 /* PointerToRelocations */
|
|
.long 0 /* PointerToLinenumbers */
|
|
.word 0 /* NumberOfRelocations */
|
|
.word 0 /* NumberOfLinenumbers */
|
|
.long 0xc8000080 /* Characteristics */
|
|
.ascii ".payload" /* Name */
|
|
.long _payload_len /* Misc.VirtualSize */
|
|
.long ( _payload - BASE_ADDRESS ) /* VirtualAddress */
|
|
.long _payload_len /* SizeOfRawData */
|
|
.long _payload_pos /* PointerToRawData */
|
|
.long 0 /* PointerToRelocations */
|
|
.long 0 /* PointerToLinenumbers */
|
|
.word 0 /* NumberOfRelocations */
|
|
.word 0 /* NumberOfLinenumbers */
|
|
.long 0xe80000e0 /* Characteristics */
|
|
.ascii ".bss" /* Name */
|
|
.byte 0, 0, 0, 0
|
|
.long _bss_len /* Misc.VirtualSize */
|
|
.long ( _bss - BASE_ADDRESS ) /* VirtualAddress */
|
|
.long 0 /* SizeOfRawData */
|
|
.long 0 /* PointerToRawData */
|
|
.long 0 /* PointerToRelocations */
|
|
.long 0 /* PointerToLinenumbers */
|
|
.word 0 /* NumberOfRelocations */
|
|
.word 0 /* NumberOfLinenumbers */
|
|
.long 0xc8000080 /* Characteristics */
|
|
.ascii ".sbat" /* Name */
|
|
.byte 0, 0, 0
|
|
.long _sbat_used /* Misc.VirtualSize */
|
|
.long ( _sbat - BASE_ADDRESS ) /* VirtualAddress */
|
|
.long _sbat_len /* SizeOfRawData */
|
|
.long _sbat_pos /* PointerToRawData */
|
|
.long 0 /* PointerToRelocations */
|
|
.long 0 /* PointerToLinenumbers */
|
|
.word 0 /* NumberOfRelocations */
|
|
.word 0 /* NumberOfLinenumbers */
|
|
.long 0x48000040 /* Characteristics */
|
|
.ascii ".reloc" /* Name */
|
|
.byte 0, 0
|
|
.long 0 /* Misc.VirtualSize */
|
|
.long ( _reloc - BASE_ADDRESS ) /* VirtualAddress */
|
|
.long 0 /* SizeOfRawData */
|
|
.long _reloc_pos /* PointerToRawData */
|
|
.long 0 /* PointerToRelocations */
|
|
.long 0 /* PointerToLinenumbers */
|
|
.word 0 /* NumberOfRelocations */
|
|
.word 0 /* NumberOfLinenumbers */
|
|
.long 0x48000040 /* Characteristics */
|
|
.equ coff_sections_len, . - coff_sections
|
|
.size coff_sections, . - coff_sections
|
|
|
|
.org 0x1f1
|
|
setup_sects:
|
|
.byte SETUP_SECTS
|
|
|
|
.org 0x1fe
|
|
boot_flag:
|
|
.word 0xaa55
|
|
|
|
.org 0x200
|
|
jump:
|
|
.byte 0xeb, setup - 1f
|
|
1:
|
|
|
|
.org 0x202
|
|
header:
|
|
.ascii "HdrS"
|
|
|
|
.org 0x206
|
|
version:
|
|
.word 0x203 /* Version 2.03 */
|
|
|
|
.org 0x20e
|
|
kernel_version:
|
|
.word ( version_string - _prefix - 0x200 )
|
|
|
|
.org 0x211
|
|
loadflags:
|
|
.byte LOADED_HIGH
|
|
|
|
.org 0x218
|
|
ramdisk_image:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x21c
|
|
ramdisk_size:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x228
|
|
cmd_line_ptr:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x22c
|
|
ramdisk_max:
|
|
.long 0xffffffff
|
|
|
|
version_string:
|
|
.asciz VERSION
|
|
|
|
/* Setup code */
|
|
setup:
|
|
/* Reset %cs so that labels work */
|
|
pushw %ds
|
|
pushw $( 1f - _prefix )
|
|
lret
|
|
1:
|
|
/* Fix up GDT */
|
|
xorl %eax, %eax
|
|
movw %cs, %ax
|
|
shll $4, %eax
|
|
addl %eax, ( gdt - _prefix + 2 )
|
|
addl %eax, ( gdt - _prefix + PREFIX_CS + 2 )
|
|
|
|
/* Switch to protected mode and jump to startup code */
|
|
cli
|
|
data32 lgdt ( gdt - _prefix )
|
|
movl %cr0, %eax
|
|
orb $CR0_PE, %al
|
|
movl %eax, %cr0
|
|
data32 ljmp $PREFIX_CS, $( 1f - _prefix )
|
|
.code32
|
|
1:
|
|
/* Load data segment registers */
|
|
movw $PREFIX_FLAT_DS, %ax
|
|
movw %ax, %ds
|
|
movw %ax, %es
|
|
movw %ax, %fs
|
|
movw %ax, %gs
|
|
movw %ax, %ss
|
|
|
|
/* Zero real-mode and protected-mode .bss sections */
|
|
xorl %eax, %eax
|
|
movl $_bss16, %edi
|
|
movl $_bss16_len, %ecx
|
|
rep stosb
|
|
movl $_bss, %edi
|
|
movl $_bss_len, %ecx
|
|
rep stosb
|
|
|
|
/* Copy payload to runtime address */
|
|
movl $LOADED_HIGH_ADDRESS, %esi
|
|
movl $_payload, %edi
|
|
movl $_payload_len, %ecx
|
|
cld
|
|
rep movsb
|
|
|
|
/* Copy parameters required by runtime */
|
|
movl %cs:( cmd_line_ptr - _prefix ), %eax
|
|
movl %eax, i386(cmdline)
|
|
movl %cs:( ramdisk_image - _prefix ), %eax
|
|
movl %eax, i386(initrd)
|
|
movl %cs:( ramdisk_size - _prefix ), %eax
|
|
movl %eax, i386(initrd_len)
|
|
|
|
/* Jump to payload */
|
|
ljmp $PREFIX_FLAT_CS, $i386(startup)
|
|
.size setup, . - setup
|
|
|
|
/* Global descriptor table */
|
|
gdt:
|
|
.word gdt_limit
|
|
.long ( gdt - _prefix )
|
|
/* 32-bit protected mode code segment based at real-mode %cs:0000 */
|
|
.org ( gdt + PREFIX_CS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x9f, 0xcf, 0
|
|
/* 32 bit protected mode flat code segment */
|
|
.org ( gdt + PREFIX_FLAT_CS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x9f, 0xcf, 0
|
|
/* 32 bit protected mode flat data segment */
|
|
.org ( gdt + PREFIX_FLAT_DS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x93, 0xcf, 0
|
|
.size gdt, . - gdt
|
|
.equ gdt_limit, . - gdt - 1
|
|
|
|
.org 0x400
|
|
debug:
|
|
.long 0 /* Characteristics */
|
|
.long 0x10d1a884 /* TimeDateStamp */
|
|
.word 0 /* MajorVersion */
|
|
.word 0 /* MinorVersion */
|
|
.long 2 /* Type */
|
|
.long debug_rsds_len /* SizeOfData */
|
|
.long ( debug_rsds - _prefix ) /* RVA */
|
|
.long ( debug_rsds - _prefix ) /* FileOffset */
|
|
.equ debug_len, . - debug
|
|
.size debug, . - debug
|
|
debug_rsds:
|
|
.ascii "RSDS" /* Signature */
|
|
.long 0 /* Unknown */
|
|
.long 0 /* Unknown2 */
|
|
.long 0 /* Unknown3 */
|
|
.long 0 /* Unknown4 */
|
|
.long 0 /* Unknown5 */
|
|
.asciz "wimboot.efi"
|
|
.equ debug_rsds_len, . - debug_rsds
|
|
.size debug_rsds, . - debug_rsds
|
|
|
|
.org ( ( SETUP_SECTS + 1 ) * SECTOR_SIZE )
|