secmain.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,174 行 · 第 1/3 页
C
1,174 行
/*++
Copyright (c) 2004 - 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:
SecMain.c
Abstract:
WinNt emulator of SEC phase. It's really a Win32 application, but this is
Ok since all the other modules for NT32 are NOT Win32 applications.
This program processes Windows environment variables and figures out
what the memory layout will be, how may FD's will be loaded and also
what the boot mode is.
The SEC registers a set of services with the SEC core. gPrivateDispatchTable
is a list of PPI's produced by the SEC that are availble for usage in PEI.
This code produces 128 K of temporary memory for the PEI stack by opening a
Windows file and mapping it directly to memory addresses.
The system.cmd script is used to set windows environment variables that drive
the configuration opitons of the SEC.
--*/
#include "SecMain.h"
//
// Globals
//
EFI_PEI_PE_COFF_LOADER_PROTOCOL *gPeiEfiPeiPeCoffLoader;
EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *gPeiEfiPeiFlushInstructionCache;
EFI_PEI_TRANSFER_CONTROL_PROTOCOL *gPeiEfiPeiTransferControl;
//
// The SEC constructs a table of PPI's to pass up to subsequent phases.
// This is done via the gPrivateDispatchTable.
//
EFI_NT_LOAD_AS_DLL_PPI mSecNtLoadAsDllPpi = {
SecWinNtPeCoffLoaderLoadAsDll,
SecWinNtPeCoffLoaderFreeLibrary
};
NT_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi = { SecWinNtPeiLoadFile };
PEI_NT_AUTOSCAN_PPI mSecNtAutoScanPpi = { SecWinNtPeiAutoScan };
PEI_NT_THUNK_PPI mSecWinNtThunkPpi = { SecWinNtWinNtThunkAddress };
PEI_STATUS_CODE_PPI mSecStatusCodePpi = { SecPeiReportStatusCode };
NT_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };
EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gEfiNtLoadAsDllPpiGuid,
&mSecNtLoadAsDllPpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gNtPeiLoadFileGuid,
&mSecNtLoadFilePpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gPeiNtAutoScanPpiGuid,
&mSecNtAutoScanPpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gPeiNtThunkPpiGuid,
&mSecWinNtThunkPpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gPeiStatusCodePpiGuid,
&mSecStatusCodePpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gNtFwhPpiGuid,
&mSecFwhInformationPpi
}
};
//
// Default information about where the FD is located.
// This array gets filled in with information from EFI_FIRMWARE_VOLUMES
// EFI_FIRMWARE_VOLUMES is a Windows environment variable set by system.cmd.
// The number of array elements is allocated base on parsing
// EFI_FIRMWARE_VOLUMES and the memory is never freed.
//
UINTN gFdInfoCount = 0;
NT_FD_INFO *gFdInfo;
//
// Array that supports seperate memory rantes.
// The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.
// The number of array elements is allocated base on parsing
// EFI_MEMORY_SIZE and the memory is never freed.
//
UINTN gSystemMemoryCount = 0;
NT_SYSTEM_MEMORY *gSystemMemory;
UINTN mPdbNameModHandleArraySize = 0;
PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL;
INTN
EFIAPI
main (
IN INTN Argc,
IN CHAR8 **Argv,
IN CHAR8 **Envp
)
/*++
Routine Description:
Main entry point to SEC for WinNt. This is a Windows program
Arguments:
Argc - Number of command line arguments
Argv - Array of command line argument strings
Envp - Array of environmemt variable strings
Returns:
0 - Normal exit
1 - Abnormal exit
--*/
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS InitialStackMemory;
UINT64 InitialStackMemorySize;
EFI_BOOT_MODE BootMode;
UINTN Index;
UINTN Index1;
UINTN Index2;
UINTN PeiIndex;
CHAR8 *MemorySizeStr;
CHAR8 *FirmwareVolumesStr;
CHAR8 *BootModeStr;
CHAR16 *FileName;
CHAR8 *FileNameAscii;
BOOLEAN Done;
VOID *PeiCoreFile;
printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n");
//
// Make some Windows calls to Set the process to the highest priority in the
// idle class. We need this to have good performance.
//
SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
//
// Set defaults in case we can not find an environment variable
//
MemorySizeStr = "64";
FirmwareVolumesStr = "..\\Fv\\FvRecovery.fd";
BootModeStr = "0";
//
// Parse the environment varialbes for the ones we care about.
//
for (Index = 0; Envp[Index] != NULL; Index++) {
if (strncmp (Envp[Index], EFI_MEMORY_SIZE_STR, sizeof (EFI_MEMORY_SIZE_STR) - 1) == 0) {
MemorySizeStr = &Envp[Index][sizeof (EFI_MEMORY_SIZE_STR)];
}
if (strncmp (Envp[Index], EFI_FIRMWARE_VOLUMES_STR, sizeof (EFI_FIRMWARE_VOLUMES_STR) - 1) == 0) {
FirmwareVolumesStr = &Envp[Index][sizeof (EFI_FIRMWARE_VOLUMES_STR)];
}
if (strncmp (Envp[Index], EFI_BOOT_MODE_STR, sizeof (EFI_BOOT_MODE_STR) - 1) == 0) {
BootModeStr = &Envp[Index][sizeof (EFI_BOOT_MODE_STR)];
}
}
//
// Allocate space for gSystemMemory Array
//
gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1;
gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
if (gSystemMemory == NULL) {
printf ("ERROR : Can not allocate memory for %s. Exiting.\n", MemorySizeStr);
exit (1);
}
//
// Allocate space for gSystemMemory Array
//
gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;
gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
if (gFdInfo == NULL) {
printf ("ERROR : Can not allocate memory for %s. Exiting.\n", FirmwareVolumesStr);
exit (1);
}
//
// Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
//
BootMode = atoi (BootModeStr);
printf (" BootMode 0x%02x\n", BootMode);
//
// Open up a 128K file to emulate temp memory for PEI.
// on a real platform this would be SRAM, or using the cache as RAM.
// Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping
//
InitialStackMemory = 0;
InitialStackMemorySize = 0x20000;
Status = WinNtOpenFile (
L"SecStack",
(UINT32) InitialStackMemorySize,
OPEN_ALWAYS,
&InitialStackMemory,
&InitialStackMemorySize
);
if (EFI_ERROR (Status)) {
printf ("ERROR : Can not open SecStack Exiting\n");
exit (1);
}
printf (" SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);
//
// Open All the firmware volumes and remember the info in the gFdInfo global
//
for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL; !Done; Index++) {
FileNameAscii = FirmwareVolumesStr;
for (Index1 = 0; (FirmwareVolumesStr[Index1] != '!') && (FirmwareVolumesStr[Index1] != 0); Index1++)
;
if (FirmwareVolumesStr[Index1] == 0) {
Done = TRUE;
} else {
FirmwareVolumesStr[Index1] = '\0';
FirmwareVolumesStr = FirmwareVolumesStr + Index1 + 1;
}
//
// Convert Ascii string to Unicode string
//
FileName = AsciiToUnicode (FileNameAscii, NULL);
//
// Open the FD and remmeber where it got mapped into our processes address space
//
Status = WinNtOpenFile (
FileName,
0,
OPEN_EXISTING,
&gFdInfo[Index].Address,
&gFdInfo[Index].Size
);
if (EFI_ERROR (Status)) {
printf ("ERROR : Can not open Firmware Device File %S (%r). Exiting.\n", FileName, Status);
exit (1);
}
printf (" FD loaded from");
//
// printf can't print filenames directly as the \ gets interperted as an
// escape character.
//
for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {
printf ("%c", FileName[Index2]);
}
free (FileName);
if (PeiCoreFile == NULL) {
//
// Assume the beginning of the FD is an FV and look for the PEI Core.
// Load the first one we find.
//
Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
if (!EFI_ERROR (Status)) {
PeiIndex = Index;
printf (" contains SEC Core");
}
}
printf ("\n");
}
//
// Calculate memory regions and store the information in the gSystemMemory
// global for later use. The autosizing code will use this data to
// map this memory into the SEC process memory space.
//
for (Index = 0, Done = FALSE; !Done; Index++) {
//
// Save the size of the memory and make a Unicode filename SystemMemory00, ...
//
gSystemMemory[Index].Size = atoi (MemorySizeStr) * 0x100000;
#ifdef USE_VC8
_snwprintf_s (gSystemMemory[Index].FileName, NT_SYSTEM_MEMORY_FILENAME_SIZE, NT_SYSTEM_MEMORY_FILENAME_SIZE, L"SystemMemory%02d", Index);
#else
_snwprintf (gSystemMemory[Index].FileName, NT_SYSTEM_MEMORY_FILENAME_SIZE, L"SystemMemory%02d", Index);
#endif
//
// Find the next region
//
for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
;
if (MemorySizeStr[Index1] == 0) {
Done = TRUE;
}
MemorySizeStr = MemorySizeStr + Index1 + 1;
}
printf ("\n");
//
// Hand off to PEI Core
//
SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);
//
// If we get here, then the PEI Core returned. This is an error as PEI should
// always hand off to DXE.
//
printf ("ERROR : PEI Core returned\n");
exit (1);
}
EFI_STATUS
WinNtOpenFile (
IN CHAR16 *FileName,
IN UINT32 MapSize,
IN DWORD CreationDisposition,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINT64 *Length
)
/*++
Routine Description:
Opens and memory maps a file using WinNt services. If BaseAddress is non zero
the process will try and allocate the memory starting at BaseAddress.
Arguments:
FileName - The name of the file to open and map
MapSize - The amount of the file to map in bytes
CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
memory emulation, and exiting files for firmware volume emulation
BaseAddress - The base address of the mapped file in the user address space.
If passed in as NULL the a new memory region is used.
If passed in as non NULL the request memory region is used for
the mapping of the file into the process space.
Length - The size of the mapped region in bytes
Returns:
EFI_SUCCESS - The file was opened and mapped.
EFI_NOT_FOUND - FileName was not found in the current directory
EFI_DEVICE_ERROR - An error occured attempting to map the opened file
--*/
{
HANDLE NtFileHandle;
HANDLE NtMapHandle;
VOID *VirtualAddress;
UINTN FileSize;
//
// Use Win API to open/create a file
//
NtFileHandle = CreateFile (
FileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (NtFileHandle == INVALID_HANDLE_VALUE) {
return EFI_NOT_FOUND;
}
//
// Map the open file into a memory range
//
NtMapHandle = CreateFileMapping (
NtFileHandle,
NULL,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?