diff options
Diffstat (limited to 'src/arch/i386')
-rw-r--r-- | src/arch/i386/Makefile | 1 | ||||
-rw-r--r-- | src/arch/i386/Makefile.efi | 24 | ||||
-rw-r--r-- | src/arch/i386/include/bits/nap.h | 1 | ||||
-rw-r--r-- | src/arch/i386/include/gpxe/efi/efix86_nap.h | 16 | ||||
-rw-r--r-- | src/arch/i386/interface/efi/efix86_nap.c | 46 | ||||
-rw-r--r-- | src/arch/i386/prefix/efiprefix.S | 175 | ||||
-rw-r--r-- | src/arch/i386/scripts/efi.lds | 174 |
7 files changed, 437 insertions, 0 deletions
diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile index 1959fbfd..dac53493 100644 --- a/src/arch/i386/Makefile +++ b/src/arch/i386/Makefile @@ -64,6 +64,7 @@ SRCDIRS += arch/i386/drivers/net SRCDIRS += arch/i386/interface/pcbios SRCDIRS += arch/i386/interface/pxe SRCDIRS += arch/i386/interface/syslinux +SRCDIRS += arch/i386/interface/efi # The various xxx_loader.c files are #included into core/loader.c and # should not be compiled directly. diff --git a/src/arch/i386/Makefile.efi b/src/arch/i386/Makefile.efi new file mode 100644 index 00000000..f1eb6fdf --- /dev/null +++ b/src/arch/i386/Makefile.efi @@ -0,0 +1,24 @@ +# -*- makefile -*- : Force emacs to use Makefile mode + +# The EFI linker script +# +LDSCRIPT = arch/i386/scripts/efi.lds + +# Use a relocatable link; we perform final relocations in the efilink utility. +# +LDFLAGS += -r -d -S + +# Media types. +# +NON_AUTO_MEDIA += efi + +# Rule for building EFI files +# +$(BIN)/%.efi.tmp-reloc : $(BIN)/%.efi.tmp $(EFILINK) + $(QM)$(ECHO) " [EFILINK] $@" + $(Q)$(LD) -e 0 -o /dev/null $< # Check for unresolved symbols + $(Q)$(EFILINK) $< $@ + +$(BIN)/%.efi : $(BIN)/%.efi.tmp-reloc + $(QM)$(ECHO) " [FINISH] $@" + $(Q)$(OBJCOPY) -Obinary $< $@ diff --git a/src/arch/i386/include/bits/nap.h b/src/arch/i386/include/bits/nap.h index 2c85444a..f8ba7a7c 100644 --- a/src/arch/i386/include/bits/nap.h +++ b/src/arch/i386/include/bits/nap.h @@ -8,5 +8,6 @@ */ #include <gpxe/bios_nap.h> +#include <gpxe/efi/efix86_nap.h> #endif /* _BITS_MAP_H */ diff --git a/src/arch/i386/include/gpxe/efi/efix86_nap.h b/src/arch/i386/include/gpxe/efi/efix86_nap.h new file mode 100644 index 00000000..91424c54 --- /dev/null +++ b/src/arch/i386/include/gpxe/efi/efix86_nap.h @@ -0,0 +1,16 @@ +#ifndef _GPXE_EFIX86_NAP_H +#define _GPXE_EFIX86_NAP_H + +/** @file + * + * EFI CPU sleeping + * + */ + +#ifdef NAP_EFIX86 +#define NAP_PREFIX_efix86 +#else +#define NAP_PREFIX_efix86 __efix86_ +#endif + +#endif /* _GPXE_EFIX86_NAP_H */ diff --git a/src/arch/i386/interface/efi/efix86_nap.c b/src/arch/i386/interface/efi/efix86_nap.c new file mode 100644 index 00000000..45e99a68 --- /dev/null +++ b/src/arch/i386/interface/efi/efix86_nap.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <gpxe/nap.h> +#include <gpxe/efi/efi.h> + +/** @file + * + * gPXE CPU sleeping API for EFI + * + */ + +/** + * Sleep until next interrupt + * + */ +static void efix86_cpu_nap ( void ) { + /* + * I can't find any EFI API that allows us to put the CPU to + * sleep. The CpuSleep() function is defined in CpuLib.h, but + * isn't part of any exposed protocol so we have no way to + * call it. + * + * The EFI shell doesn't seem to bother sleeping the CPU; it + * just sits there idly burning power. + * + */ + __asm__ __volatile__ ( "hlt" ); +} + +PROVIDE_NAP ( efix86, cpu_nap, efix86_cpu_nap ); diff --git a/src/arch/i386/prefix/efiprefix.S b/src/arch/i386/prefix/efiprefix.S new file mode 100644 index 00000000..c4cf68e4 --- /dev/null +++ b/src/arch/i386/prefix/efiprefix.S @@ -0,0 +1,175 @@ + .text + .code32 + .arch i386 + .section ".prefix", "a", @progbits + .org 0x00 + + /* DOS (.com) header + * + * EFI executables seem to leave most of this empty + */ +mzhdr: + .ascii "MZ" /* Magic number */ + .word 0 /* Bytes on last page of file */ + .word 0 /* Pages in file */ + .word 0 /* Relocations */ + .word 0 /* Size of header in paragraphs */ + .word 0 /* Minimum extra paragraphs needed */ + .word 0 /* Maximum extra paragraphs needed */ + .word 0 /* Initial (relative) SS value */ + .word 0 /* Initial SP value */ + .word 0 /* "Checksum" */ + .word 0 /* Initial IP value */ + .word 0 /* Initial (relative) CS value */ + .word 0 /* File address of relocation table */ + .word 0 /* Ovesrlay number */ + .word 0, 0, 0, 0 /* Reserved words */ + .word 0 /* OEM identifier (for e_oeminfo) */ + .word 0 /* OEM information; e_oemid specific */ + .word 0, 0, 0, 0, 0 /* Reserved words */ + .word 0, 0, 0, 0, 0 /* Reserved words */ + .long pehdr_lma /* File address of new exe header */ + .size mzhdr, . - mzhdr + + /* PE header */ + .org 0xc0 /* For compatibility with MS toolchain */ +pehdr: + .ascii "PE\0\0" /* Magic number */ + .word 0x014c /* CPU architecture: i386 */ + .word num_pe_sections /* Number of sections */ + .long 0x10d1a884 /* Timestamp */ + .long 0 /* Symbol table */ + .long 0 /* Number of symbols */ + .word opthdr_size /* Size of optional header */ + .word 0x2102 /* Characteristics */ + .size pehdr, . - pehdr + .equ pehdr_lma, pehdr - mzhdr + + /* "Optional" header */ +opthdr: + .word 0x010b /* Magic number */ + .byte 0 /* Linker major version number */ + .byte 0 /* Linker minor version number */ + .long _text_filesz /* Size of text section */ + .long _data_filesz /* Size of data section */ + .long _bss_filesz /* Size of bss section */ + .long efi_entry_lma /* Entry point */ + .long _text_lma /* Text section start RVA */ + .long _data_lma /* Data section start RVA */ + .long 0 /* Image base address */ + .long _max_align /* Section alignment */ + .long _max_align /* File alignment */ + .word 0 /* Operating system major version number */ + .word 0 /* Operating system minor version number */ + .word 0 /* Image major version number */ + .word 0 /* Image minor version number */ + .word 0 /* Subsystem major version number */ + .word 0 /* Subsystem minor version number */ + .long 0 /* Reserved */ + .long _filesz /* Total image size */ + .long _prefix_filesz /* Total header size */ + .long 0 /* "Checksum" */ + .word 0x0a /* Subsystem: EFI */ + .word 0 /* DLL characteristics */ + .long 0 /* Size of stack reserve */ + .long 0 /* Size of stack commit */ + .long 0 /* Size of heap reserve */ + .long 0 /* Size of heap commit */ + .long 0 /* Loader flags */ + .long 16 /* Number of data directory entries */ + .long 0, 0 /* Export directory */ + .long 0, 0 /* Import directory */ + .long 0, 0 /* Resource directory */ + .long 0, 0 /* Exception directory */ + .long 0, 0 /* Security directory */ + .long _reloc_lma, _reloc_filesz /* Base relocation directory */ + .long debugdir_lma, debugdir_size /* Debug directory */ + .long 0, 0 /* Description directory */ + .long 0, 0 /* Special directory */ + .long 0, 0 /* Thread storage directory */ + .long 0, 0 /* Load configuration directory */ + .long 0, 0 /* Bound import directory */ + .long 0, 0 /* Import address table directory */ + .long 0, 0 /* Delay import directory */ + .long 0, 0 /* Reserved */ + .long 0, 0 /* Reserved */ + .size opthdr, . - opthdr + .equ opthdr_size, . - opthdr + + /* PE sections */ +pe_sections: +text_section: + .asciz ".text" /* Section name */ + .align 8 + .long _text_filesz /* Section size */ + .long _text_lma /* Relative Virtual Address */ + .long _text_filesz /* Section size (rounded up) */ + .long _text_lma /* Pointer to raw data */ + .long 0 /* Link-time relocations */ + .long 0 /* Line numbers */ + .word 0 /* Number of link-time relocations */ + .word 0 /* Number of line numbers */ + .long 0x68000020 /* Characteristics */ +rodata_section: + .asciz ".rodata" /* Section name */ + .align 8 + .long _rodata_filesz /* Section size */ + .long _rodata_lma /* Relative Virtual Address */ + .long _rodata_filesz /* Section size (rounded up) */ + .long _rodata_lma /* Pointer to raw data */ + .long 0 /* Link-time relocations */ + .long 0 /* Line numbers */ + .word 0 /* Number of link-time relocations */ + .word 0 /* Number of line numbers */ + .long 0x48000040 /* Characteristics */ +data_section: + .asciz ".data" /* Section name */ + .align 8 + .long _data_filesz /* Section size */ + .long _data_lma /* Relative Virtual Address */ + .long _data_filesz /* Section size (rounded up) */ + .long _data_lma /* Pointer to raw data */ + .long 0 /* Link-time relocations */ + .long 0 /* Line numbers */ + .word 0 /* Number of link-time relocations */ + .word 0 /* Number of line numbers */ + .long 0xc8000040 /* Characteristics */ +reloc_section: + .asciz ".reloc" /* Section name */ + .align 8 + .long _reloc_filesz /* Section size */ + .long _reloc_lma /* Relative Virtual Address */ + .long _reloc_filesz /* Section size (rounded up) */ + .long _reloc_lma /* Pointer to raw data */ + .long 0 /* Link-time relocations */ + .long 0 /* Line numbers */ + .word 0 /* Number of link-time relocations */ + .word 0 /* Number of line numbers */ + .long 0x42000040 /* Characteristics */ + +pe_sections_end: + .size pe_sections, . - pe_sections + .equ num_pe_sections, ( ( . - pe_sections ) / 0x28 ) + + /* Debug directory */ + .section ".rodata" + .globl debugdir +debugdir: + .long 0 /* Characteristics */ + .long 0x10d1a884 /* Timestamp */ + .word 0 /* Major version */ + .word 0 /* Minor version */ + .long 0x02 /* RSDS? */ + .long codeview_rsds_size /* Size of data */ + .long codeview_rsds_lma /* RVA */ + .long codeview_rsds_lma /* File offset */ + .size debugdir, . - debugdir + .equ debugdir_size, . - debugdir + /* Codeview structure */ + .globl codeview_rsds +codeview_rsds: + .ascii "RSDS" /* Magic number */ + .long 0, 0, 0, 0, 0 /* Unused by EFI */ + .asciz "efiprefix.pdb" + .size codeview_rsds, . - codeview_rsds + .equ codeview_rsds_size, . - codeview_rsds diff --git a/src/arch/i386/scripts/efi.lds b/src/arch/i386/scripts/efi.lds new file mode 100644 index 00000000..8d9ecd77 --- /dev/null +++ b/src/arch/i386/scripts/efi.lds @@ -0,0 +1,174 @@ +/* -*- sh -*- */ + +/* + * Linker script for EFI images + * + */ + +EXTERN ( efi_entry ) + +SECTIONS { + + /* The file starts at a virtual address of zero, and sections are + * contiguous. Each section is aligned to at least _max_align, + * which defaults to 32. Load addresses are equal to virtual + * addresses. + */ + + . = 0; + PROVIDE ( _max_align = 32 ); + + /* + * The prefix + * + */ + + .prefix : AT ( _prefix_lma ) { + _prefix = .; + *(.prefix) + *(.prefix.*) + _mprefix = .; + } .prefix_bss (NOLOAD) : { + _eprefix = .; + } + _prefix_filesz = ABSOLUTE ( _mprefix - _prefix ); + _prefix_memsz = ABSOLUTE ( _eprefix - _prefix ); + + /* + * The text section + * + */ + + . = ALIGN ( _max_align ); + .text : AT ( _text_lma ) { + _text = .; + *(.text) + *(.text.*) + _mtext = .; + } .text_bss (NOLOAD) : { + _etext = .; + } + _text_filesz = ABSOLUTE ( _mtext - _text ); + _text_memsz = ABSOLUTE ( _etext - _text ); + + /* + * The rodata section + * + */ + + . = ALIGN ( _max_align ); + .rodata : AT ( _rodata_lma ) { + _rodata = .; + *(.rodata) + *(.rodata.*) + _mrodata = .; + } .rodata_bss (NOLOAD) : { + _erodata = .; + } + _rodata_filesz = ABSOLUTE ( _mrodata - _rodata ); + _rodata_memsz = ABSOLUTE ( _erodata - _rodata ); + + /* + * The data section + * + */ + + . = ALIGN ( _max_align ); + .data : AT ( _data_lma ) { + _data = .; + *(.data) + *(.data.*) + *(SORT(.tbl.*)) /* Various tables. See include/tables.h */ + /* EFI seems to not support proper bss sections */ + *(.bss) + *(.bss.*) + *(COMMON) + *(.stack) + *(.stack.*) + _mdata = .; + } .data_bss (NOLOAD) : { + _edata = .; + } + _data_filesz = ABSOLUTE ( _mdata - _data ); + _data_memsz = ABSOLUTE ( _edata - _data ); + + /* + * The bss section + * + */ + + . = ALIGN ( _max_align ); + .bss : AT ( _bss_lma ) { + _bss = .; + /* EFI seems to not support proper bss sections */ + _mbss = .; + } .bss_bss (NOLOAD) : { + _ebss = .; + } + _bss_filesz = ABSOLUTE ( _mbss - _bss ); + _bss_memsz = ABSOLUTE ( _ebss - _bss ); + + /* + * The reloc section + * + */ + + . = ALIGN ( _max_align ); + .reloc : AT ( _reloc_lma ) { + _reloc = .; + /* Provide some dummy contents to force ld to include this + * section. It will be created by the efilink utility. + */ + . += 1; + _mreloc = .; + } .reloc_bss (NOLOAD) : { + _ereloc = .; + } + _reloc_filesz = ABSOLUTE ( _mreloc - _reloc ); + _reloc_memsz = ABSOLUTE ( _ereloc - _reloc ); + + _filesz = ABSOLUTE ( . ); + + /* + * Weak symbols that need zero values if not otherwise defined + * + */ + + .weak 0x0 : { + _weak = .; + *(.weak) + _eweak = .; + } + _assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" ); + + /* + * Dispose of the comment and note sections to make the link map + * easier to read + * + */ + + /DISCARD/ : { + *(.comment) + *(.note) + } + + /* + * Load address calculations. + * + */ + + _prefix_lma = ABSOLUTE ( _prefix ); + _text_lma = ABSOLUTE ( _text ); + _rodata_lma = ABSOLUTE ( _rodata ); + _data_lma = ABSOLUTE ( _data ); + _bss_lma = ABSOLUTE ( _bss ); + _reloc_lma = ABSOLUTE ( _reloc ); + + /* + * Load addresses required by the prefix + * + */ + efi_entry_lma = ABSOLUTE ( efi_entry ); + debugdir_lma = ABSOLUTE ( debugdir ); + codeview_rsds_lma = ABSOLUTE ( codeview_rsds ); +} |