📄 image.c
字号:
//
if (DstBufAlocated) {
CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages);
}
if (Image->ImageContext.FixupData != NULL) {
CoreFreePool (Image->ImageContext.FixupData);
}
return Status;
}
LOADED_IMAGE_PRIVATE_DATA *
CoreLoadedImageInfo (
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
Get the image's private data from its handle.
Arguments:
ImageHandle - The image handle
Returns:
Return the image private data associated with ImageHandle.
--*/
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
LOADED_IMAGE_PRIVATE_DATA *Image;
Status = CoreHandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
&LoadedImage
);
if (!EFI_ERROR (Status)) {
Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);
} else {
DEBUG ((EFI_D_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %x\n", ImageHandle));
Image = NULL;
}
return Image;
}
EFI_STATUS
CoreLoadImageCommon (
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
IN OUT UINTN *NumberOfPages OPTIONAL,
OUT EFI_HANDLE *ImageHandle,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
IN UINT32 Attribute,
IN BOOLEAN CrossLoad
)
/*++
Routine Description:
Loads an EFI image into memory and returns a handle to the image.
Arguments:
BootPolicy - If TRUE, indicates that the request originates from the boot manager,
and that the boot manager is attempting to load FilePath as a boot selection.
ParentImageHandle - The caller's image handle.
FilePath - The specific file path from which the image is loaded.
SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
the image to be loaded.
SourceSize - The size in bytes of SourceBuffer.
DstBuffer - The buffer to store the image
NumberOfPages - If not NULL, a pointer to the image's page number, if this number
is not enough, return EFI_BUFFER_TOO_SMALL and this parameter contain
the required number.
ImageHandle - Pointer to the returned image handle that is created when the image
is successfully loaded.
EntryPoint - A pointer to the entry point
Attribute - The bit mask of attributes to set for the load PE image
CrossLoad - Whether expect to support cross architecture loading
Returns:
EFI_SUCCESS - The image was loaded into memory.
EFI_NOT_FOUND - The FilePath was not found.
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
EFI_BUFFER_TOO_SMALL - The buffer is too small
EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
parsed to locate the proper protocol for loading the file.
EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
--*/
{
LOADED_IMAGE_PRIVATE_DATA *Image;
LOADED_IMAGE_PRIVATE_DATA *ParentImage;
IMAGE_FILE_HANDLE FHand;
EFI_STATUS Status;
EFI_STATUS SecurityStatus;
EFI_HANDLE DeviceHandle;
UINT32 AuthenticationStatus;
EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
UINTN FilePathSize;
SecurityStatus = EFI_SUCCESS;
ASSERT (gEfiCurrentTpl < EFI_TPL_NOTIFY);
ParentImage = NULL;
//
// The caller must pass in a valid ParentImageHandle
//
if (ImageHandle == NULL || ParentImageHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
ParentImage = CoreLoadedImageInfo (ParentImageHandle);
if (ParentImage == NULL) {
DEBUG((EFI_D_LOAD|EFI_D_ERROR, "LoadImageEx: Parent handle not an image handle\n"));
return EFI_INVALID_PARAMETER;
}
//
// Get simple read access to the source file
//
OriginalFilePath = FilePath;
Status = CoreOpenImageFile (
BootPolicy,
SourceBuffer,
SourceSize,
FilePath,
&DeviceHandle,
&FHand,
&AuthenticationStatus
);
if (Status == EFI_ALREADY_STARTED) {
Image = NULL;
goto Done;
} else if (EFI_ERROR (Status)) {
return Status;
}
//
// Verify the Authentication Status through the Security Architectural Protocol
//
if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {
SecurityStatus = gSecurity->FileAuthenticationState (
gSecurity,
AuthenticationStatus,
OriginalFilePath
);
if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {
Status = SecurityStatus;
Image = NULL;
goto Done;
}
}
//
// Allocate a new image structure
//
Image = CoreAllocateZeroBootServicesPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));
if (Image == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Pull out just the file portion of the DevicePath for the LoadedImage FilePath
//
Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, &HandleFilePath);
if (!EFI_ERROR (Status)) {
FilePathSize = CoreDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
FilePath = (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *)FilePath) + FilePathSize );
}
//
// Initialize the fields for an internal driver
//
Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE;
Image->Info.SystemTable = gST;
Image->Info.DeviceHandle = DeviceHandle;
Image->Info.Revision = EFI_LOADED_IMAGE_INFORMATION_REVISION;
Image->Info.FilePath = CoreDuplicateDevicePath (FilePath);
Image->Info.ParentHandle = ParentImageHandle;
if (NumberOfPages != NULL) {
Image->NumberOfPages = *NumberOfPages ;
} else {
Image->NumberOfPages = 0 ;
}
//
// Install the protocol interfaces for this image
// don't fire notifications yet
//
Status = CoreInstallProtocolInterfaceNotify (
&Image->Handle,
&gEfiLoadedImageProtocolGuid,
EFI_NATIVE_INTERFACE,
&Image->Info,
FALSE
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Install Debug Mask Protocol
//
DEBUG_CODE (
Status = InstallDebugMaskProtocol(Image->Handle);
ASSERT_EFI_ERROR (Status);
)
//
// Load the image. If EntryPoint is Null, it will not be set.
//
Status = CoreLoadPeImage (&FHand, Image, DstBuffer, EntryPoint, Attribute, CrossLoad);
if (EFI_ERROR (Status)) {
if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) {
if (NumberOfPages != NULL) {
*NumberOfPages = Image->NumberOfPages;
}
}
goto Done;
}
//
// Register the image in the Debug Image Info Table if the attribute is set
//
if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) {
CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle);
}
//
//Reinstall loaded image protocol to fire any notifications
//
Status = CoreReinstallProtocolInterface (
Image->Handle,
&gEfiLoadedImageProtocolGuid,
&Image->Info,
&Image->Info
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Success. Return the image handle
//
*ImageHandle = Image->Handle;
Done:
//
// All done accessing the source file
// If we allocated the Source buffer, free it
//
if (FHand.FreeBuffer) {
CoreFreePool (FHand.Source);
}
//
// There was an error. If there's an Image structure, free it
//
if (EFI_ERROR (Status)) {
if (Image != NULL) {
CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));
*ImageHandle = NULL;
}
} else if (EFI_ERROR (SecurityStatus)) {
Status = SecurityStatus;
}
return Status;
}
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreLoadImage (
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
OUT EFI_HANDLE *ImageHandle
)
/*++
Routine Description:
Loads an EFI image into memory and returns a handle to the image.
Arguments:
BootPolicy - If TRUE, indicates that the request originates from the boot manager,
and that the boot manager is attempting to load FilePath as a boot selection.
ParentImageHandle - The caller's image handle.
FilePath - The specific file path from which the image is loaded.
SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
the image to be loaded.
SourceSize - The size in bytes of SourceBuffer.
ImageHandle - Pointer to the returned image handle that is created when the image
is successfully loaded.
Returns:
EFI_SUCCESS - The image was loaded into memory.
EFI_NOT_FOUND - The FilePath was not found.
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
parsed to locate the proper protocol for loading the file.
EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
--*/
{
EFI_STATUS Status;
PERF_START (NULL, L"LoadImage", NULL, 0);
Status = CoreLoadImageCommon (
BootPolicy,
ParentImageHandle,
FilePath,
SourceBuffer,
SourceSize,
(EFI_PHYSICAL_ADDRESS)NULL,
NULL,
ImageHandle,
NULL,
EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION,
FALSE
);
if (!EFI_ERROR (Status)) {
PERF_UPDATE (0, L"LoadImage", NULL, *ImageHandle, L"LoadImage", NULL);
PERF_END (*ImageHandle, L"LoadImage", NULL, 0);
} else {
PERF_UPDATE (0, L"LoadImage", NULL, 0, L"Load Failed", L"CoreLoadImage");
PERF_END (0, L"Load Failed", L"CoreLoadImage", 0);
}
return Status;
}
EFI_STATUS
EFIAPI
CoreLoadImageEx (
IN EFI_PE32_IMAGE_PROTOCOL *This,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
OUT UINTN *NumberOfPages OPTIONAL,
OUT EFI_HANDLE *ImageHandle,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
IN UINT32 Attribute
)
/*++
Routine Description:
Loads an EFI image into memory and returns a handle to the image with extended parameters.
Arguments:
This - Calling context
ParentImageHandle - The caller's image handle.
FilePath - The specific file path from which the image is loaded.
SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
the image to be loaded.
SourceSize - The size in bytes of SourceBuffer.
DstBuffer - The buffer to store the image.
NumberOfPages - For input, specifies the space size of the image by caller if not NULL.
For output, specifies the actual space size needed.
ImageHandle - Image handle for output.
EntryPoint - Image entry point for output.
Attribute - The bit mask of attributes to set for the load PE image.
Returns:
EFI_SUCCESS - The image was loaded into memory.
EFI_NOT_FOUND - The FilePath was not found.
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
parsed to locate the proper protocol for loading the file.
EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
--*/
{
return CoreLoadImageCommon (
FALSE,
ParentImageHandle,
FilePath,
SourceBuffer,
SourceSize,
DstBuffer,
NumberOfPages,
ImageHandle,
EntryPoint,
Attribute,
TRUE
);
}
EFI_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreStartImage (
IN EFI_HANDLE ImageHandle,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
)
/*++
Routine Description:
Transfer control to a loaded image's entry point.
Arguments:
ImageHandle - Handle of image to be started.
ExitDataSize - Pointer of the size to ExitData
ExitData - Pointer to a pointer to a data buffer that includes a Null-terminated
Unicode string, optionally followed by additional binary data. The string
is a description that the caller may use to further indicate the reason for
the image’s exit.
Returns:
EFI_INVALID_PARAMETER - Invalid parameter
EFI_OUT_OF_RESOURCES - No enough buffer to allocate
EFI_SUCCESS - Successfully transfer control to the image's entry point.
--*/
{
EFI_STATUS Status;
LOADED_IMAGE_PRIVATE_DATA *Image;
LOADED_IMAGE_PRIVATE_DATA *LastImage;
UINT64 HandleDatabaseKey;
Image = CoreLoadedImageInfo (ImageHandle);
if (Image == NULL_HANDLE || Image->Started) {
return EFI_INVALID_PARAMETER;
}
//
// Cannot start image of an unsupported processor architecture
//
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
return EFI_UNSUPPORTED;
}
//
// Don't profile Objects or invalid start requests
//
PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);
//
// Push the current start image context, and
// link the current image to the head. This is the
// only image that can call Exit()
//
HandleDatabaseKey = CoreGetHandleDatabaseKey();
LastImage = mCurrentImage;
mCurrentImage = Image;
Image->Tpl = gEfiCurrentTpl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -