Ошибка startimage() с -1 после loadimage() в UEFI при загрузке приложения efi из другого приложения

Я пытаюсь загрузить приложение efi из другого приложения efi, используя протоколы loadimage и startimage. но loadimage завершается успешно, startimage завершается с ошибкой с возвращаемым значением -1/0xffffffff. было бы очень полезно, если бы кто-нибудь предложил некоторые идеи, почему это терпит неудачу. если есть ошибка в коде, исправьте.

EFI_STATUS LoadPythonBinary()
{
    EFI_STATUS Status;
    UINTN NumberOfFSHandles;
    EFI_HANDLE *FSHandles;
    EFI_GUID SimpleFileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
    UINTN  Index = 0;
    EFI_BLOCK_IO  *BlkIo;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSysProtocol =  NULL;
    EFI_DEVICE_PATH_PROTOCOL        *FilePath;
    EFI_HANDLE                      ImageHandle2 = NULL;
//    EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
//    EFI_HANDLE                      DeviceHandle;
    EFI_HANDLE          Controller=NULL;
    EFI_LOADED_IMAGE_PROTOCOL  *ImageInfo;
    EFI_GUID EfiDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
    EFI_GUID EfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
    const CHAR16   *FileName = L"Python.efi";
    EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
//    EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
    char temp[MAX_PATH];
    CHAR16 CmdLineParams[MAX_PATH] = L"fs0:\\GK\\Temp\\UnzipBuildTools.py fs0:\\GK\\Temp\\EFI.zip fs0:\\Test";
    strcpy(temp,(const char *)StrDup16to8(CmdLineParams));

    Status = gBS->LocateHandleBuffer(ByProtocol, &SimpleFileSystemGuid,NULL, &NumberOfFSHandles, &FSHandles);
    if(!EFI_ERROR(Status))
    {
        for(Index = 0; Index < NumberOfFSHandles; Index++)
        {
            Status = gBS->HandleProtocol(FSHandles[Index], &SimpleFileSystemGuid, &BlkIo);
            if(!EFI_ERROR(Status))
            {
                    FilePath = FileDevicePath(FSHandles[Index],FileName);
                    Status = gBS->LoadImage(TRUE, gImageHandle, FilePath, NULL, 0, &ImageHandle2);
                    printf("Load Image Status = %x", Status);
                    if(!EFI_ERROR(Status))
                    {
                        printf("Image Loaded Successfully\n");
                        Status = gBS->HandleProtocol(ImageHandle2, &EfiLoadedImageProtocol,(VOID**)&ImageInfo);
                        if(!EFI_ERROR(Status))
                        {
                            if(ImageInfo->ImageCodeType == EfiLoaderCode) 
                            {
                                 gBS->FreePool(FilePath);
                            }
                            printf("Options :%s\n",temp);
                            printf("LoadedImage->ImageSize = %x", ImageInfo->ImageSize);
                            ImageInfo->LoadOptions = CmdLineParams;
                            ImageInfo->LoadOptionsSize = (UINT32)(wcslen(CmdLineParams));
                            ImageInfo->DeviceHandle = gImageHandle;
                        }
                    }

                    printf("About to start image\n");
                    Status = gBS->StartImage(ImageHandle2, NULL, NULL);
                    printf("StartImage Status = %x", Status);
                    if(!EFI_ERROR(Status))
                    {
                        printf("StartImage success\n");
                        break;
                    }
            }
        }
    }

return Status;
}

person gkreddy    schedule 05.08.2016    source источник


Ответы (2)


Возможная проблема. Вероятно, ваш целевой образ (Python.efi) не является допустимым приложением UEFI и не может быть загружен с помощью EFI_BOOT_SERVICES.StartImage(). > интерфейс. Для получения дополнительной информации ознакомьтесь с допустимыми типами образов UEFI, загружаемыми службой загрузки UEFI, проверьте сеанс 7.4 в Спецификация UEFI 2.7.

Решение. Убедитесь, что в INF-файле целевого приложения поле MODULE_TYPE настроено на UEFI_APPLICATION и его .c имеет сигнатуру точки входа в приложение UEFI, аналогичную следующей:

EFI_STATUS
EFIAPI
MyEntryPointName (
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE  *SystemTable
    )
{
 ...
}

С примером функционального кода можно ознакомиться в LoadImageApp. Это приложение успешно загружает и запускает целевое приложение с именем HelloImageEntryPoint.efi.

person Manoel Rui    schedule 31.10.2017

-1 не является допустимым значением EFI_STATUS, если вы работаете в 64-разрядной системе. EFI_STATUS является 64-разрядным. Также, если вы используете Print(), %r распечатает строку для EFI_STATUS.

Значения EFI_STATUS, возвращаемые службами EFI, определяются в спецификации EFI: EFI_INVALID_PARAMETER — ImageHandle либо является недопустимым дескриптором изображения, либо изображение уже было инициализировано с помощью StartImage.

EFI_SECURITY_VIOLATION — текущая политика платформы указывает, что образ не должен запускаться.

Код выхода из изображения - Код выхода из изображения.

Итак, код, который вы загрузили, вернул вам ошибку?

person Andrew Fish    schedule 10.08.2017
comment
Это больше похоже на комментарий, чем на ответ на заданный вопрос. - person ; 10.08.2017
comment
Обновлен ответ, чтобы указать, как действительный EFI_STATUS поможет отладить проблему. - person Andrew Fish; 11.08.2017