Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[efi] Add EFI image format and basic runtime environment
We have EFI APIs for CPU I/O, PCI I/O, timers, console I/O, user
access and user memory allocation.

EFI executables are created using the vanilla GNU toolchain, with the
EXE header handcrafted in assembly and relocations generated by a
custom efilink utility.
  • Loading branch information
Michael Brown committed Oct 13, 2008
1 parent 54c024e commit 81d92c6
Show file tree
Hide file tree
Showing 40 changed files with 4,781 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Makefile
Expand Up @@ -37,6 +37,7 @@ SYMCHECK := $(PERL) ./util/symcheck.pl
SORTOBJDUMP := $(PERL) ./util/sortobjdump.pl
NRV2B := ./util/nrv2b
ZBIN := ./util/zbin
EFILINK := ./util/efilink
DOXYGEN := doxygen

###############################################################################
Expand All @@ -57,7 +58,7 @@ SRCDIRS += drivers/block
SRCDIRS += drivers/nvs
SRCDIRS += drivers/bitbash
SRCDIRS += drivers/infiniband
SRCDIRS += interface/pxe
SRCDIRS += interface/pxe interface/efi
SRCDIRS += tests
SRCDIRS += crypto crypto/axtls crypto/matrixssl
SRCDIRS += hci hci/commands hci/tui
Expand Down
9 changes: 9 additions & 0 deletions src/Makefile.housekeeping
Expand Up @@ -693,6 +693,15 @@ $(ZBIN) : util/zbin.c util/nrv2b.c $(MAKEDEPS)
$(Q)$(HOST_CC) -O2 -o $@ $<
CLEANUP += $(ZBIN)

###############################################################################
#
# The EFI custom linker
#
$(EFILINK) : util/efilink.c $(MAKEDEPS)
$(QM)$(ECHO) " [HOSTCC] $@"
$(Q)$(HOST_CC) -O2 -o $@ $< -lbfd
CLEANUP += $(EFILINK)

###############################################################################
#
# Auto-incrementing build serial number. Append "bs" to your list of
Expand Down
1 change: 1 addition & 0 deletions src/arch/i386/Makefile
Expand Up @@ -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.
Expand Down
24 changes: 24 additions & 0 deletions 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 $< $@
1 change: 1 addition & 0 deletions src/arch/i386/include/bits/nap.h
Expand Up @@ -8,5 +8,6 @@
*/

#include <gpxe/bios_nap.h>
#include <gpxe/efi/efix86_nap.h>

#endif /* _BITS_MAP_H */
16 changes: 16 additions & 0 deletions 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 */
46 changes: 46 additions & 0 deletions 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 );
175 changes: 175 additions & 0 deletions 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

0 comments on commit 81d92c6

Please sign in to comment.