EFI: Initial test EFI application

* Only set HAIKU_BOOT_PLATFORM to bios_ia32 if not defined
* Add gnuefi build feature
* Introduce BOOT_LDFLAGS, and move options for passing to linker
  into ArchitectureSetup
* x86_64 compile fixes for warnings in boot loader
* loader/elf.cpp: don't include ELF32 support when targeting EFI
* relocation_func.cpp: copy of the relocation code from gnuefi
  to make _relocate extern "C", and avoid including <efilib.h>
* boot_loader_efi.ld: copy of gnuefi's elf_x86_64_efi.lds,
  modified to include support for C++ constructors, etc. Keep in
  sync with the gnuefi package

Signed-off-by: Jessica Hamilton <[email protected]>
This commit is contained in:
Fredrik Holmqvist
2016-09-02 19:02:29 +12:00
committed by Jessica Hamilton
parent 20e11028aa
commit 211483cb51
27 changed files with 474 additions and 59 deletions
+27 -12
View File
@@ -279,7 +279,7 @@ rule KernelArchitectureSetup architecture
HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET = 192 ; # in kB - unused yet
case x86 :
HAIKU_BOOT_PLATFORM = bios_ia32 ;
HAIKU_BOOT_PLATFORM ?= bios_ia32 ;
HAIKU_BOOT_FLOPPY_IMAGE_SIZE = 2880 ; # in kB
# offset in floppy image (>= sizeof(haiku_loader))
HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET = 320 ; # in kB
@@ -291,7 +291,7 @@ rule KernelArchitectureSetup architecture
case x86_64 :
# x86_64 completely shares the x86 bootloader.
HAIKU_BOOT_PLATFORM = bios_ia32 ;
HAIKU_BOOT_PLATFORM ?= bios_ia32 ;
HAIKU_BOOT_FLOPPY_IMAGE_SIZE = 2880 ; # in kB
# offset in floppy image (>= sizeof(haiku_loader))
HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET = 320 ; # in kB
@@ -326,12 +326,6 @@ rule KernelArchitectureSetup architecture
Exit "Currently unsupported target CPU:" $(cpu) ;
}
# Include embedded board-specific file.
if $(HAIKU_BOOT_BOARD) {
include [ FDirName $(HAIKU_BUILD_RULES_DIR) board $(HAIKU_BOOT_BOARD)
BoardSetup ] ;
}
# private kernel headers to be used when compiling kernel code
HAIKU_PRIVATE_KERNEL_HEADERS =
[ PrivateHeaders $(DOT) kernel libroot shared
@@ -361,6 +355,7 @@ rule KernelArchitectureSetup architecture
HAIKU_BOOT_CCFLAGS = $(HAIKU_CCFLAGS_$(architecture)) $(gccBaseFlags) ;
HAIKU_BOOT_C++FLAGS = $(HAIKU_C++FLAGS_$(architecture)) $(g++BaseFlags) ;
HAIKU_BOOT_LINKFLAGS = ;
HAIKU_BOOT_LDFLAGS = -Bstatic ;
if $(gccVersion[1]) >= 4 {
HAIKU_KERNEL_C++FLAGS += -std=gnu++11 ;
@@ -370,6 +365,16 @@ rule KernelArchitectureSetup architecture
HAIKU_KERNEL_PIC_LINKFLAGS = ;
HAIKU_KERNEL_ADDON_LINKFLAGS = ;
# Include embedded board-specific file.
if $(HAIKU_BOOT_BOARD) {
include [ FDirName $(HAIKU_BUILD_RULES_DIR) board $(HAIKU_BOOT_BOARD)
BoardSetup ] ;
if $(HAIKU_BOARD_LOADER_BASE) {
HAIKU_BOOT_LDFLAGS +=
--defsym BOARD_LOADER_BASE=$(HAIKU_BOARD_LOADER_BASE) ;
}
}
switch $(cpu) {
case ppc :
# Build a position independent PPC kernel. We need to be able to
@@ -401,10 +406,20 @@ rule KernelArchitectureSetup architecture
HAIKU_KERNEL_PIC_LINKFLAGS += -z max-page-size=0x1000 ;
HAIKU_KERNEL_ADDON_LINKFLAGS += -z max-page-size=0x1000 ;
# Bootloader is 32-bit.
HAIKU_BOOT_LINKFLAGS += -m elf_i386_haiku ;
HAIKU_BOOT_CCFLAGS += -m32 -march=pentium ;
HAIKU_BOOT_C++FLAGS += -m32 -march=pentium ;
# BIOS Bootloader is 32-bit.
if $(HAIKU_BOOT_PLATFORM) = bios_ia32 {
HAIKU_BOOT_LINKFLAGS += -m elf_i386_haiku ;
HAIKU_BOOT_CCFLAGS += -m32 -march=pentium ;
HAIKU_BOOT_C++FLAGS += -m32 -march=pentium ;
}
}
if $(HAIKU_BOOT_PLATFORM) = efi {
HAIKU_BOOT_CCFLAGS += -fpic -fno-stack-protector -fPIC -fshort-wchar -mno-red-zone
-maccumulate-outgoing-args -Wno-error=unused-variable ;
HAIKU_BOOT_C++FLAGS += -fpic -fno-stack-protector -fPIC -fshort-wchar -mno-red-zone
-maccumulate-outgoing-args -Wno-error=unused-variable ;
HAIKU_BOOT_LDFLAGS = -Bstatic -Bsymbolic -shared -nostdlib -znocombreloc -nostartfiles ;
}
# warning flags
+1 -1
View File
@@ -47,7 +47,7 @@ rule BootLd
LINK on $(1) = $(TARGET_LD_$(TARGET_PACKAGING_ARCH)) ;
LINKFLAGS on $(1) = $(4) ;
LINKFLAGS on $(1) = $(TARGET_BOOT_LINKFLAGS) $(4) ;
if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
# Remove any preset LINKLIBS, but link against libgcc.a. Linking against
+17
View File
@@ -571,6 +571,23 @@ if [ IsPackageAvailable expat_devel ] {
}
# gnu-efi
if $(TARGET_PACKAGING_ARCH) = x86_64 {
if [ IsPackageAvailable gnuefi ] {
ExtractBuildFeatureArchives gnuefi :
file: base gnuefi
headers: $(developHeadersDir)/gnuefi
headersProtocol: $(developHeadersDir)/gnuefi/protocol
headersArch: $(developHeadersDir)/gnuefi/$(TARGET_ARCH)
libdir: $(libDir)/gnuefi
;
EnableBuildFeatures gnuefi ;
} else {
Echo "gnuefi support not available on $(TARGET_PACKAGING_ARCH)" ;
}
}
# GPL add-ons
if $(HAIKU_INCLUDE_GPL_ADDONS) = 1 {
EnableBuildFeatures gpl ;
+1 -1
View File
@@ -649,7 +649,7 @@ local buildVars =
KERNEL_CCFLAGS KERNEL_C++FLAGS
KERNEL_PIC_CCFLAGS KERNEL_PIC_LINKFLAGS KERNEL_ADDON_LINKFLAGS
BOOT_CCFLAGS BOOT_C++FLAGS BOOT_LINKFLAGS
BOOT_CCFLAGS BOOT_C++FLAGS BOOT_LINKFLAGS BOOT_LDFLAGS
KERNEL_WARNING_CCFLAGS KERNEL_WARNING_C++FLAGS
View File
@@ -0,0 +1,46 @@
/*
* Copyright 2013-2016 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_BOOT_PLATFORM_EFI_KERNEL_ARGS_H
#define KERNEL_BOOT_PLATFORM_EFI_KERNEL_ARGS_H
#ifndef KERNEL_BOOT_KERNEL_ARGS_H
# error This file is included from <boot/kernel_args.h> only
#endif
// currently the EFI loader pretends to be the bios_ia32 platform.
// not quite right, as the kernel needs to be aware of efi runtime services
#include <arch/x86/apm.h>
#include <boot/disk_identifier.h>
#include <util/FixedWidthPointer.h>
#define SMP_MAX_CPUS 64
#define MAX_PHYSICAL_MEMORY_RANGE 32
#define MAX_PHYSICAL_ALLOCATED_RANGE 32
#define MAX_VIRTUAL_ALLOCATED_RANGE 32
#define MAX_SERIAL_PORTS 4
typedef struct bios_drive {
struct bios_drive *next;
uint16 drive_number;
disk_identifier identifier;
} bios_drive;
typedef struct {
uint16 serial_base_ports[MAX_SERIAL_PORTS];
FixedWidthPointer<bios_drive> drives;
// this does not contain the boot drive
// seems to be ignored entirely?
apm_info apm;
} _PACKED platform_kernel_args;
#endif /* KERNEL_BOOT_PLATFORM_BIOS_IA32_KERNEL_ARGS_H */
@@ -0,0 +1,17 @@
/*
* Copyright 2013-2016 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_BOOT_PLATFORM_EFI_STAGE2_ARGS_H
#define _KERNEL_BOOT_PLATFORM_EFI_STAGE2_ARGS_H
#ifndef KERNEL_BOOT_STAGE2_ARGS_H
# error This file is included from <boot/stage2_args.h> only
#endif
struct platform_stage2_args {
};
#endif /* _KERNEL_BOOT_PLATFORM_EFI_STAGE2_ARGS_H */
+25 -8
View File
@@ -2,8 +2,14 @@ SubDir HAIKU_TOP src system boot ;
DEFINES += _BOOT_MODE ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
$(TARGET_KERNEL_ARCH) ] ;
if $(TARGET_ARCH) = x86_64 && $(TARGET_BOOT_PLATFORM) != bios_ia32 {
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
x86_64 ] ;
} else {
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
$(TARGET_KERNEL_ARCH) ] ;
}
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix string ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix stdlib ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix locale ] ;
@@ -44,11 +50,6 @@ BootMergeObject boot_libroot.o :
: -fno-pic
;
local extraLinkerArgs = ;
if $(HAIKU_BOARD_LOADER_BASE) {
extraLinkerArgs += --defsym BOARD_LOADER_BASE=$(HAIKU_BOARD_LOADER_BASE) ;
}
AddResources haiku_loader : boot_loader.rdef ;
BootLd boot_loader_$(TARGET_BOOT_PLATFORM) :
@@ -76,7 +77,7 @@ BootLd boot_loader_$(TARGET_BOOT_PLATFORM) :
boot_libroot.o
: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_loader_$(TARGET_BOOT_PLATFORM).ld
: -Bstatic $(extraLinkerArgs)
: $(TARGET_BOOT_LDFLAGS)
;
rule BuildCoffLoader {
@@ -130,6 +131,22 @@ BuildBiosLoader haiku_loader : boot_loader_$(TARGET_BOOT_PLATFORM) ;
# different target for PXE, to be build with TARGET_BOOT_PLATFORM=pxe_ia32 jam pxehaiku-loader
BuildBiosLoader pxehaiku-loader : boot_loader_$(TARGET_BOOT_PLATFORM) ;
rule BuildEFILoader {
local efiLoader = $(1) ;
local bootLoader = $(2) ;
Depends $(efiLoader) : $(bootLoader) ;
MakeLocateDebug $(efiLoader) ;
}
actions BuildEFILoader {
rm -f $(1)
$(TARGET_OBJCOPY_$(TARGET_PACKAGING_ARCH)) -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
-j .rel -j .rela -j .reloc --target=efi-app-x86_64 $(2) $(1)
}
BuildEFILoader haiku_loader.efi : boot_loader_$(TARGET_BOOT_PLATFORM) ;
SubInclude HAIKU_TOP src system boot arch $(TARGET_KERNEL_ARCH) ;
SubInclude HAIKU_TOP src system boot loader ;
SubInclude HAIKU_TOP src system boot platform ;
+22 -12
View File
@@ -6,13 +6,15 @@ local kernelArchSources =
arch_elf.cpp
;
local kernelArch32Sources =
cpuid.S
;
local kernelLibArchSources =
arch_string.S
;
local kernelArchSpecificSources ;
local kernelLibArchSpecificSources ;
if $(TARGET_ARCH) = x86_64 && $(TARGET_BOOT_PLATFORM) != bios_ia32 {
kernelArchSpecificSources = cpuid.cpp ;
kernelLibArchSpecificSources = arch_string.cpp ;
} else {
kernelArchSpecificSources = cpuid.S ;
kernelLibArchSpecificSources = arch_string.S ;
}
local librootOsArchSources =
byteorder.S
@@ -20,17 +22,25 @@ local librootOsArchSources =
BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o :
$(kernelArchSources)
$(kernelArch32Sources)
$(kernelLibArchSources)
$(kernelArchSpecificSources)
$(kernelLibArchSpecificSources)
$(librootOsArchSources)
: # additional flags
: -std=c++11 # additional flags
;
SEARCH on [ FGristFiles $(kernelArchSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel arch x86 ] ;
SEARCH on [ FGristFiles $(kernelArch32Sources) ]
if $(TARGET_ARCH) = x86_64 && $(TARGET_BOOT_PLATFORM) != bios_ia32 {
SEARCH on [ FGristFiles $(kernelArchSpecificSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel arch x86 64 ] ;
SEARCH on [ FGristFiles $(kernelLibArchSpecificSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot posix string arch x86_64 ] ;
} else {
SEARCH on [ FGristFiles $(kernelArchSpecificSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel arch x86 32 ] ;
SEARCH on [ FGristFiles $(kernelLibArchSources) ]
SEARCH on [ FGristFiles $(kernelLibArchSpecificSources) ]
= [ FDirName $(HAIKU_TOP) src system kernel lib arch x86 ] ;
}
SEARCH on [ FGristFiles $(librootOsArchSources) ]
= [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ;
+5
View File
@@ -45,6 +45,11 @@ UsePrivateHeaders shared storage ;
#BOOT_SUPPORT_FILE_SYSTEM_FAT
;
if $(HAIKU_BOOT_PLATFORM) != efi {
DEFINES +=
BOOT_SUPPORT_ELF32
;
}
}
}
+12 -3
View File
@@ -61,6 +61,7 @@ private:
};
#ifdef BOOT_SUPPORT_ELF32
struct ELF32Class {
static const uint8 kIdentClass = ELFCLASS32;
@@ -96,6 +97,7 @@ struct ELF32Class {
};
typedef ELFLoader<ELF32Class> ELF32Loader;
#endif
#ifdef BOOT_SUPPORT_ELF64
@@ -225,7 +227,7 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
// known but unused type
continue;
default:
dprintf("unhandled pheader type 0x%lx\n", header.p_type);
dprintf("unhandled pheader type 0x%" B_PRIx32 "\n", header.p_type);
continue;
}
@@ -320,7 +322,7 @@ ELFLoader<Class>::Load(int fd, preloaded_image* _image)
header.p_filesz);
if (length < (ssize_t)header.p_filesz) {
status = B_BAD_DATA;
dprintf("error reading in seg %ld\n", i);
dprintf("error reading in seg %" B_PRId32 "\n", i);
goto error2;
}
@@ -642,13 +644,14 @@ elf_load_image(int fd, preloaded_image** _image)
return status;
}
#endif
#if BOOT_SUPPORT_ELF32
if (gKernelArgs.kernel_image == NULL
|| gKernelArgs.kernel_image->elf_class == ELFCLASS32) {
status = ELF32Loader::Create(fd, _image);
if (status == B_OK)
return ELF32Loader::Load(fd, *_image);
}
#endif
return status;
}
@@ -706,16 +709,22 @@ elf_relocate_image(preloaded_image* image)
return ELF64Loader::Relocate(image);
else
#endif
#ifdef BOOT_SUPPORT_ELF32
return ELF32Loader::Relocate(image);
#else
return B_ERROR;
#endif
}
#ifdef BOOT_SUPPORT_ELF32
status_t
boot_elf_resolve_symbol(preloaded_elf32_image* image, Elf32_Sym* symbol,
Elf32_Addr* symbolAddress)
{
return ELF32Loader::Resolve(image, symbol, symbolAddress);
}
#endif
#ifdef BOOT_SUPPORT_ELF64
@@ -107,7 +107,7 @@ Stream::ReadAt(off_t offset, uint8 *buffer, size_t size)
{
if (offset < 0)
return B_BAD_VALUE;
if (offset + size > fNode.Size())
if (offset + (off_t)size > fNode.Size())
size = fNode.Size() - offset;
ssize_t bytesLeft = (ssize_t)size;
@@ -186,7 +186,7 @@ HashIterator::GetNext(int32 &block)
fNode.SetTo(fData);
if (fNode.ValidateCheckSum() != B_OK) {
dprintf("block at %ld bad checksum.\n", fBlock);
dprintf("block at %" B_PRId32 " bad checksum.\n", fBlock);
return NULL;
}
@@ -306,7 +306,7 @@ Stream::ReadAt(off_t pos, uint8* buffer, size_t* _length)
size_t length = *_length;
if (pos + length > data.Size())
if (pos + (off_t)length > data.Size())
length = data.Size() - pos;
block_run run;
@@ -112,7 +112,8 @@ Volume::ValidateBlockRun(block_run run)
|| run.Start() > (1UL << AllocationGroupShift())
|| run.length == 0
|| uint32(run.Length() + run.Start()) > (1UL << AllocationGroupShift())) {
dprintf("bfs: invalid run(%ld,%d,%d)\n", run.AllocationGroup(), run.Start(), run.Length());
dprintf("bfs: invalid run(%" B_PRId32 ",%d,%d)\n",
run.AllocationGroup(), run.Start(), run.Length());
return B_BAD_DATA;
}
return B_OK;
@@ -257,7 +257,7 @@ Stream::ReadAt(off_t pos, void *_buffer, size_t *_length, off_t *diskOffset)
size_t length = *_length;
if (pos + length > fSize)
if (pos + (off_t)length > fSize)
length = fSize - pos;
off_t num; // block number
@@ -525,7 +525,7 @@ struct File : ::Node {
off_t size = fFile->Size();
if (pos < 0 || pos > size)
return B_BAD_VALUE;
if (pos + bufferSize > size)
if (pos + (off_t)bufferSize > size)
bufferSize = size - pos;
if (bufferSize > 0) {
@@ -101,7 +101,7 @@ load_driver_settings(stage2_args* /*args*/, Directory* volume)
status_t status = load_driver_settings_file(settings, name);
if (status != B_OK)
dprintf("Could not load \"%s\" error %ld\n", name, status);
dprintf("Could not load \"%s\" error %" B_PRIx32 "\n", name, status);
}
settings->Close(cookie);
+3 -3
View File
@@ -123,7 +123,7 @@ load_kernel(stage2_args* args, BootVolume& volume)
close(fd);
if (status < B_OK) {
dprintf("loading kernel failed: %lx!\n", status);
dprintf("loading kernel failed: %" B_PRIx32 "!\n", status);
return status;
}
@@ -131,7 +131,7 @@ load_kernel(stage2_args* args, BootVolume& volume)
status = elf_relocate_image(gKernelArgs.kernel_image);
if (status < B_OK) {
dprintf("relocating kernel failed: %lx!\n", status);
dprintf("relocating kernel failed: %" B_PRIx32 "!\n", status);
return status;
}
@@ -163,7 +163,7 @@ load_modules_from(BootVolume& volume, const char* path)
status_t status = elf_load_image(modules, name);
if (status != B_OK)
dprintf("Could not load \"%s\" error %ld\n", name, status);
dprintf("Could not load \"%s\" error %" B_PRIx32 "\n", name, status);
}
modules->Close(cookie);
+2 -1
View File
@@ -169,7 +169,8 @@ RemoteDisk::GetName(char *nameBuffer, size_t bufferSize) const
if (!nameBuffer)
return B_BAD_VALUE;
snprintf(nameBuffer, bufferSize, "RemoteDisk:%ld.%ld.%ld.%ld:%hd",
snprintf(nameBuffer, bufferSize,
"RemoteDisk:%" B_PRIu32 ".%" B_PRIu32 ".%" B_PRIu32 ".%" B_PRIu32 ":%hd",
(fServerAddress >> 24) & 0xff, (fServerAddress >> 16) & 0xff,
(fServerAddress >> 8) & 0xff, fServerAddress & 0xff, fServerPort);
+9 -8
View File
@@ -168,7 +168,7 @@ Partition::ReadAt(void *cookie, off_t position, void *buffer, size_t bufferSize)
if (position < 0)
return B_BAD_VALUE;
if (position + bufferSize > this->size)
if (position + (off_t)bufferSize > this->size)
bufferSize = this->size - position;
ssize_t result = read_pos(fFD, this->offset + position, buffer, bufferSize);
@@ -185,7 +185,7 @@ Partition::WriteAt(void *cookie, off_t position, const void *buffer,
if (position < 0)
return B_BAD_VALUE;
if (position + bufferSize > this->size)
if (position + (off_t)bufferSize > this->size)
bufferSize = this->size - position;
ssize_t result = write_pos(fFD, this->offset + position, buffer,
@@ -321,7 +321,7 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice)
if (priority < 0.0)
continue;
TRACE((" priority: %ld\n", (int32)(priority * 1000)));
TRACE((" priority: %" B_PRId32 "\n", (int32)(priority * 1000)));
if (priority <= bestPriority) {
// the disk system recognized the partition worse than the currently
// best one
@@ -379,9 +379,9 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice)
Partition *child = NULL;
while ((child = (Partition *)iterator.Next()) != NULL) {
TRACE(("%p Partition::Scan(): scan child %p (start = %Ld, size "
"= %Ld, parent = %p)!\n", this, child, child->offset,
child->size, child->Parent()));
TRACE(("%p Partition::Scan(): scan child %p (start = %" B_PRId64
", size = %" B_PRIdOFF ", parent = %p)!\n", this, child,
child->offset, child->size, child->Parent()));
child->Scan(mountFileSystems);
@@ -466,7 +466,7 @@ add_partitions_for(Node *device, bool mountFileSystems, bool isBootDevice)
status_t status = add_partitions_for(fd, mountFileSystems, isBootDevice);
if (status < B_OK)
dprintf("add_partitions_for(%d) failed: %ld\n", fd, status);
dprintf("add_partitions_for(%d) failed: %" B_PRIx32 "\n", fd, status);
close(fd);
return B_OK;
@@ -505,7 +505,8 @@ get_child_partition(partition_id id, int32 index)
{
// TODO: do we really have to implement this?
// The intel partition module doesn't really need this for our mission...
TRACE(("get_child_partition(id = %lu, index = %ld)\n", id, index));
TRACE(("get_child_partition(id = %" B_PRId32 ", index = %" B_PRId32 ")\n",
id, index));
return NULL;
}
+3 -1
View File
@@ -294,7 +294,9 @@ MemoryDisk::MemoryDisk(const uint8* data, size_t size, const char* name)
ssize_t
MemoryDisk::ReadAt(void* cookie, off_t pos, void* buffer, size_t bufferSize)
{
if (pos >= fSize)
if (pos < 0)
return B_BAD_VALUE;
if ((size_t)pos >= fSize)
return 0;
if (pos + bufferSize > fSize)
+40
View File
@@ -0,0 +1,40 @@
SubDir HAIKU_TOP src system boot platform efi ;
UsePrivateHeaders [ FDirName kernel boot ] ;
UseBuildFeatureHeaders gnuefi ;
UseBuildFeatureHeaders gnuefi : headersProtocol ;
UseBuildFeatureHeaders gnuefi : headersArch ;
{
local defines = _BOOT_MODE GNU_EFI_USE_MS_ABI _BOOT_PLATFORM=efi ;
defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) -fno-rtti ;
}
local efi_glue_src =
crt0-efi-x86_64.S
;
local platform_src =
relocation_func.cpp
start.c
;
Includes [ FGristFiles $(efi_glue_src) $(platform_src) ]
:
[ BuildFeatureAttribute gnuefi : headers ]
[ BuildFeatureAttribute gnuefi : headersProtocol ]
[ BuildFeatureAttribute gnuefi : headersArch ]
;
BootMergeObject boot_platform_efi.o :
$(efi_glue_src)
$(platform_src)
:
: boot_platform_generic.a
;
SEARCH on [ FGristFiles relocation_func.cpp ] = [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
LOCATE on [ FGristFiles $(efi_glue_src) ] = [ BuildFeatureAttribute gnuefi : libdir : path ] ;
Depends [ FGristFiles $(efi_glue_src) ] : [ BuildFeatureAttribute gnuefi : libdir ] ;
@@ -0,0 +1,97 @@
/* reloc_x86_64.c - position independent x86_64 ELF shared object relocator
Copyright (C) 1999 Hewlett-Packard Co.
Contributed by David Mosberger <davidm@hpl.hp.com>.
Copyright (C) 2005 Intel Co.
Contributed by Fenghua Yu <fenghua.yu@intel.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Hewlett-Packard Co. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include <efi.h>
#include <elf.h>
extern "C" EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
EFI_HANDLE image __attribute__((__unused__)),
EFI_SYSTEM_TABLE *systab __attribute__((__unused__)))
{
long relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
unsigned long *addr;
int i;
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
switch (dyn[i].d_tag) {
case DT_RELA:
rel = (Elf64_Rel*)
((unsigned long)dyn[i].d_un.d_ptr
+ ldbase);
break;
case DT_RELASZ:
relsz = dyn[i].d_un.d_val;
break;
case DT_RELAENT:
relent = dyn[i].d_un.d_val;
break;
default:
break;
}
}
if (!rel && relent == 0)
return EFI_SUCCESS;
if (!rel || relent == 0)
return EFI_LOAD_ERROR;
while (relsz > 0) {
/* apply the relocs */
switch (ELF64_R_TYPE (rel->r_info)) {
case R_X86_64_NONE:
break;
case R_X86_64_RELATIVE:
addr = (unsigned long *)
(ldbase + rel->r_offset);
*addr += ldbase;
break;
default:
break;
}
rel = (Elf64_Rel*) ((char *) rel + relent);
relsz -= relent;
}
return EFI_SUCCESS;
}
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2011, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "efibind.h"
#include "efidef.h"
#include "efidevp.h"
#include "eficon.h"
#include "efiprot.h"
#include "efiapi.h"
#include "efierr.h"
static const CHAR16 *exampleText = L"Example EFI Application. Press any key!";
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable);
/**
* efi_main - The entry point for the EFI application
* @image: firmware-allocated handle that identifies the image
* @SystemTable: EFI system table
*/
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable)
{
UINTN index;
EFI_EVENT event = systemTable->ConIn->WaitForKey;
SIMPLE_TEXT_OUTPUT_INTERFACE *conOut = systemTable->ConOut;
conOut->OutputString(conOut, (CHAR16*)exampleText);
systemTable->BootServices->WaitForEvent(1, &event, &index);
return EFI_SUCCESS;
}
+2 -2
View File
@@ -37,7 +37,7 @@ is_in_image(struct elf_image_info *image, addr_t address)
#endif // !_BOOT_MODE
#if !defined(__x86_64__) || defined(_BOOT_MODE)
#if !defined(__x86_64__) || (defined(_BOOT_MODE) && _BOOT_PLATFORM != efi)
#ifdef TRACE_ARCH_ELF
@@ -183,7 +183,7 @@ arch_elf_relocate_rela(struct elf_image_info *image,
}
#endif // !__x86_64__ || _BOOT_MODE
#endif // !__x86_64__ || (_BOOT_MODE && _BOOT_PLATFORM != efi)
#if defined(__x86_64__) || defined(_BOOT_MODE)
@@ -0,0 +1,79 @@
/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below & ctor support - KEEP IN SYNC */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0;
ImageBase = .;
.hash : { *(.hash) } /* this MUST come first! */
. = ALIGN(4096);
.eh_frame :
{
*(.eh_frame)
}
. = ALIGN(4096);
.text :
{
_text = .;
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
. = ALIGN(16);
}
_etext = .;
_text_size = . - _text;
. = ALIGN(4096);
.reloc :
{
*(.reloc)
}
. = ALIGN(4096);
.data :
{
. = ALIGN(0x4);
__ctor_list = .;
*(.ctors)
__ctor_end = .;
_data = .;
*(.rodata*)
*(.got.plt)
*(.got)
*(.data*)
*(.sdata)
/* the EFI loader doesn't seem to like a .bss section, so we stick
it all into .data: */
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
*(.rel.local)
}
.note.gnu.build-id : { *(.note.gnu.build-id) }
_edata = .;
_data_size = . - _etext;
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
.rela :
{
*(.rela.data*)
*(.rela.ctors)
*(.rela.got)
*(.rela.stab)
}
. = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
. = ALIGN(4096);
.ignored.reloc :
{
*(.rela.reloc)
*(.eh_frame)
*(.note.GNU-stack)
}
.comment 0 : { *(.comment) }
}