/*You can find the function in Shell load.c*/
STATIC
EFI_STATUS
LoadDriver (
IN EFI_HANDLE ParentImage,
IN SHELL_FILE_ARG *Arg,
IN BOOLEAN Connect
)
{
EFI_HANDLE ImageHandle;
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *NodePath;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
CHAR16 *LoadOptions;
UINTN LoadOptionsSize;
CHAR16 *Cwd;
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_FILE_HEADER ImageHeader;
EFI_IMAGE_OPTIONAL_HEADER OptionalHeader;
NodePath = FileDevicePath (NULL, Arg->FileName);
FilePath = AppendDevicePath (Arg->ParentDevicePath, NodePath);
if (NodePath) {
FreePool (NodePath);
NodePath = NULL;
}
if (!FilePath) {
return EFI_OUT_OF_RESOURCES;
}
//
// Check whether Image is valid to be loaded.
//
Status = LibGetImageHeader (
FilePath,
&DosHeader,
&ImageHeader,
&OptionalHeader
);
if (!EFI_ERROR (Status) && !EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageHeader.Machine) &&
(OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER ||
OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {
FreePool (FilePath);
PrintToken (
STRING_TOKEN (STR_LOAD_IMAGE_TYPE_UNSUPPORTED),
HiiLoadHandle,
LibGetMachineTypeString (ImageHeader.Machine),
LibGetMachineTypeString (EFI_IMAGE_MACHINE_TYPE)
);
return EFI_INVALID_PARAMETER;
}
Status = BS->LoadImage (
FALSE,
ParentImage,
FilePath,
NULL,
0,
&ImageHandle
);
FreePool (FilePath);
if (EFI_ERROR (Status)) {
if (Status == EFI_SECURITY_VIOLATION) {
BS->UnloadImage (ImageHandle);
}
PrintToken (STRING_TOKEN (STR_LOAD_NOT_IMAGE), HiiLoadHandle, Arg->FullName);
return EFI_INVALID_PARAMETER;
}
//
// Verify the image is a driver ?
//
BS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID *) &ImageInfo);
if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
PrintToken (STRING_TOKEN (STR_LOAD_IMAGE_NOT_DRIVER), HiiLoadHandle, Arg->FullName);
BS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
return EFI_INVALID_PARAMETER;
}
//
// Construct a load options buffer containing the command line and
// current working directory.
//
// NOTE: To prevent memory leaks, the protocol is responsible for
// freeing the memory associated with the load options.
//
// One day we'll pass arguments to the protocol....
//
Cwd = ShellCurDir (NULL);
if (NULL == Cwd) {
Cwd = StrDuplicate (L"");
}
LoadOptionsSize = (StrLen (Arg->FullName) + 2 + StrLen (Cwd) + 2) * sizeof (CHAR16);
LoadOptions = AllocatePool (LoadOptionsSize);
ASSERT (LoadOptions);
StrCpy (LoadOptions, Arg->FullName);
StrCpy (&LoadOptions[StrLen (LoadOptions) + 1], Cwd);
FreePool (Cwd);
if (ImageInfo->LoadOptions) {
FreePool (ImageInfo->LoadOptions);
}
ImageInfo->LoadOptionsSize = (UINT32) LoadOptionsSize;
ImageInfo->LoadOptions = LoadOptions;
//
// Start the image
//
Status = BS->StartImage (ImageHandle, NULL, NULL);
if (!EFI_ERROR (Status)) {
PrintToken (
STRING_TOKEN (STR_LOAD_IMAGE_LOADED),
HiiLoadHandle,
Arg->FullName,
ImageInfo->ImageBase,
Status
);
} else {
PrintToken (
STRING_TOKEN (STR_LOAD_IMAGE_ERROR),
HiiLoadHandle,
Arg->FullName,
Status
);
}
if (Connect) {
Status = LoadConnectAllDriversToAllControllers ();
}
//
// When any driver starts, turn off the watchdog timer
//
BS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
return Status;
}
沒有留言:
張貼留言