From 9071550e8697ed9df3d24b369bd30e3f0e190d1f Mon Sep 17 00:00:00 2001 From: klu2 Date: Fri, 18 Apr 2008 03:09:54 +0000 Subject: Add missing module for duet package. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5088 6f19259b-4bc3-4df7-8a09-765794883524 --- DuetPkg/EfiLdr/Debug.c | 93 ++++++ DuetPkg/EfiLdr/Debug.h | 49 ++++ DuetPkg/EfiLdr/EfiLdr.h | 115 ++++++++ DuetPkg/EfiLdr/EfiLdr.inf | 58 ++++ DuetPkg/EfiLdr/EfiLdrHandoff.h | 56 ++++ DuetPkg/EfiLdr/EfiLoader.c | 266 +++++++++++++++++ DuetPkg/EfiLdr/Ia32/EfiLdr.inf | 27 ++ DuetPkg/EfiLdr/Ia32/Makefile | 183 ++++++++++++ DuetPkg/EfiLdr/PeLoader.c | 641 +++++++++++++++++++++++++++++++++++++++++ DuetPkg/EfiLdr/PeLoader.h | 42 +++ DuetPkg/EfiLdr/Support.c | 237 +++++++++++++++ DuetPkg/EfiLdr/Support.h | 50 ++++ DuetPkg/EfiLdr/X64/EfiLdr.inf | 27 ++ DuetPkg/EfiLdr/X64/Makefile | 186 ++++++++++++ DuetPkg/EfiLdr/efildr.c | 28 ++ 15 files changed, 2058 insertions(+) create mode 100644 DuetPkg/EfiLdr/Debug.c create mode 100644 DuetPkg/EfiLdr/Debug.h create mode 100644 DuetPkg/EfiLdr/EfiLdr.h create mode 100644 DuetPkg/EfiLdr/EfiLdr.inf create mode 100644 DuetPkg/EfiLdr/EfiLdrHandoff.h create mode 100644 DuetPkg/EfiLdr/EfiLoader.c create mode 100644 DuetPkg/EfiLdr/Ia32/EfiLdr.inf create mode 100644 DuetPkg/EfiLdr/Ia32/Makefile create mode 100644 DuetPkg/EfiLdr/PeLoader.c create mode 100644 DuetPkg/EfiLdr/PeLoader.h create mode 100644 DuetPkg/EfiLdr/Support.c create mode 100644 DuetPkg/EfiLdr/Support.h create mode 100644 DuetPkg/EfiLdr/X64/EfiLdr.inf create mode 100644 DuetPkg/EfiLdr/X64/Makefile create mode 100644 DuetPkg/EfiLdr/efildr.c (limited to 'DuetPkg/EfiLdr') diff --git a/DuetPkg/EfiLdr/Debug.c b/DuetPkg/EfiLdr/Debug.c new file mode 100644 index 0000000000..2cc8c73a1e --- /dev/null +++ b/DuetPkg/EfiLdr/Debug.c @@ -0,0 +1,93 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + Debug.c + +Abstract: + +Revision History: + +--*/ +#include "EfiLdr.h" +#include "Debug.h" + +UINT8 *mCursor; +UINT8 mHeaderIndex = 10; + +VOID +PrintHeader ( + CHAR8 Char + ) +{ + *(UINT8 *)(UINTN)(0x000b8000 + mHeaderIndex) = Char; + mHeaderIndex += 2; +} + +VOID +ClearScreen ( + VOID + ) +{ + UINT32 Index; + + mCursor = (UINT8 *)(UINTN)(0x000b8000 + 160); + for (Index = 0; Index < 80 * 49; Index++) { + *mCursor = ' '; + mCursor += 2; + } + mCursor = (UINT8 *)(UINTN)(0x000b8000 + 160); +} + +VOID +PrintValue64 ( + UINT64 Value + ) +{ + PrintValue ((UINT32) RShiftU64 (Value, 32)); + PrintValue ((UINT32) Value); +} + +VOID +PrintValue ( + UINT32 Value + ) +{ + UINT32 Index; + UINT8 Char; + + for (Index = 0; Index < 8; Index++) { + Char = (UINT8)((Value >> ((7 - Index) * 4)) & 0x0f) + '0'; + if (Char > '9') { + Char = Char - '0' - 10 + 'A'; + } + *mCursor = Char; + mCursor += 2; + } +} + +VOID +PrintString ( + UINT8 *String + ) +{ + UINT32 Index; + + for (Index = 0; String[Index] != 0; Index++) { + if (String[Index] == '\n') { + mCursor = (UINT8 *)(UINTN)(0xb8000 + (((((UINTN)mCursor - 0xb8000) + 160) / 160) * 160)); + } else { + *mCursor = String[Index]; + mCursor += 2; + } + } +} + diff --git a/DuetPkg/EfiLdr/Debug.h b/DuetPkg/EfiLdr/Debug.h new file mode 100644 index 0000000000..9939109e91 --- /dev/null +++ b/DuetPkg/EfiLdr/Debug.h @@ -0,0 +1,49 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + Debug.h + +Abstract: + +Revision History: + +--*/ + +#ifndef _EFILDR_DEBUG_H_ +#define _EFILDR_DEBUG_H_ + +VOID +PrintHeader ( + CHAR8 Char + ); + +VOID +PrintValue ( + UINT32 Value + ); + +VOID +PrintValue64 ( + UINT64 Value + ); + +VOID +PrintString ( + UINT8 *String + ); + +VOID +ClearScreen ( + VOID + ); + +#endif diff --git a/DuetPkg/EfiLdr/EfiLdr.h b/DuetPkg/EfiLdr/EfiLdr.h new file mode 100644 index 0000000000..b1d0e1c272 --- /dev/null +++ b/DuetPkg/EfiLdr/EfiLdr.h @@ -0,0 +1,115 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + EfiLdr.c + +Abstract: + +Revision History: + +--*/ + +#ifndef _DUET_EFI_LOADER_H_ +#define _DUET_EFI_LOADER_H_ + +#include "FrameworkDxe.h" +#include "Uefi.h" +#include "EfiLdrHandoff.h" + +#include +#include +#include +#include +#include + +#define INT15_E820_AddressRangeMemory 1 +#define INT15_E820_AddressRangeReserved 2 +#define INT15_E820_AddressRangeACPI 3 +#define INT15_E820_AddressRangeNVS 4 + +#define EFI_FIRMWARE_BASE_ADDRESS 0x00200000 + +#define EFI_DECOMPRESSED_BUFFER_ADDRESS 0x00600000 + +#define EFI_MAX_MEMORY_DESCRIPTORS 64 + +#define LOADED_IMAGE_SIGNATURE EFI_SIGNATURE_32('l','d','r','i') + +typedef struct { + UINTN Signature; + CHAR16 *Name; // Displayable name + UINTN Type; + + BOOLEAN Started; // If entrypoint has been called + VOID *StartImageContext; + + EFI_IMAGE_ENTRY_POINT EntryPoint; // The image's entry point + EFI_LOADED_IMAGE_PROTOCOL Info; // loaded image protocol + + // + EFI_PHYSICAL_ADDRESS ImageBasePage; // Location in memory + UINTN NoPages; // Number of pages + UINT8 *ImageBase; // As a char pointer + UINT8 *ImageEof; // End of memory image + + // relocate info + UINT8 *ImageAdjust; // Bias for reloc calculations + UINTN StackAddress; + UINT8 *FixupData; // Original fixup data +} EFILDR_LOADED_IMAGE; + +#pragma pack(4) +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + UINT32 Type; +} BIOS_MEMORY_MAP_ENTRY; +#pragma pack() + +typedef struct { + UINT32 MemoryMapSize; + BIOS_MEMORY_MAP_ENTRY MemoryMapEntry[1]; +} BIOS_MEMORY_MAP; + +EFI_STATUS +EFIAPI +UefiDecompressGetInfo ( + IN EFI_TIANO_DECOMPRESS_PROTOCOL *This, + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ); + +EFI_STATUS +EFIAPI +TianoDecompress ( + IN EFI_TIANO_DECOMPRESS_PROTOCOL *This, + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ); + +EFILDR_LOADED_IMAGE DxeCoreImage; +EFILDR_LOADED_IMAGE DxeIplImage; + +typedef +VOID +(* EFI_MAIN_ENTRYPOINT) ( + IN EFILDRHANDOFF *Handoff + ) +; + +#endif //_DUET_EFI_LOADER_H_ \ No newline at end of file diff --git a/DuetPkg/EfiLdr/EfiLdr.inf b/DuetPkg/EfiLdr/EfiLdr.inf new file mode 100644 index 0000000000..d829ca2479 --- /dev/null +++ b/DuetPkg/EfiLdr/EfiLdr.inf @@ -0,0 +1,58 @@ +#/*++ +# +# Copyright (c) 2006, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# EfiLdr.inf +# +# Abstract: +# +#--*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EfiLoader + FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD + #MODULE_TYPE = USER_DEFINED + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + ENTRY_POINT = EfiLoader + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + UefiApplicationEntryPoint + BaseUefiTianoDecompressLib + +[Sources.common] + Debug.h + PeLoader.h + Support.h + EfiLdrHandoff.h + EfiLdr.h + EfiLoader.c + Debug.c + PeLoader.c + Support.c + +[BuildOptions.common] + #MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib + MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE + MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h + MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi + MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny diff --git a/DuetPkg/EfiLdr/EfiLdrHandoff.h b/DuetPkg/EfiLdr/EfiLdrHandoff.h new file mode 100644 index 0000000000..786b6cb828 --- /dev/null +++ b/DuetPkg/EfiLdr/EfiLdrHandoff.h @@ -0,0 +1,56 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + EfiLdrHandoff.h + +Abstract: + +Revision History: + +--*/ + +#ifndef _EFILDR_HANDOFF_H_ +#define _EFILDR_HANDOFF_H_ + +#define EFILDR_BASE_SEGMENT 0x2000 +#define EFILDR_LOAD_ADDRESS (EFILDR_BASE_SEGMENT << 4) +#define EFILDR_HEADER_ADDRESS (EFILDR_LOAD_ADDRESS+0x2000) + +#define EFILDR_CB_VA 0x00 + +typedef struct _EFILDRHANDOFF { + UINTN MemDescCount; + EFI_MEMORY_DESCRIPTOR *MemDesc; + VOID *BfvBase; + UINTN BfvSize; + VOID *DxeIplImageBase; + UINTN DxeIplImageSize; + VOID *DxeCoreImageBase; + UINTN DxeCoreImageSize; + VOID *DxeCoreEntryPoint; +} EFILDRHANDOFF; + +typedef struct { + UINT32 CheckSum; + UINT32 Offset; + UINT32 Length; + UINT8 FileName[52]; +} EFILDR_IMAGE; + +typedef struct { + UINT32 Signature; + UINT32 HeaderCheckSum; + UINT32 FileLength; + UINT32 NumberOfImages; +} EFILDR_HEADER; + +#endif diff --git a/DuetPkg/EfiLdr/EfiLoader.c b/DuetPkg/EfiLdr/EfiLoader.c new file mode 100644 index 0000000000..382b7802a1 --- /dev/null +++ b/DuetPkg/EfiLdr/EfiLoader.c @@ -0,0 +1,266 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + EfiLoader.c + +Abstract: + +Revision History: + +--*/ + +#include "EfiLdr.h" +#include "Support.h" +#include "Debug.h" +#include "PeLoader.h" + +VOID +EfiLoader ( + UINT32 BiosMemoryMapBaseAddress + ) +{ + BIOS_MEMORY_MAP *BiosMemoryMap; + EFILDR_HEADER *EFILDRHeader; + EFILDR_IMAGE *EFILDRImage; + EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS]; + EFI_STATUS Status; + UINTN NumberOfMemoryMapEntries; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINTN BfvPageNumber; + UINTN BfvBase; + EFI_MAIN_ENTRYPOINT EfiMainEntrypoint; + static EFILDRHANDOFF Handoff; + +PrintHeader ('A'); + + ClearScreen(); + PrintString("EFI Loader\n"); + +// PrintString("&BiosMemoryMapBaseAddress = "); +// PrintValue64 ((UINT64)(&BiosMemoryMapBaseAddress)); +// PrintString(" BiosMemoryMapBaseAddress = "); +// PrintValue(BiosMemoryMapBaseAddress); +// PrintString("\n"); + + // + // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then + // round the start address up to the next page, and round the length down to a page boundry. + // + BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress); + NumberOfMemoryMapEntries = 0; + GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap); + + // + // Get information on where the image is in memory + // + + EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS); + EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER)); + +PrintHeader ('D'); + + // + // Point to the 4th image (Bfv) + // + + EFILDRImage += 3; + + // + // Decompress the image + // + + Status = UefiDecompressGetInfo ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + &DestinationSize, + &ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + Status = TianoDecompress ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, + DestinationSize, + (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), + ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize); + BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB); + if (BfvBase == 0) { + CpuDeadLoop(); + } + ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE); + CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize); + +PrintHeader ('B'); + + // + // Point to the 2nd image (DxeIpl) + // + + EFILDRImage -= 2; + + // + // Decompress the image + // + + Status = UefiDecompressGetInfo ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + &DestinationSize, + &ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + Status = TianoDecompress ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, + DestinationSize, + (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), + ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + // + // Load and relocate the EFI PE/COFF Firmware Image + // + Status = EfiLdrPeCoffLoadPeImage ( + (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), + &DxeIplImage, + &NumberOfMemoryMapEntries, + EfiMemoryDescriptor + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + +// PrintString("Image.NoPages = "); +// PrintValue(Image.NoPages); +// PrintString("\n"); + +PrintHeader ('C'); + + // + // Point to the 3rd image (DxeMain) + // + + EFILDRImage++; + + // + // Decompress the image + // + + Status = UefiDecompressGetInfo ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + &DestinationSize, + &ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + Status = TianoDecompress ( + NULL, + (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), + EFILDRImage->Length, + (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, + DestinationSize, + (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), + ScratchSize + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + + // + // Load and relocate the EFI PE/COFF Firmware Image + // + Status = EfiLdrPeCoffLoadPeImage ( + (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), + &DxeCoreImage, + &NumberOfMemoryMapEntries, + EfiMemoryDescriptor + ); + if (EFI_ERROR (Status)) { + CpuDeadLoop(); + } + +PrintHeader ('E'); + + // + // Display the table of memory descriptors. + // + +// PrintString("\nEFI Memory Descriptors\n"); +/* + { + UINTN Index; + for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) { + PrintString("Type = "); + PrintValue(EfiMemoryDescriptor[Index].Type); + PrintString(" Start = "); + PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart)); + PrintString(" NumberOfPages = "); + PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages)); + PrintString("\n"); + } + } +*/ + + // + // Jump to EFI Firmware + // + + if (DxeIplImage.EntryPoint != NULL) { + + Handoff.MemDescCount = NumberOfMemoryMapEntries; + Handoff.MemDesc = EfiMemoryDescriptor; + Handoff.BfvBase = (VOID *)(UINTN)BfvBase; + Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE; + Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage; + Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE; + Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage; + Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE; + Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint; + + EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint; + EfiMainEntrypoint (&Handoff); + } + +PrintHeader ('F'); + + // + // There was a problem loading the image, so HALT the system. + // + + CpuDeadLoop(); +} + diff --git a/DuetPkg/EfiLdr/Ia32/EfiLdr.inf b/DuetPkg/EfiLdr/Ia32/EfiLdr.inf new file mode 100644 index 0000000000..ba87791958 --- /dev/null +++ b/DuetPkg/EfiLdr/Ia32/EfiLdr.inf @@ -0,0 +1,27 @@ +#/*++ +# +# Copyright (c) 2006, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# EfiLdr.inf +# +# Abstract: +# +#--*/ + +[defines] +BASE_NAME = EfiLoader +COMPONENT_TYPE = FILE +BUILD_TYPE = CUSTOM_MAKEFILE +FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD + +[sources.common] + +[nmake.common] diff --git a/DuetPkg/EfiLdr/Ia32/Makefile b/DuetPkg/EfiLdr/Ia32/Makefile new file mode 100644 index 0000000000..61cadf7e8f --- /dev/null +++ b/DuetPkg/EfiLdr/Ia32/Makefile @@ -0,0 +1,183 @@ +#/*++ +# +# Copyright (c) 2006 - 2007, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# Makefile +# +# Abstract: +# +#--*/ + +# +# Globals +# +BIN_DIR = $(BUILD_DIR)\$(PROCESSOR) +TOOLCHAIN = TOOLCHAIN_$(PROCESSOR) + +TOOLBIN_DIR = $(BUILD_DIR)\Tools + +# +# Include CommonTools.env enviroment +# + +!INCLUDE $(BUILD_DIR)\PlatformTools.env + +# +# Include paths +# +INC = -I $(SOURCE_DIR)\. -I $(SOURCE_DIR)\.\$(PROCESSOR) $(INC) +INC = -I $(EDK_SOURCE)\Foundation\ \ + -I $(EDK_SOURCE)\Foundation\Include \ + -I $(EDK_SOURCE)\Foundation\Include\$(PROCESSOR) \ + -I $(EDK_SOURCE)\Foundation\Efi \ + -I $(EDK_SOURCE)\Foundation\Efi\Include \ + -I $(EDK_SOURCE)\Foundation\Framework \ + -I $(EDK_SOURCE)\Foundation\Framework\Include \ + -I $(EDK_SOURCE)\Foundation\Library\Dxe\Include \ + -I $(EDK_SOURCE)\Foundation\Library\Pei\Include \ + -I $(EDK_SOURCE)\Foundation\Include\Pei \ + $(INC) + +LDRDEP = $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\EfiLdrHandoff.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\EfiLoader.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Debug.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Debug.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\Support.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Support.h + +all : \ + $(BIN_DIR)\BootSect.com \ + $(BIN_DIR)\Bs16.com \ + $(BIN_DIR)\Bs32.com \ + $(BIN_DIR)\Gpt.com \ + $(BIN_DIR)\Mbr.com \ + $(BIN_DIR)\Start.com \ + $(BIN_DIR)\Start16.com \ + $(BIN_DIR)\Start32.com \ + $(BIN_DIR)\Efi32.com2 \ + $(BIN_DIR)\Efildr.efi \ + + +loader : \ + Fv\Efildr \ + Fv\Efildr16 \ + Fv\Efildr20 \ + + +# +# Generate loader object +# +$(BIN_DIR)\BootSect.obj: $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\BootSect.obj $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm + +$(BIN_DIR)\BootSect.com: $(BIN_DIR)\BootSect.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny BootSect.obj,BootSect.com,BootSect.map,,, + +$(BIN_DIR)\Bs16.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs16.obj $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm + +$(BIN_DIR)\Bs16.com: $(BIN_DIR)\Bs16.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Bs16.obj,Bs16.com,Bs16.map,,, + +$(BIN_DIR)\Bs32.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs32.obj $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm + +$(BIN_DIR)\Bs32.com: $(BIN_DIR)\Bs32.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Bs32.obj,Bs32.com,Bs32.map,,, + +$(BIN_DIR)\Gpt.obj: $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Gpt.obj $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm + +$(BIN_DIR)\Gpt.com: $(BIN_DIR)\Gpt.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Gpt.obj,Gpt.com,Gpt.map,,, + +$(BIN_DIR)\Mbr.obj: $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Mbr.obj $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm + +$(BIN_DIR)\Mbr.com: $(BIN_DIR)\Mbr.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Mbr.obj,Mbr.com,Mbr.map,,, + +$(BIN_DIR)\Start.obj: $(BUILD_DIR)\..\Loader\BootSector\Start.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Start.obj $(BUILD_DIR)\..\Loader\BootSector\Start.asm + +$(BIN_DIR)\Start.com: $(BIN_DIR)\Start.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Start.obj,Start.com,Start.map,,, + +$(BIN_DIR)\Start16.obj: $(BUILD_DIR)\..\Loader\BootSector\Start16.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Start16.obj $(BUILD_DIR)\..\Loader\BootSector\Start16.asm + +$(BIN_DIR)\Start16.com: $(BIN_DIR)\Start16.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Start16.obj,Start16.com,Start16.map,,, + +$(BIN_DIR)\Start32.obj: $(BUILD_DIR)\..\Loader\BootSector\Start32.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Start32.obj $(BUILD_DIR)\..\Loader\BootSector\Start32.asm + +$(BIN_DIR)\Start32.com: $(BIN_DIR)\Start32.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Start32.obj,Start32.com,Start32.map,,, + +$(BIN_DIR)\Efi32.obj: $(BUILD_DIR)\..\Loader\BootSector\Efi32.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Efi32.obj $(BUILD_DIR)\..\Loader\BootSector\Efi32.asm + +$(BIN_DIR)\Efi32.com: $(BIN_DIR)\Efi32.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Efi32.obj,Efi32.com,Efi32.map,,, + +$(BIN_DIR)\Efi32.com2: $(BIN_DIR)\Efi32.com + $(TOOLBIN_DIR)\Splitfile $(BIN_DIR)\Efi32.com 135168 + +$(BIN_DIR)\Efildr.obj: $(LDRDEP) + $(CC) $(C_FLAGS) $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c + +$(BIN_DIR)\Efildr.dll: $(BIN_DIR)\Efildr.obj + $(LINK) /nologo /MACHINE:X86 /SUBSYSTEM:CONSOLE /NODEFAULTLIB /INCREMENTAL:NO \ + /MAP /FIXED /BASE:0x00010000 /OPT:REF /ALIGN:32 /MERGE:.data=.text \ + /MERGE:.rdata=.text /DRIVER /ENTRY:EfiLoader $(BIN_DIR)\Efildr.obj \ + $(BIN_DIR)\CompilerStub.lib $(BIN_DIR)\EfiCommonLib.lib $(BIN_DIR)\PeiLib.lib \ + /OUT:$(BIN_DIR)\Efildr.dll /IGNORE:4078,4096 + +$(BIN_DIR)\Efildr.efi: $(BIN_DIR)\Efildr.dll + $(TOOLBIN_DIR)\FwImage app $(BIN_DIR)\Efildr.dll $(BIN_DIR)\Efildr.efi + +# +# Generate loader binary +# +Fv\EfiMain.z : Fv\EfiMain.fv + $(TOOLBIN_DIR)\Eficompress -tTiano Fv\EfiMain.fv Fv\EfiMain.z + +Fv\DxeMain.z : $(BIN_DIR)\DxeMain.efi + $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeMain.efi Fv\DxeMain.z + +Fv\DxeIpl.z : $(BIN_DIR)\DxeIpl.efi + $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeIpl.efi Fv\DxeIpl.z + +Fv\Efildr32: $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z + $(TOOLBIN_DIR)\Efildrimage Fv\Efildr32 $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z + +Fv\Efildr: $(BIN_DIR)\Start.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32 + copy /b $(BIN_DIR)\Start.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr + +Fv\Efildr16: $(BIN_DIR)\Start16.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32 + copy /b $(BIN_DIR)\Start16.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr16 + +Fv\Efildr20: $(BIN_DIR)\Start32.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32 + copy /b $(BIN_DIR)\Start32.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr20 + diff --git a/DuetPkg/EfiLdr/PeLoader.c b/DuetPkg/EfiLdr/PeLoader.c new file mode 100644 index 0000000000..73608da161 --- /dev/null +++ b/DuetPkg/EfiLdr/PeLoader.c @@ -0,0 +1,641 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + PeLoader.c + +Abstract: + +Revision History: + +--*/ +#include "EfiLdr.h" +#include "Debug.h" +#include "Support.h" + +STATIC +EFI_STATUS +EfiLdrPeCoffLoadPeRelocate ( + IN EFILDR_LOADED_IMAGE *Image, + IN EFI_IMAGE_DATA_DIRECTORY *RelocDir, + IN UINTN Adjust, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor + ); + +STATIC +EFI_STATUS +EfiLdrPeCoffImageRead ( + IN VOID *FHand, + IN UINTN Offset, + IN OUT UINTN ReadSize, + OUT VOID *Buffer + ); + +STATIC +VOID * +EfiLdrPeCoffImageAddress ( + IN EFILDR_LOADED_IMAGE *Image, + IN UINTN Address + ); + + +EFI_STATUS +EfiLdrPeCoffSetImageType ( + IN OUT EFILDR_LOADED_IMAGE *Image, + IN UINTN ImageType + ); + +EFI_STATUS +EfiLdrPeCoffCheckImageMachineType ( + IN UINT16 MachineType + ); + +EFI_STATUS +EfiLdrGetPeImageInfo ( + IN VOID *FHand, + OUT UINT64 *ImageBase, + OUT UINT32 *ImageSize + ) +{ + EFI_STATUS Status; + EFI_IMAGE_DOS_HEADER DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; + + ZeroMem (&DosHdr, sizeof(DosHdr)); + ZeroMem (&PeHdr, sizeof(PeHdr)); + + // + // Read image headers + // + + EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr); + if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + return EFI_UNSUPPORTED; + } + + EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr); + + if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { + return EFI_UNSUPPORTED; + } + + // + // Verify machine type + // + + Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine); + if (EFI_ERROR(Status)) { + return Status; + } + + if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + *ImageBase = (UINT32)PeHdr.Pe32.OptionalHeader.ImageBase; + } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + *ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase; + } else { + return EFI_UNSUPPORTED; + } + + *ImageSize = PeHdr.Pe32.OptionalHeader.SizeOfImage; + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiLdrPeCoffLoadPeImage ( + IN VOID *FHand, + IN EFILDR_LOADED_IMAGE *Image, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor + ) +{ + EFI_IMAGE_DOS_HEADER DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; + EFI_IMAGE_SECTION_HEADER *FirstSection; + EFI_IMAGE_SECTION_HEADER *Section; + UINTN Index; + EFI_STATUS Status; + UINT8 *Base; + UINT8 *End; + EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; + UINTN DirCount; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY TempDebugEntry; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; + UINTN CodeViewSize; + UINTN CodeViewOffset; + UINTN CodeViewFileOffset; + UINTN OptionalHeaderSize; + UINTN PeHeaderSize; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY *DataDirectory; + UINT64 ImageBase; + + ZeroMem (&DosHdr, sizeof(DosHdr)); + ZeroMem (&PeHdr, sizeof(PeHdr)); + + // + // Read image headers + // + + EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr); + if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) { +// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Dos header signature not found\n")); +PrintHeader ('F'); + return EFI_UNSUPPORTED; + } + + EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr); + + if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { +// DEBUG ((D_LOAD, "PeCoffLoadPeImage: PE image header signature not found\n")); +PrintHeader ('G'); + return EFI_UNSUPPORTED; + } + + // + // Set the image subsystem type + // + + Status = EfiLdrPeCoffSetImageType (Image, PeHdr.Pe32.OptionalHeader.Subsystem); + if (EFI_ERROR(Status)) { +// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Subsystem type not known\n")); +PrintHeader ('H'); + return Status; + } + + // + // Verify machine type + // + + Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine); + if (EFI_ERROR(Status)) { +// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Incorrect machine type\n")); +PrintHeader ('I'); + return Status; + } + + // + // Compute the amount of memory needed to load the image and + // allocate it. This will include all sections plus the codeview debug info. + // Since the codeview info is actually outside of the image, we calculate + // its size seperately and add it to the total. + // + // Memory starts off as data + // + + CodeViewSize = 0; + CodeViewFileOffset = 0; + if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + } else { + return EFI_UNSUPPORTED; + } + for (DirCount = 0; + (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0); + DirCount++) { + Status = EfiLdrPeCoffImageRead ( + FHand, + DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), + sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), + &TempDebugEntry + ); + if (!EFI_ERROR (Status)) { + if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + CodeViewSize = TempDebugEntry.SizeOfData; + CodeViewFileOffset = TempDebugEntry.FileOffset; + } + } + } + + CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment; + Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize); + + // + // Compute the amount of memory needed to load the image and + // allocate it. Memory starts off as data + // + + Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB); + if (Image->ImageBasePage == 0) { + return EFI_OUT_OF_RESOURCES; + } + + if (EFI_ERROR(Status)) { +PrintHeader ('J'); + return Status; + } + +// DEBUG((D_LOAD, "LoadPe: new image base %lx\n", Image->ImageBasePage)); + Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage; + Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1; + Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage; + Image->ImageEof = Image->ImageBase + Image->Info.ImageSize; + Image->ImageAdjust = Image->ImageBase; + + // + // Copy the Image header to the base location + // + Status = EfiLdrPeCoffImageRead ( + FHand, + 0, + PeHdr.Pe32.OptionalHeader.SizeOfHeaders, + Image->ImageBase + ); + + if (EFI_ERROR(Status)) { +PrintHeader ('K'); + return Status; + } + + // + // Load each directory of the image into memory... + // Save the address of the Debug directory for later + // + if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes; + DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory; + } else { + NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes; + DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory; + } + DebugEntry = NULL; + for (Index = 0; Index < NumberOfRvaAndSizes; Index++) { + if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) { + Status = EfiLdrPeCoffImageRead ( + FHand, + DataDirectory[Index].VirtualAddress, + DataDirectory[Index].Size, + Image->ImageBase + DataDirectory[Index].VirtualAddress + ); + if (EFI_ERROR(Status)) { + return Status; + } + if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress); + } + } + } + + // + // Load each section of the image + // + + // BUGBUG: change this to use the in memory copy + if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32); + PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32); + } else { + OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64); + PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64); + } + FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( + Image->ImageBase + + DosHdr.e_lfanew + + PeHeaderSize + + PeHdr.Pe32.FileHeader.SizeOfOptionalHeader - + OptionalHeaderSize + ); + + Section = FirstSection; + for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) { + + // + // Compute sections address + // + + Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress); + End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize)); + + if (EFI_ERROR(Status) || !Base || !End) { +// DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index)); +PrintHeader ('L'); + return EFI_LOAD_ERROR; + } + +// DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base)); + + // + // Read the section + // + + if (Section->SizeOfRawData) { + Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base); + if (EFI_ERROR(Status)) { +PrintHeader ('M'); + return Status; + } + } + + // + // If raw size is less then virt size, zero fill the remaining + // + + if (Section->SizeOfRawData < Section->Misc.VirtualSize) { + ZeroMem ( + Base + Section->SizeOfRawData, + Section->Misc.VirtualSize - Section->SizeOfRawData + ); + } + + // + // Next Section + // + + Section += 1; + } + + // + // Copy in CodeView information if it exists + // + if (CodeViewSize != 0) { + Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset); + DebugEntry->RVA = (UINT32) (CodeViewOffset); + } + + // + // Apply relocations only if needed + // + if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase; + } else { + ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase; + } + if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) { + Status = EfiLdrPeCoffLoadPeRelocate ( + Image, + &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC], + (UINTN) Image->ImageBase - (UINTN)ImageBase, + NumberOfMemoryMapEntries, + EfiMemoryDescriptor + ); + + if (EFI_ERROR(Status)) { +PrintHeader ('N'); + return Status; + } + } + + // + // Use exported EFI specific interface if present, else use the image's entry point + // + Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN) + (EfiLdrPeCoffImageAddress( + Image, + PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint + )); + + return Status; +} + +STATIC +EFI_STATUS +EfiLdrPeCoffLoadPeRelocate ( + IN EFILDR_LOADED_IMAGE *Image, + IN EFI_IMAGE_DATA_DIRECTORY *RelocDir, + IN UINTN Adjust, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor + ) +{ + EFI_IMAGE_BASE_RELOCATION *RelocBase; + EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; + UINT16 *Reloc; + UINT16 *RelocEnd; + UINT8 *Fixup; + UINT8 *FixupBase; + UINT16 *F16; + UINT32 *F32; + UINT64 *F64; + UINT8 *FixupData; + UINTN NoFixupPages; + + // + // Find the relocation block + // + + RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress); + RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size); + if (!RelocBase || !RelocBaseEnd) { +PrintHeader ('O'); + return EFI_LOAD_ERROR; + } + + NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN)); + Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB); + if (Image->FixupData == 0) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Run the whole relocation block + // + + FixupData = Image->FixupData; + while (RelocBase < RelocBaseEnd) { + + Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION)); + RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock); + FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress); + if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) { +PrintHeader ('P'); + return EFI_LOAD_ERROR; + } + + // + // Run this relocation record + // + + while (Reloc < RelocEnd) { + + Fixup = FixupBase + (*Reloc & 0xFFF); + switch ((*Reloc) >> 12) { + + case EFI_IMAGE_REL_BASED_ABSOLUTE: + break; + + case EFI_IMAGE_REL_BASED_HIGH: + F16 = (UINT16 *) Fixup; + *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16)); + if (FixupData != NULL) { + *(UINT16 *) FixupData = *F16; + FixupData = FixupData + sizeof(UINT16); + } + break; + + case EFI_IMAGE_REL_BASED_LOW: + F16 = (UINT16 *) Fixup; + *F16 = *F16 + (UINT16) Adjust; + if (FixupData != NULL) { + *(UINT16 *) FixupData = *F16; + FixupData = FixupData + sizeof(UINT16); + } + break; + + case EFI_IMAGE_REL_BASED_HIGHLOW: + F32 = (UINT32 *) Fixup; + *F32 = *F32 + (UINT32) Adjust; + if (FixupData != NULL) { + FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32)); + *(UINT32 *) FixupData = *F32; + FixupData = FixupData + sizeof(UINT32); + } + break; + + case EFI_IMAGE_REL_BASED_DIR64: + F64 = (UINT64 *) Fixup; + *F64 = *F64 + (UINT64) Adjust; + if (FixupData != NULL) { + FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64)); + *(UINT64 *) FixupData = *F64; + FixupData = FixupData + sizeof(UINT64); + } + break; + + case EFI_IMAGE_REL_BASED_HIGHADJ: + CpuDeadLoop(); // BUGBUG: not done + break; + + default: +// DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n")); +PrintHeader ('Q'); + CpuDeadLoop(); + return EFI_LOAD_ERROR; + } + + // Next reloc record + Reloc += 1; + } + + // next reloc block + RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; + } + + // + // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor. + // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields. + // + Image->NoPages += NoFixupPages; + Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EfiLdrPeCoffImageRead ( + IN VOID *FHand, + IN UINTN Offset, + IN OUT UINTN ReadSize, + OUT VOID *Buffer + ) +{ + CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize); + + return EFI_SUCCESS; +} + +STATIC +VOID * +EfiLdrPeCoffImageAddress ( + IN EFILDR_LOADED_IMAGE *Image, + IN UINTN Address + ) +{ + UINT8 *FixedAddress; + + FixedAddress = Image->ImageAdjust + Address; + + if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) { +// DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n")); + FixedAddress = NULL; + } + +// DEBUG(( +// D_LOAD, +// "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n", +// Image->ImageBase, +// Image->ImageEof, +// Address, +// FixedAddress +// )); + return FixedAddress; +} + + +EFI_STATUS +EfiLdrPeCoffSetImageType ( + IN OUT EFILDR_LOADED_IMAGE *Image, + IN UINTN ImageType + ) +{ + EFI_MEMORY_TYPE CodeType; + EFI_MEMORY_TYPE DataType; + + switch (ImageType) { + case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: + CodeType = EfiLoaderCode; + DataType = EfiLoaderData; + break; + + case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: + CodeType = EfiBootServicesCode; + DataType = EfiBootServicesData; + break; + + case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: + CodeType = EfiRuntimeServicesCode; + DataType = EfiRuntimeServicesData; + break; + + default: + return EFI_INVALID_PARAMETER; + } + + Image->Type = ImageType; + Image->Info.ImageCodeType = CodeType; + Image->Info.ImageDataType = DataType; + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiLdrPeCoffCheckImageMachineType ( + IN UINT16 MachineType + ) +{ + EFI_STATUS Status; + + Status = EFI_UNSUPPORTED; + +#if EFI32 + if (MachineType == EFI_IMAGE_MACHINE_IA32) { + Status = EFI_SUCCESS; + } +#endif + +#if EFIX64 + if (MachineType == EFI_IMAGE_MACHINE_X64) { + Status = EFI_SUCCESS; + } +#endif + +#if EFI64 + if (MachineType == EFI_IMAGE_MACHINE_IA64) { + Status = EFI_SUCCESS; + } +#endif + + return Status; +} + diff --git a/DuetPkg/EfiLdr/PeLoader.h b/DuetPkg/EfiLdr/PeLoader.h new file mode 100644 index 0000000000..895c0b704e --- /dev/null +++ b/DuetPkg/EfiLdr/PeLoader.h @@ -0,0 +1,42 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + PeLoader.h + +Abstract: + +Revision History: + +--*/ + +#ifndef _EFILDR_PELOADER_H_ +#define _EFILDR_PELOADER_H_ + +#include "EfiLdr.h" + +EFI_STATUS +EfiLdrGetPeImageInfo ( + IN VOID *FHand, + OUT UINT64 *ImageBase, + OUT UINT32 *ImageSize + ); + +EFI_STATUS +EfiLdrPeCoffLoadPeImage ( + IN VOID *FHand, + IN EFILDR_LOADED_IMAGE *Image, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor + ); + + +#endif diff --git a/DuetPkg/EfiLdr/Support.c b/DuetPkg/EfiLdr/Support.c new file mode 100644 index 0000000000..0335d20e5a --- /dev/null +++ b/DuetPkg/EfiLdr/Support.c @@ -0,0 +1,237 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + Support.c + +Abstract: + +Revision History: + +--*/ +#include "EfiLdr.h" + +EFI_STATUS +EfiAddMemoryDescriptor( + UINTN *NoDesc, + EFI_MEMORY_DESCRIPTOR *Desc, + EFI_MEMORY_TYPE Type, + EFI_PHYSICAL_ADDRESS BaseAddress, + UINT64 NoPages, + UINT64 Attribute + ) +{ + UINTN NumberOfDesc; + UINT64 Temp; + UINTN Index; + + if (NoPages == 0) { + return EFI_SUCCESS; + } + + // + // See if the new memory descriptor needs to be carved out of an existing memory descriptor + // + + NumberOfDesc = *NoDesc; + for (Index = 0; Index < NumberOfDesc; Index++) { + + if (Desc[Index].Type == EfiConventionalMemory) { + + Temp = DivU64x32 ((BaseAddress - Desc[Index].PhysicalStart), EFI_PAGE_SIZE) + NoPages; + + if ((Desc[Index].PhysicalStart < BaseAddress) && (Desc[Index].NumberOfPages >= Temp)) { + if (Desc[Index].NumberOfPages > Temp) { + Desc[*NoDesc].Type = EfiConventionalMemory; + Desc[*NoDesc].PhysicalStart = BaseAddress + MultU64x32 (NoPages, EFI_PAGE_SIZE); + Desc[*NoDesc].NumberOfPages = Desc[Index].NumberOfPages - Temp; + Desc[*NoDesc].VirtualStart = 0; + Desc[*NoDesc].Attribute = Desc[Index].Attribute; + *NoDesc = *NoDesc + 1; + } + Desc[Index].NumberOfPages = Temp - NoPages; + } + + if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages == NoPages)) { + Desc[Index].Type = Type; + Desc[Index].Attribute = Attribute; + return EFI_SUCCESS; + } + + if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages > NoPages)) { + Desc[Index].NumberOfPages -= NoPages; + Desc[Index].PhysicalStart += MultU64x32 (NoPages, EFI_PAGE_SIZE); + } + } + } + + // + // Add the new memory descriptor + // + + Desc[*NoDesc].Type = Type; + Desc[*NoDesc].PhysicalStart = BaseAddress; + Desc[*NoDesc].NumberOfPages = NoPages; + Desc[*NoDesc].VirtualStart = 0; + Desc[*NoDesc].Attribute = Attribute; + *NoDesc = *NoDesc + 1; + + return EFI_SUCCESS; +} + +UINTN +FindSpace ( + UINTN NoPages, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor, + EFI_MEMORY_TYPE Type, + UINT64 Attribute + ) +{ + EFI_PHYSICAL_ADDRESS MaxPhysicalStart; + UINT64 MaxNoPages; + UINTN Index; + EFI_MEMORY_DESCRIPTOR *CurrentMemoryDescriptor; + + MaxPhysicalStart = 0; + MaxNoPages = 0; + CurrentMemoryDescriptor = NULL; + for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) { + if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000) { + continue; + } + if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) && + (EfiMemoryDescriptor[Index].NumberOfPages >= NoPages)) { + if (EfiMemoryDescriptor[Index].PhysicalStart > MaxPhysicalStart) { + if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000000) { + MaxPhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart; + MaxNoPages = EfiMemoryDescriptor[Index].NumberOfPages; + CurrentMemoryDescriptor = &EfiMemoryDescriptor[Index]; + } + } + } + if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) || + (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) { + continue; + } + if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) || + (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) { + break; + } + } + + if (MaxPhysicalStart == 0) { + return 0; + } + + if (MaxNoPages != NoPages) { + CurrentMemoryDescriptor->NumberOfPages = MaxNoPages - NoPages; + EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Type = Type; + EfiMemoryDescriptor[*NumberOfMemoryMapEntries].PhysicalStart = MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT); + EfiMemoryDescriptor[*NumberOfMemoryMapEntries].NumberOfPages = NoPages; + EfiMemoryDescriptor[*NumberOfMemoryMapEntries].VirtualStart = 0; + EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Attribute = Attribute; + *NumberOfMemoryMapEntries = *NumberOfMemoryMapEntries + 1; + } else { + CurrentMemoryDescriptor->Type = Type; + CurrentMemoryDescriptor->Attribute = Attribute; + } + + return (UINTN)(MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT)); +} + +VOID +GenMemoryMap ( + UINTN *NumberOfMemoryMapEntries, + EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor, + BIOS_MEMORY_MAP *BiosMemoryMap + ) +{ + UINT64 BaseAddress; + UINT64 Length; + EFI_MEMORY_TYPE Type; + UINTN Index; + UINTN Attr; + UINT64 Ceiling; + + Ceiling = 0xFFFFFFFF; + for (Index = 0; Index < BiosMemoryMap->MemoryMapSize / sizeof(BIOS_MEMORY_MAP_ENTRY); Index++) { + + switch (BiosMemoryMap->MemoryMapEntry[Index].Type) { + case (INT15_E820_AddressRangeMemory): + Type = EfiConventionalMemory; + Attr = EFI_MEMORY_WB; + break; + case (INT15_E820_AddressRangeReserved): + Type = EfiReservedMemoryType; + Attr = EFI_MEMORY_UC; + break; + case (INT15_E820_AddressRangeACPI): + Type = EfiACPIReclaimMemory; + Attr = EFI_MEMORY_WB; + break; + case (INT15_E820_AddressRangeNVS): + Type = EfiACPIMemoryNVS; + Attr = EFI_MEMORY_UC; + break; + default: + // We should not get here, according to ACPI 2.0 Spec. + // BIOS behaviour of the Int15h, E820h + Type = EfiReservedMemoryType; + Attr = EFI_MEMORY_UC; + break; + } + if (Type == EfiConventionalMemory) { + BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress; + Length = BiosMemoryMap->MemoryMapEntry[Index].Length; + if (BaseAddress & EFI_PAGE_MASK) { + Length = Length + (BaseAddress & EFI_PAGE_MASK) - EFI_PAGE_SIZE; + BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT); + } + } else { + BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress; + Length = BiosMemoryMap->MemoryMapEntry[Index].Length + (BaseAddress & EFI_PAGE_MASK); + BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT), EFI_PAGE_SHIFT); + if (Length & EFI_PAGE_MASK) { + Length = LShiftU64 (RShiftU64 (Length, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT); + } + // + // Update Memory Ceiling + // + if ((BaseAddress >= 0x100000) && (BaseAddress < 0x100000000)) { + if (Ceiling > BaseAddress) { + Ceiling = BaseAddress; + } + } + } + EfiAddMemoryDescriptor ( + NumberOfMemoryMapEntries, + EfiMemoryDescriptor, + Type, + (EFI_PHYSICAL_ADDRESS)BaseAddress, + RShiftU64 (Length, EFI_PAGE_SHIFT), + Attr + ); + } + + // + // Update MemoryMap according to Ceiling + // + for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) { + if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) && + (EfiMemoryDescriptor[Index].PhysicalStart > 0x100000) && + (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000000)) { + if (EfiMemoryDescriptor[Index].PhysicalStart >= Ceiling) { + EfiMemoryDescriptor[Index].Type = EfiReservedMemoryType; + } + } + } +} diff --git a/DuetPkg/EfiLdr/Support.h b/DuetPkg/EfiLdr/Support.h new file mode 100644 index 0000000000..360f4250d0 --- /dev/null +++ b/DuetPkg/EfiLdr/Support.h @@ -0,0 +1,50 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + Support.h + +Abstract: + +Revision History: + +--*/ + +#ifndef _EFILDR_SUPPORT_H_ +#define _EFILDR_SUPPORT_H_ + +EFI_STATUS +EfiAddMemoryDescriptor( + UINTN *NoDesc, + EFI_MEMORY_DESCRIPTOR *Desc, + EFI_MEMORY_TYPE Type, + EFI_PHYSICAL_ADDRESS BaseAddress, + UINT64 NoPages, + UINT64 Attribute + ); + +UINTN +FindSpace( + UINTN NoPages, + IN UINTN *NumberOfMemoryMapEntries, + IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor, + EFI_MEMORY_TYPE Type, + UINT64 Attribute + ); + +VOID +GenMemoryMap ( + UINTN *NumberOfMemoryMapEntries, + EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor, + BIOS_MEMORY_MAP *BiosMemoryMap + ); + +#endif diff --git a/DuetPkg/EfiLdr/X64/EfiLdr.inf b/DuetPkg/EfiLdr/X64/EfiLdr.inf new file mode 100644 index 0000000000..ba87791958 --- /dev/null +++ b/DuetPkg/EfiLdr/X64/EfiLdr.inf @@ -0,0 +1,27 @@ +#/*++ +# +# Copyright (c) 2006, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# EfiLdr.inf +# +# Abstract: +# +#--*/ + +[defines] +BASE_NAME = EfiLoader +COMPONENT_TYPE = FILE +BUILD_TYPE = CUSTOM_MAKEFILE +FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD + +[sources.common] + +[nmake.common] diff --git a/DuetPkg/EfiLdr/X64/Makefile b/DuetPkg/EfiLdr/X64/Makefile new file mode 100644 index 0000000000..dc31b137d7 --- /dev/null +++ b/DuetPkg/EfiLdr/X64/Makefile @@ -0,0 +1,186 @@ +#/*++ +# +# Copyright (c) 2006 - 2007, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# Makefile +# +# Abstract: +# +#--*/ + +# +# Globals +# +BIN_DIR = $(BUILD_DIR)\$(PROCESSOR) +TOOLCHAIN = TOOLCHAIN_$(PROCESSOR) + +TOOLBIN_DIR = $(BUILD_DIR)\Tools + +# +# Include CommonTools.env enviroment +# + +!INCLUDE $(BUILD_DIR)\PlatformTools.env + +# +# Include paths +# +INC = -I $(SOURCE_DIR)\. -I $(SOURCE_DIR)\.\$(PROCESSOR) $(INC) +INC = -I $(EDK_SOURCE)\Foundation\ \ + -I $(EDK_SOURCE)\Foundation\Include \ + -I $(EDK_SOURCE)\Foundation\Include\$(PROCESSOR) \ + -I $(EDK_SOURCE)\Foundation\Efi \ + -I $(EDK_SOURCE)\Foundation\Efi\Include \ + -I $(EDK_SOURCE)\Foundation\Framework \ + -I $(EDK_SOURCE)\Foundation\Framework\Include \ + -I $(EDK_SOURCE)\Foundation\Library\Dxe\Include \ + -I $(EDK_SOURCE)\Foundation\Library\Pei\Include \ + -I $(EDK_SOURCE)\Foundation\Include\Pei \ + $(INC) + +LDRDEP = $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\EfiLdrHandoff.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\EfiLoader.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Debug.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Debug.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.h \ + $(BUILD_DIR)\..\Loader\EfiLdr\Support.c \ + $(BUILD_DIR)\..\Loader\EfiLdr\Support.h + +all : \ + $(BIN_DIR)\BootSect.com \ + $(BIN_DIR)\Bs16.com \ + $(BIN_DIR)\Bs32.com \ + $(BIN_DIR)\Gpt.com \ + $(BIN_DIR)\Mbr.com \ + $(BIN_DIR)\Start64.com \ + $(BIN_DIR)\St16_64.com \ + $(BIN_DIR)\St32_64.com \ + $(BIN_DIR)\Efi64.com2 \ + $(BIN_DIR)\Efildr.efi \ + + +loader : \ + Fv\Efildr \ + Fv\Efildr16 \ + Fv\Efildr20 \ + + +# +# Generate loader object +# +$(BIN_DIR)\BootSect.obj: $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\BootSect.obj $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm + +$(BIN_DIR)\BootSect.com: $(BIN_DIR)\BootSect.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny BootSect.obj,BootSect.com,BootSect.map,,, + +$(BIN_DIR)\Bs16.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs16.obj $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm + +$(BIN_DIR)\Bs16.com: $(BIN_DIR)\Bs16.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Bs16.obj,Bs16.com,Bs16.map,,, + +$(BIN_DIR)\Bs32.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs32.obj $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm + +$(BIN_DIR)\Bs32.com: $(BIN_DIR)\Bs32.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Bs32.obj,Bs32.com,Bs32.map,,, + +$(BIN_DIR)\Gpt.obj: $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Gpt.obj $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm + +$(BIN_DIR)\Gpt.com: $(BIN_DIR)\Gpt.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Gpt.obj,Gpt.com,Gpt.map,,, + +$(BIN_DIR)\Mbr.obj: $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Mbr.obj $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm + +$(BIN_DIR)\Mbr.com: $(BIN_DIR)\Mbr.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Mbr.obj,Mbr.com,Mbr.map,,, + +$(BIN_DIR)\Start64.obj: $(BUILD_DIR)\..\Loader\BootSector\Start64.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Start64.obj $(BUILD_DIR)\..\Loader\BootSector\Start64.asm + +$(BIN_DIR)\Start64.com: $(BIN_DIR)\Start64.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Start64.obj,Start64.com,Start64.map,,, + +$(BIN_DIR)\St16_64.obj: $(BUILD_DIR)\..\Loader\BootSector\St16_64.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\St16_64.obj $(BUILD_DIR)\..\Loader\BootSector\St16_64.asm + +$(BIN_DIR)\St16_64.com: $(BIN_DIR)\St16_64.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny St16_64.obj,St16_64.com,St16_64.map,,, + +$(BIN_DIR)\St32_64.obj: $(BUILD_DIR)\..\Loader\BootSector\St32_64.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\St32_64.obj $(BUILD_DIR)\..\Loader\BootSector\St32_64.asm + +$(BIN_DIR)\St32_64.com: $(BIN_DIR)\St32_64.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny St32_64.obj,St32_64.com,St32_64.map,,, + +$(BIN_DIR)\Efi64.obj: $(BUILD_DIR)\..\Loader\BootSector\Efi64.asm + $(ASM16) /c /omf /Fo$(BIN_DIR)\Efi64.obj $(BUILD_DIR)\..\Loader\BootSector\Efi64.asm + +$(BIN_DIR)\Efi64.com: $(BIN_DIR)\Efi64.obj + cd $(BIN_DIR) + $(ASMLINK16) /tiny Efi64.obj,Efi64.com,Efi64.map,,, + +$(BIN_DIR)\Efi64.com2: $(BIN_DIR)\Efi64.com + $(TOOLBIN_DIR)\Splitfile $(BIN_DIR)\Efi64.com 135168 + +$(BIN_DIR)\Efildr.obj: $(LDRDEP) + $(CC) $(C_FLAGS) $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c + +$(BIN_DIR)\Efildr.dll: $(BIN_DIR)\Efildr.obj + $(LINK) /nologo /MACHINE:AMD64 /SUBSYSTEM:CONSOLE /NODEFAULTLIB /INCREMENTAL:NO \ + /MAP /FIXED /BASE:0x00010000 /OPT:REF /ALIGN:32 /MERGE:.data=.text \ + /MERGE:.rdata=.text /DRIVER /ENTRY:EfiLoader $(BIN_DIR)\Efildr.obj \ + $(BIN_DIR)\CompilerStub.lib $(BIN_DIR)\EfiCommonLib.lib $(BIN_DIR)\PeiLib.lib \ + /OUT:$(BIN_DIR)\Efildr.dll /IGNORE:4078,4096 + +$(BIN_DIR)\Efildr.efi: $(BIN_DIR)\Efildr.dll + $(TOOLBIN_DIR)\FwImage app $(BIN_DIR)\Efildr.dll $(BIN_DIR)\Efildr.efi + +# +# Generate loader binary +# +Fv\EfiMain.z : Fv\EfiMain.fv + $(TOOLBIN_DIR)\Eficompress -tTiano Fv\EfiMain.fv Fv\EfiMain.z + +Fv\DxeMain.z : $(BIN_DIR)\DxeMain.efi + $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeMain.efi Fv\DxeMain.z + +Fv\DxeIpl.z : $(BIN_DIR)\DxeIpl.efi + $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeIpl.efi Fv\DxeIpl.z + +Fv\Efildr64: $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z + $(TOOLBIN_DIR)\Efildrimage Fv\Efildr64 $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z + +Fv\Efildr: $(BIN_DIR)\Start64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64 + copy /b $(BIN_DIR)\Start64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\EfildrPure + $(TOOLBIN_DIR)\GenPage Fv\EfildrPure Fv\Efildr + +Fv\Efildr16: $(BIN_DIR)\St16_64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64 + copy /b $(BIN_DIR)\St16_64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\Efildr16Pure + $(TOOLBIN_DIR)\GenPage Fv\Efildr16Pure Fv\Efildr16 + +Fv\Efildr20: $(BIN_DIR)\St32_64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64 + copy /b $(BIN_DIR)\St32_64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\Efildr20Pure + $(TOOLBIN_DIR)\GenPage Fv\Efildr20Pure Fv\Efildr20 + diff --git a/DuetPkg/EfiLdr/efildr.c b/DuetPkg/EfiLdr/efildr.c new file mode 100644 index 0000000000..5cf7db6eb6 --- /dev/null +++ b/DuetPkg/EfiLdr/efildr.c @@ -0,0 +1,28 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + EfiLdr.c + +Abstract: + +Revision History: + +--*/ + +// +// BUGBUG, include all C files +// +#include "EfiLoader.c" +#include "PeLoader.c" +#include "Support.c" +#include "Debug.c" + -- cgit v1.2.3