secmain.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,174 行 · 第 1/3 页
C
1,174 行
PAGE_READWRITE,
0,
MapSize,
NULL
);
if (NtMapHandle == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Get the virtual address (address in the emulator) of the mapped file
//
VirtualAddress = MapViewOfFileEx (
NtMapHandle,
FILE_MAP_ALL_ACCESS,
0,
0,
MapSize,
(LPVOID) (UINTN) *BaseAddress
);
if (VirtualAddress == NULL) {
return EFI_DEVICE_ERROR;
}
if (MapSize == 0) {
//
// Seek to the end of the file to figure out the true file size.
//
FileSize = SetFilePointer (
NtFileHandle,
0,
NULL,
FILE_END
);
if (FileSize == -1) {
return EFI_DEVICE_ERROR;
}
*Length = (UINT64) FileSize;
} else {
*Length = (UINT64) MapSize;
}
*BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAddress;
return EFI_SUCCESS;
}
#define BYTES_PER_RECORD 512
EFI_STATUS
EFIAPI
SecPeiReportStatusCode (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN EFI_GUID * CallerId,
IN EFI_STATUS_CODE_DATA * Data OPTIONAL
)
/*++
Routine Description:
This routine produces the ReportStatusCode PEI service. It's passed
up to the PEI Core via a PPI. T
This code currently uses the NT clib printf. This does not work the same way
as the EFI Print (), as %t, %g, %s as Unicode are not supported.
Arguments:
(see EFI_PEI_REPORT_STATUS_CODE)
Returns:
EFI_SUCCESS - Always return success
--*/
// TODO: PeiServices - add argument and description to function comment
// TODO: CodeType - add argument and description to function comment
// TODO: Value - add argument and description to function comment
// TODO: Instance - add argument and description to function comment
// TODO: CallerId - add argument and description to function comment
// TODO: Data - add argument and description to function comment
{
CHAR8 *Format;
EFI_DEBUG_INFO *DebugInfo;
VA_LIST Marker;
CHAR8 PrintBuffer[BYTES_PER_RECORD * 2];
CHAR8 *Filename;
CHAR8 *Description;
UINT32 LineNumber;
if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
//
// This supports DEBUG () marcos
// Data format
// EFI_STATUS_CODE_DATA
// EFI_DEBUG_INFO
//
// The first 12 * UINT64 bytes of the string are really an
// arguement stack to support varargs on the Format string.
//
DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
Marker = (VA_LIST) (DebugInfo + 1);
Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
AvSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);
printf (PrintBuffer);
}
if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)
) {
if (ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
//
// Support ASSERT () macro
//
printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);
EFI_BREAKPOINT ();
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
SecWinNtPeCoffLoaderLoadAsDll (
IN CHAR8 *PdbFileName,
IN VOID **ImageEntryPoint,
OUT VOID **ModHandle
)
/*++
Routine Description:
Loads the .DLL file is present when a PE/COFF file is loaded. This provides source level
debugging for drivers that have cooresponding .DLL files on the local system.
Arguments:
PdbFileName - The name of the .PDB file. This was found from the PE/COFF
file's debug directory entry.
ImageEntryPoint - A pointer to the DLL entry point of the .DLL file was loaded.
ModHandle - A pointer to the DLL Module of the .DLL file was loaded.
Returns:
EFI_SUCCESS - The .DLL file was loaded, and the DLL entry point is returned in
ImageEntryPoint
EFI_NOT_FOUND - The .DLL file could not be found
EFI_UNSUPPORTED - The .DLL file was loaded, but the entry point to the .DLL file
could not determined.
EFI_ALREADY_STARTED - The .DLL file was already loaded
--*/
{
CHAR16 *DllFileName;
HMODULE Library;
UINTN Index;
*ImageEntryPoint = NULL;
*ModHandle = NULL;
//
// Check whether the ModHandle is already registered. If it does, that means
// the DLL file is already loaded. To load it second times will cause the
// first time load information crash.
//
Library = GetModHandle (PdbFileName);
if (Library != NULL) {
return EFI_ALREADY_STARTED;
}
//
// Convert filename from ASCII to Unicode
//
DllFileName = AsciiToUnicode (PdbFileName, &Index);
//
// Check that we have a valid filename
//
if (Index < 5 || DllFileName[Index - 4] != '.') {
free (DllFileName);
return EFI_NOT_FOUND;
}
//
// Replace .PDB with .DLL on the filename
//
DllFileName[Index - 3] = 'D';
DllFileName[Index - 2] = 'L';
DllFileName[Index - 1] = 'L';
//
// Load the .DLL file into the user process's address space
//
Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (Library == NULL) {
free (DllFileName);
return EFI_NOT_FOUND;
}
//
// InitializeDriver is the entry point we put in all our EFI DLL's. The
// DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the normal
// DLL entry point of DllMain, and prevents other modules that are referenced
// in side the DllFileName from being loaded.
//
*ImageEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver");
if (*ImageEntryPoint == NULL) {
free (DllFileName);
return EFI_UNSUPPORTED;
}
*ModHandle = Library;
//
// Register this module handle, this is used to check second times load.
//
AddModHandle (PdbFileName, Library);
free (DllFileName);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
SecWinNtPeCoffLoaderFreeLibrary (
IN VOID *ModHandle
)
/*++
Routine Description:
Free resources allocated by SecWinNtPeCoffLoaderLoadAsDll
Arguments:
MohHandle - Handle of the resources to free to undo the work.
Returns:
EFI_SUCCESS - This resource is freed successfully.
--*/
{
if (ModHandle != NULL) {
RemoveModeHandle (ModHandle);
FreeLibrary (ModHandle);
}
return EFI_SUCCESS;
}
VOID
SecLoadFromCore (
IN UINTN LargestRegion,
IN UINTN LargestRegionSize,
IN UINTN BootFirmwareVolumeBase,
IN VOID *PeiCorePe32File
)
/*++
Routine Description:
This is the service to load the PEI Core from the Firmware Volume
Arguments:
LargestRegion - Memory to use for PEI.
LargestRegionSize - Size of Memory to use for PEI
BootFirmwareVolumeBase - Start of the Boot FV
PeiCorePe32File - PEI Core PE32
Returns:
Success means control is transfered and thus we should never return
--*/
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TopOfMemory;
VOID *TopOfStack;
UINT64 PeiCoreSize;
EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint;
EFI_PHYSICAL_ADDRESS PeiImageAddress;
EFI_PEI_STARTUP_DESCRIPTOR PeiStartup;
//
// Install the PEI Protocols that are shared between PEI and DXE
//
InstallEfiPeiFlushInstructionCache (&gPeiEfiPeiFlushInstructionCache);
InstallEfiPeiTransferControl (&gPeiEfiPeiTransferControl);
gPeiEfiPeiPeCoffLoader = NULL;
InstallEfiPeiPeCoffLoader (NULL, &gPeiEfiPeiPeCoffLoader, (EFI_PEI_PPI_DESCRIPTOR *) &mSecNtLoadAsDllPpi);
//
// Compute Top Of Memory for Stack and PEI Core Allocations
//
TopOfMemory = LargestRegion + ((LargestRegionSize) & (~15));
//
// Allocate 128KB for the Stack
//
TopOfStack = (VOID *) (UINTN) (TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR));
TopOfMemory = TopOfMemory - EFI_STACK_SIZE;
//
// Bind this information into the SEC hand-off state
//
PeiStartup.DispatchTable = (EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable;
PeiStartup.SizeOfCacheAsRam = EFI_STACK_SIZE;
PeiStartup.BootFirmwareVolume = BootFirmwareVolumeBase;
CopyMem (TopOfStack, &PeiStartup, sizeof (EFI_PEI_STARTUP_DESCRIPTOR));
//
// Load the PEI Core from a Firmware Volume
//
Status = SecWinNtPeiLoadFile (
PeiCorePe32File,
&PeiImageAddress,
&PeiCoreSize,
&PeiCoreEntryPoint
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Transfer control to the PEI Core
//
SecSwitchStacks (
(VOID *) (UINTN) PeiCoreEntryPoint,
(VOID *) (UINTN) TopOfStack,
(VOID *) (UINTN) TopOfStack,
(VOID *) (UINTN) NULL
);
//
// If we get here, then the PEI Core returned. This is an error
//
return ;
}
EFI_STATUS
EFIAPI
SecWinNtPeiAutoScan (
IN UINTN Index,
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
OUT UINT64 *MemorySize
)
/*++
Routine Description:
This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
It allows discontiguous memory regions to be supported by the emulator.
It uses gSystemMemory[] and gSystemMemoryCount that were created by
parsing the Windows environment variable EFI_MEMORY_SIZE.
The size comes from the varaible and the address comes from the call to
WinNtOpenFile.
Arguments:
Index - Which memory region to use
MemoryBase - Return Base address of memory region
MemorySize - Return size in bytes of the memory region
Returns:
EFI_SUCCESS - If memory region was mapped
EFI_UNSUPPORTED - If Index is not supported
--*/
{
EFI_STATUS Status;
if (Index >= gSystemMemoryCount) {
return EFI_UNSUPPORTED;
}
*MemoryBase = 0;
Status = WinNtOpenFile (
gSystemMemory[Index].FileName,
(UINT32) gSystemMemory[Index].Size,
OPEN_ALWAYS,
MemoryBase,
MemorySize
);
gSystemMemory[Index].Memory = *MemoryBase;
return Status;
}
EFI_STATUS
EFIAPI
SecWinNtWinNtThunkAddress (
IN OUT UINT64 *InterfaceSize,
IN OUT EFI_PHYSICAL_ADDRESS *InterfaceBase
)
/*++
Routine Description:
Since the SEC is the only Windows program in stack it must export
an interface to do Win API calls. That's what the WinNtThunk address
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?