From: "Laszlo Ersek" <lersek@redhat.com>
To: devel@edk2.groups.io, ard.biesheuvel@linaro.org
Subject: Re: [edk2-devel] [PATCH v2 06/14] ArmVirtPkg/PlatformBootManagerLib: switch to separate QEMU loader
Date: Thu, 5 Mar 2020 11:01:35 +0100 [thread overview]
Message-ID: <55629ce8-f016-d6bb-b0e6-c3739bb9d2cc@redhat.com> (raw)
In-Reply-To: <20200304095233.21046-7-ard.biesheuvel@linaro.org>
On 03/04/20 10:52, Ard Biesheuvel wrote:
> Drop the QEMU loader file system implementation inside this library,
> and switch to the separate QemuLoadImageLib library and the associated
> driver to expose the kernel and initrd passed via the QEMU command line.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf | 9 +-
> ArmVirtPkg/Library/PlatformBootManagerLib/QemuKernel.c | 1061 +-------------------
> 2 files changed, 7 insertions(+), 1063 deletions(-)
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks,
Laszlo
> diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index a9d4888d4377..a010564527b6 100644
> --- a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -44,9 +44,8 @@ [LibraryClasses]
> MemoryAllocationLib
> PcdLib
> PlatformBmPrintScLib
> - PrintLib
> QemuBootOrderLib
> - QemuFwCfgLib
> + QemuLoadImageLib
> ReportStatusCodeLib
> UefiBootManagerLib
> UefiBootServicesTableLib
> @@ -64,18 +63,12 @@ [Pcd]
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
>
> [Guids]
> - gEfiFileInfoGuid
> - gEfiFileSystemInfoGuid
> - gEfiFileSystemVolumeLabelInfoIdGuid
> gEfiEndOfDxeEventGroupGuid
> gRootBridgesConnectedEventGroupGuid
> gUefiShellFileGuid
>
> [Protocols]
> - gEfiDevicePathProtocolGuid
> gEfiFirmwareVolume2ProtocolGuid
> gEfiGraphicsOutputProtocolGuid
> - gEfiLoadedImageProtocolGuid
> gEfiPciRootBridgeIoProtocolGuid
> - gEfiSimpleFileSystemProtocolGuid
> gVirtioDeviceProtocolGuid
> diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/QemuKernel.c b/ArmVirtPkg/Library/PlatformBootManagerLib/QemuKernel.c
> index d3851fd75fa5..e9c110a0ed75 100644
> --- a/ArmVirtPkg/Library/PlatformBootManagerLib/QemuKernel.c
> +++ b/ArmVirtPkg/Library/PlatformBootManagerLib/QemuKernel.c
> @@ -9,887 +9,11 @@
> SPDX-License-Identifier: BSD-2-Clause-Patent
> **/
>
> -#include <Guid/FileInfo.h>
> -#include <Guid/FileSystemInfo.h>
> -#include <Guid/FileSystemVolumeLabelInfo.h>
> -#include <Library/PrintLib.h>
> -#include <Library/QemuFwCfgLib.h>
> +#include <Library/QemuLoadImageLib.h>
> #include <Library/ReportStatusCodeLib.h>
> -#include <Protocol/DevicePath.h>
> -#include <Protocol/LoadedImage.h>
> -#include <Protocol/SimpleFileSystem.h>
>
> #include "PlatformBm.h"
>
> -//
> -// Static data that hosts the fw_cfg blobs and serves file requests.
> -//
> -typedef enum {
> - KernelBlobTypeKernel,
> - KernelBlobTypeInitrd,
> - KernelBlobTypeCommandLine,
> - KernelBlobTypeMax
> -} KERNEL_BLOB_TYPE;
> -
> -typedef struct {
> - FIRMWARE_CONFIG_ITEM CONST SizeKey;
> - FIRMWARE_CONFIG_ITEM CONST DataKey;
> - CONST CHAR16 * CONST Name;
> - UINT32 Size;
> - UINT8 *Data;
> -} KERNEL_BLOB;
> -
> -STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {
> - { QemuFwCfgItemKernelSize, QemuFwCfgItemKernelData, L"kernel" },
> - { QemuFwCfgItemInitrdSize, QemuFwCfgItemInitrdData, L"initrd" },
> - { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, L"cmdline" }
> -};
> -
> -STATIC UINT64 mTotalBlobBytes;
> -
> -//
> -// Device path for the handle that incorporates our "EFI stub filesystem". The
> -// GUID is arbitrary and need not be standardized or advertized.
> -//
> -#pragma pack(1)
> -typedef struct {
> - VENDOR_DEVICE_PATH VenHwNode;
> - EFI_DEVICE_PATH_PROTOCOL EndNode;
> -} SINGLE_VENHW_NODE_DEVPATH;
> -#pragma pack()
> -
> -STATIC CONST SINGLE_VENHW_NODE_DEVPATH mFileSystemDevicePath = {
> - {
> - { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH) } },
> - {
> - 0xb0fae7e7, 0x6b07, 0x49d0,
> - { 0x9e, 0x5b, 0x3b, 0xde, 0xc8, 0x3b, 0x03, 0x9d }
> - }
> - },
> -
> - {
> - END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
> - { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
> - }
> -};
> -
> -//
> -// The "file in the EFI stub filesystem" abstraction.
> -//
> -STATIC EFI_TIME mInitTime;
> -
> -#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')
> -
> -typedef struct {
> - UINT64 Signature; // Carries STUB_FILE_SIG.
> -
> - KERNEL_BLOB_TYPE BlobType; // Index into mKernelBlob. KernelBlobTypeMax
> - // denotes the root directory of the filesystem.
> -
> - UINT64 Position; // Byte position for regular files;
> - // next directory entry to return for the root
> - // directory.
> -
> - EFI_FILE_PROTOCOL File; // Standard protocol interface.
> -} STUB_FILE;
> -
> -#define STUB_FILE_FROM_FILE(FilePointer) \
> - CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG)
> -
> -//
> -// Tentative definition of the file protocol template. The initializer
> -// (external definition) will be provided later.
> -//
> -STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate;
> -
> -
> -//
> -// Protocol member functions for File.
> -//
> -
> -/**
> - Opens a new file relative to the source file's location.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
> - the file handle to the source location. This would
> - typically be an open handle to a directory.
> -
> - @param[out] NewHandle A pointer to the location to return the opened handle
> - for the new file.
> -
> - @param[in] FileName The Null-terminated string of the name of the file to
> - be opened. The file name may contain the following
> - path modifiers: "\", ".", and "..".
> -
> - @param[in] OpenMode The mode to open the file. The only valid
> - combinations that the file may be opened with are:
> - Read, Read/Write, or Create/Read/Write.
> -
> - @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case
> - these are the attribute bits for the newly created
> - file.
> -
> - @retval EFI_SUCCESS The file was opened.
> - @retval EFI_NOT_FOUND The specified file could not be found on the
> - device.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
> - medium is no longer supported.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a
> - file for write when the media is
> - write-protected.
> - @retval EFI_ACCESS_DENIED The service denied access to the file.
> - @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
> - file.
> - @retval EFI_VOLUME_FULL The volume is full.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileOpen (
> - IN EFI_FILE_PROTOCOL *This,
> - OUT EFI_FILE_PROTOCOL **NewHandle,
> - IN CHAR16 *FileName,
> - IN UINT64 OpenMode,
> - IN UINT64 Attributes
> - )
> -{
> - CONST STUB_FILE *StubFile;
> - UINTN BlobType;
> - STUB_FILE *NewStubFile;
> -
> - //
> - // We're read-only.
> - //
> - switch (OpenMode) {
> - case EFI_FILE_MODE_READ:
> - break;
> -
> - case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
> - case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
> - return EFI_WRITE_PROTECTED;
> -
> - default:
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Only the root directory supports opening files in it.
> - //
> - StubFile = STUB_FILE_FROM_FILE (This);
> - if (StubFile->BlobType != KernelBlobTypeMax) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - //
> - // Locate the file.
> - //
> - for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
> - if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {
> - break;
> - }
> - }
> - if (BlobType == KernelBlobTypeMax) {
> - return EFI_NOT_FOUND;
> - }
> -
> - //
> - // Found it.
> - //
> - NewStubFile = AllocatePool (sizeof *NewStubFile);
> - if (NewStubFile == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - NewStubFile->Signature = STUB_FILE_SIG;
> - NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType;
> - NewStubFile->Position = 0;
> - CopyMem (&NewStubFile->File, &mEfiFileProtocolTemplate,
> - sizeof mEfiFileProtocolTemplate);
> - *NewHandle = &NewStubFile->File;
> -
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Closes a specified file handle.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
> - handle to close.
> -
> - @retval EFI_SUCCESS The file was closed.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileClose (
> - IN EFI_FILE_PROTOCOL *This
> - )
> -{
> - FreePool (STUB_FILE_FROM_FILE (This));
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Close and delete the file handle.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
> - handle to the file to delete.
> -
> - @retval EFI_SUCCESS The file was closed and deleted, and the
> - handle was closed.
> - @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not
> - deleted.
> -
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileDelete (
> - IN EFI_FILE_PROTOCOL *This
> - )
> -{
> - FreePool (STUB_FILE_FROM_FILE (This));
> - return EFI_WARN_DELETE_FAILURE;
> -}
> -
> -
> -/**
> - Helper function that formats an EFI_FILE_INFO structure into the
> - user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including
> - KernelBlobTypeMax, which stands for the root directory).
> -
> - The interface follows the EFI_FILE_GET_INFO -- and for directories, the
> - EFI_FILE_READ -- interfaces.
> -
> - @param[in] BlobType The KERNEL_BLOB_TYPE value identifying the fw_cfg
> - blob backing the STUB_FILE that information is
> - being requested about. If BlobType equals
> - KernelBlobTypeMax, then information will be
> - provided about the root directory of the
> - filesystem.
> -
> - @param[in,out] BufferSize On input, the size of Buffer. On output, the
> - amount of data returned in Buffer. In both cases,
> - the size is measured in bytes.
> -
> - @param[out] Buffer A pointer to the data buffer to return. The
> - buffer's type is EFI_FILE_INFO.
> -
> - @retval EFI_SUCCESS The information was returned.
> - @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to store the
> - EFI_FILE_INFO structure. BufferSize has been
> - updated with the size needed to complete the
> - request.
> -**/
> -STATIC
> -EFI_STATUS
> -ConvertKernelBlobTypeToFileInfo (
> - IN KERNEL_BLOB_TYPE BlobType,
> - IN OUT UINTN *BufferSize,
> - OUT VOID *Buffer
> - )
> -{
> - CONST CHAR16 *Name;
> - UINT64 FileSize;
> - UINT64 Attribute;
> -
> - UINTN NameSize;
> - UINTN FileInfoSize;
> - EFI_FILE_INFO *FileInfo;
> - UINTN OriginalBufferSize;
> -
> - if (BlobType == KernelBlobTypeMax) {
> - //
> - // getting file info about the root directory
> - //
> - Name = L"\\";
> - FileSize = KernelBlobTypeMax;
> - Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
> - } else {
> - CONST KERNEL_BLOB *Blob;
> -
> - Blob = &mKernelBlob[BlobType];
> - Name = Blob->Name;
> - FileSize = Blob->Size;
> - Attribute = EFI_FILE_READ_ONLY;
> - }
> -
> - NameSize = (StrLen(Name) + 1) * 2;
> - FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize;
> - ASSERT (FileInfoSize >= sizeof *FileInfo);
> -
> - OriginalBufferSize = *BufferSize;
> - *BufferSize = FileInfoSize;
> - if (OriginalBufferSize < *BufferSize) {
> - return EFI_BUFFER_TOO_SMALL;
> - }
> -
> - FileInfo = (EFI_FILE_INFO *)Buffer;
> - FileInfo->Size = FileInfoSize;
> - FileInfo->FileSize = FileSize;
> - FileInfo->PhysicalSize = FileSize;
> - FileInfo->Attribute = Attribute;
> -
> - CopyMem (&FileInfo->CreateTime, &mInitTime, sizeof mInitTime);
> - CopyMem (&FileInfo->LastAccessTime, &mInitTime, sizeof mInitTime);
> - CopyMem (&FileInfo->ModificationTime, &mInitTime, sizeof mInitTime);
> - CopyMem (FileInfo->FileName, Name, NameSize);
> -
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Reads data from a file, or continues scanning a directory.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
> - is the file handle to read data from.
> -
> - @param[in,out] BufferSize On input, the size of the Buffer. On output, the
> - amount of data returned in Buffer. In both cases,
> - the size is measured in bytes. If the read goes
> - beyond the end of the file, the read length is
> - truncated to the end of the file.
> -
> - If This is a directory, the function reads the
> - directory entry at the current position and
> - returns the entry (as EFI_FILE_INFO) in Buffer. If
> - there are no more directory entries, the
> - BufferSize is set to zero on output.
> -
> - @param[out] Buffer The buffer into which the data is read.
> -
> - @retval EFI_SUCCESS Data was read.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted
> - file.
> - @retval EFI_DEVICE_ERROR On entry, the current file position is beyond
> - the end of the file.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to store the
> - current directory entry as a EFI_FILE_INFO
> - structure. BufferSize has been updated with the
> - size needed to complete the request, and the
> - directory position has not been advanced.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileRead (
> - IN EFI_FILE_PROTOCOL *This,
> - IN OUT UINTN *BufferSize,
> - OUT VOID *Buffer
> - )
> -{
> - STUB_FILE *StubFile;
> - CONST KERNEL_BLOB *Blob;
> - UINT64 Left;
> -
> - StubFile = STUB_FILE_FROM_FILE (This);
> -
> - //
> - // Scanning the root directory?
> - //
> - if (StubFile->BlobType == KernelBlobTypeMax) {
> - EFI_STATUS Status;
> -
> - if (StubFile->Position == KernelBlobTypeMax) {
> - //
> - // Scanning complete.
> - //
> - *BufferSize = 0;
> - return EFI_SUCCESS;
> - }
> -
> - Status = ConvertKernelBlobTypeToFileInfo (
> - (KERNEL_BLOB_TYPE)StubFile->Position,
> - BufferSize,
> - Buffer);
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> - ++StubFile->Position;
> - return EFI_SUCCESS;
> - }
> -
> - //
> - // Reading a file.
> - //
> - Blob = &mKernelBlob[StubFile->BlobType];
> - if (StubFile->Position > Blob->Size) {
> - return EFI_DEVICE_ERROR;
> - }
> -
> - Left = Blob->Size - StubFile->Position;
> - if (*BufferSize > Left) {
> - *BufferSize = (UINTN)Left;
> - }
> - if (Blob->Data != NULL) {
> - CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);
> - }
> - StubFile->Position += *BufferSize;
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Writes data to a file.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
> - is the file handle to write data to.
> -
> - @param[in,out] BufferSize On input, the size of the Buffer. On output, the
> - amount of data actually written. In both cases,
> - the size is measured in bytes.
> -
> - @param[in] Buffer The buffer of data to write.
> -
> - @retval EFI_SUCCESS Data was written.
> - @retval EFI_UNSUPPORTED Writes to open directory files are not
> - supported.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
> - @retval EFI_ACCESS_DENIED The file was opened read only.
> - @retval EFI_VOLUME_FULL The volume is full.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileWrite (
> - IN EFI_FILE_PROTOCOL *This,
> - IN OUT UINTN *BufferSize,
> - IN VOID *Buffer
> - )
> -{
> - STUB_FILE *StubFile;
> -
> - StubFile = STUB_FILE_FROM_FILE (This);
> - return (StubFile->BlobType == KernelBlobTypeMax) ?
> - EFI_UNSUPPORTED :
> - EFI_WRITE_PROTECTED;
> -}
> -
> -
> -/**
> - Returns a file's current position.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
> - file handle to get the current position on.
> -
> - @param[out] Position The address to return the file's current position
> - value.
> -
> - @retval EFI_SUCCESS The position was returned.
> - @retval EFI_UNSUPPORTED The request is not valid on open directories.
> - @retval EFI_DEVICE_ERROR An attempt was made to get the position from a
> - deleted file.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileGetPosition (
> - IN EFI_FILE_PROTOCOL *This,
> - OUT UINT64 *Position
> - )
> -{
> - STUB_FILE *StubFile;
> -
> - StubFile = STUB_FILE_FROM_FILE (This);
> - if (StubFile->BlobType == KernelBlobTypeMax) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - *Position = StubFile->Position;
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Sets a file's current position.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
> - file handle to set the requested position on.
> -
> - @param[in] Position The byte position from the start of the file to set. For
> - regular files, MAX_UINT64 means "seek to end". For
> - directories, zero means "rewind directory scan".
> -
> - @retval EFI_SUCCESS The position was set.
> - @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
> - directories.
> - @retval EFI_DEVICE_ERROR An attempt was made to set the position of a
> - deleted file.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileSetPosition (
> - IN EFI_FILE_PROTOCOL *This,
> - IN UINT64 Position
> - )
> -{
> - STUB_FILE *StubFile;
> - KERNEL_BLOB *Blob;
> -
> - StubFile = STUB_FILE_FROM_FILE (This);
> -
> - if (StubFile->BlobType == KernelBlobTypeMax) {
> - if (Position == 0) {
> - //
> - // rewinding a directory scan is allowed
> - //
> - StubFile->Position = 0;
> - return EFI_SUCCESS;
> - }
> - return EFI_UNSUPPORTED;
> - }
> -
> - //
> - // regular file seek
> - //
> - Blob = &mKernelBlob[StubFile->BlobType];
> - if (Position == MAX_UINT64) {
> - //
> - // seek to end
> - //
> - StubFile->Position = Blob->Size;
> - } else {
> - //
> - // absolute seek from beginning -- seeking past the end is allowed
> - //
> - StubFile->Position = Position;
> - }
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Returns information about a file.
> -
> - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance
> - that is the file handle the requested
> - information is for.
> -
> - @param[in] InformationType The type identifier GUID for the information
> - being requested. The following information
> - types are supported, storing the
> - corresponding structures in Buffer:
> -
> - - gEfiFileInfoGuid: EFI_FILE_INFO
> -
> - - gEfiFileSystemInfoGuid:
> - EFI_FILE_SYSTEM_INFO
> -
> - - gEfiFileSystemVolumeLabelInfoIdGuid:
> - EFI_FILE_SYSTEM_VOLUME_LABEL
> -
> - @param[in,out] BufferSize On input, the size of Buffer. On output, the
> - amount of data returned in Buffer. In both
> - cases, the size is measured in bytes.
> -
> - @param[out] Buffer A pointer to the data buffer to return. The
> - buffer's type is indicated by
> - InformationType.
> -
> - @retval EFI_SUCCESS The information was returned.
> - @retval EFI_UNSUPPORTED The InformationType is not known.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to store the
> - information structure requested by
> - InformationType. BufferSize has been updated
> - with the size needed to complete the request.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileGetInfo (
> - IN EFI_FILE_PROTOCOL *This,
> - IN EFI_GUID *InformationType,
> - IN OUT UINTN *BufferSize,
> - OUT VOID *Buffer
> - )
> -{
> - CONST STUB_FILE *StubFile;
> - UINTN OriginalBufferSize;
> -
> - StubFile = STUB_FILE_FROM_FILE (This);
> -
> - if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
> - return ConvertKernelBlobTypeToFileInfo (StubFile->BlobType, BufferSize,
> - Buffer);
> - }
> -
> - OriginalBufferSize = *BufferSize;
> -
> - if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
> - EFI_FILE_SYSTEM_INFO *FileSystemInfo;
> -
> - *BufferSize = sizeof *FileSystemInfo;
> - if (OriginalBufferSize < *BufferSize) {
> - return EFI_BUFFER_TOO_SMALL;
> - }
> -
> - FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
> - FileSystemInfo->Size = sizeof *FileSystemInfo;
> - FileSystemInfo->ReadOnly = TRUE;
> - FileSystemInfo->VolumeSize = mTotalBlobBytes;
> - FileSystemInfo->FreeSpace = 0;
> - FileSystemInfo->BlockSize = 1;
> - FileSystemInfo->VolumeLabel[0] = L'\0';
> -
> - return EFI_SUCCESS;
> - }
> -
> - if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
> - EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;
> -
> - *BufferSize = sizeof *FileSystemVolumeLabel;
> - if (OriginalBufferSize < *BufferSize) {
> - return EFI_BUFFER_TOO_SMALL;
> - }
> -
> - FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;
> - FileSystemVolumeLabel->VolumeLabel[0] = L'\0';
> -
> - return EFI_SUCCESS;
> - }
> -
> - return EFI_UNSUPPORTED;
> -}
> -
> -
> -/**
> - Sets information about a file.
> -
> - @param[in] File A pointer to the EFI_FILE_PROTOCOL instance that
> - is the file handle the information is for.
> -
> - @param[in] InformationType The type identifier for the information being
> - set.
> -
> - @param[in] BufferSize The size, in bytes, of Buffer.
> -
> - @param[in] Buffer A pointer to the data buffer to write. The
> - buffer's type is indicated by InformationType.
> -
> - @retval EFI_SUCCESS The information was set.
> - @retval EFI_UNSUPPORTED The InformationType is not known.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the
> - media is read-only.
> - @retval EFI_WRITE_PROTECTED InformationType is
> - EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media
> - is read only.
> - @retval EFI_WRITE_PROTECTED InformationType is
> - EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media
> - is read-only.
> - @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
> - to a file that is already present.
> - @retval EFI_ACCESS_DENIED An attempt is being made to change the
> - EFI_FILE_DIRECTORY Attribute.
> - @retval EFI_ACCESS_DENIED An attempt is being made to change the size of
> - a directory.
> - @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the
> - file was opened read-only and an attempt is
> - being made to modify a field other than
> - Attribute.
> - @retval EFI_VOLUME_FULL The volume is full.
> - @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type
> - indicated by InformationType.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileSetInfo (
> - IN EFI_FILE_PROTOCOL *This,
> - IN EFI_GUID *InformationType,
> - IN UINTN BufferSize,
> - IN VOID *Buffer
> - )
> -{
> - return EFI_WRITE_PROTECTED;
> -}
> -
> -
> -/**
> - Flushes all modified data associated with a file to a device.
> -
> - @param [in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
> - file handle to flush.
> -
> - @retval EFI_SUCCESS The data was flushed.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
> - @retval EFI_ACCESS_DENIED The file was opened read-only.
> - @retval EFI_VOLUME_FULL The volume is full.
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileFlush (
> - IN EFI_FILE_PROTOCOL *This
> - )
> -{
> - return EFI_WRITE_PROTECTED;
> -}
> -
> -//
> -// External definition of the file protocol template.
> -//
> -STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
> - EFI_FILE_PROTOCOL_REVISION, // revision 1
> - StubFileOpen,
> - StubFileClose,
> - StubFileDelete,
> - StubFileRead,
> - StubFileWrite,
> - StubFileGetPosition,
> - StubFileSetPosition,
> - StubFileGetInfo,
> - StubFileSetInfo,
> - StubFileFlush,
> - NULL, // OpenEx, revision 2
> - NULL, // ReadEx, revision 2
> - NULL, // WriteEx, revision 2
> - NULL // FlushEx, revision 2
> -};
> -
> -
> -//
> -// Protocol member functions for SimpleFileSystem.
> -//
> -
> -/**
> - Open the root directory on a volume.
> -
> - @param[in] This A pointer to the volume to open the root directory on.
> -
> - @param[out] Root A pointer to the location to return the opened file handle
> - for the root directory in.
> -
> - @retval EFI_SUCCESS The device was opened.
> - @retval EFI_UNSUPPORTED This volume does not support the requested file
> - system type.
> - @retval EFI_NO_MEDIA The device has no medium.
> - @retval EFI_DEVICE_ERROR The device reported an error.
> - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
> - @retval EFI_ACCESS_DENIED The service denied access to the file.
> - @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
> - resources.
> - @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
> - medium is no longer supported. Any existing
> - file handles for this volume are no longer
> - valid. To access the files on the new medium,
> - the volume must be reopened with OpenVolume().
> -**/
> -STATIC
> -EFI_STATUS
> -EFIAPI
> -StubFileSystemOpenVolume (
> - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
> - OUT EFI_FILE_PROTOCOL **Root
> - )
> -{
> - STUB_FILE *StubFile;
> -
> - StubFile = AllocatePool (sizeof *StubFile);
> - if (StubFile == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - StubFile->Signature = STUB_FILE_SIG;
> - StubFile->BlobType = KernelBlobTypeMax;
> - StubFile->Position = 0;
> - CopyMem (&StubFile->File, &mEfiFileProtocolTemplate,
> - sizeof mEfiFileProtocolTemplate);
> - *Root = &StubFile->File;
> -
> - return EFI_SUCCESS;
> -}
> -
> -STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
> - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
> - StubFileSystemOpenVolume
> -};
> -
> -
> -//
> -// Utility functions.
> -//
> -
> -/**
> - Populate a blob in mKernelBlob.
> -
> - param[in,out] Blob Pointer to the KERNEL_BLOB element in mKernelBlob that is
> - to be filled from fw_cfg.
> -
> - @retval EFI_SUCCESS Blob has been populated. If fw_cfg reported a
> - size of zero for the blob, then Blob->Data has
> - been left unchanged.
> -
> - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Blob->Data.
> -**/
> -STATIC
> -EFI_STATUS
> -FetchBlob (
> - IN OUT KERNEL_BLOB *Blob
> - )
> -{
> - UINT32 Left;
> -
> - //
> - // Read blob size.
> - //
> - QemuFwCfgSelectItem (Blob->SizeKey);
> - Blob->Size = QemuFwCfgRead32 ();
> - if (Blob->Size == 0) {
> - return EFI_SUCCESS;
> - }
> -
> - //
> - // Read blob.
> - //
> - Blob->Data = AllocatePool (Blob->Size);
> - if (Blob->Data == NULL) {
> - DEBUG ((EFI_D_ERROR, "%a: failed to allocate %Ld bytes for \"%s\"\n",
> - __FUNCTION__, (INT64)Blob->Size, Blob->Name));
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - DEBUG ((EFI_D_INFO, "%a: loading %Ld bytes for \"%s\"\n", __FUNCTION__,
> - (INT64)Blob->Size, Blob->Name));
> - QemuFwCfgSelectItem (Blob->DataKey);
> -
> - Left = Blob->Size;
> - do {
> - UINT32 Chunk;
> -
> - Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;
> - QemuFwCfgReadBytes (Chunk, Blob->Data + (Blob->Size - Left));
> - Left -= Chunk;
> - DEBUG ((EFI_D_VERBOSE, "%a: %Ld bytes remaining for \"%s\"\n",
> - __FUNCTION__, (INT64)Left, Blob->Name));
> - } while (Left > 0);
> - return EFI_SUCCESS;
> -}
> -
> -
> //
> // The entry point of the feature.
> //
> @@ -916,159 +40,14 @@ TryRunningQemuKernel (
> VOID
> )
> {
> - UINTN BlobType;
> - KERNEL_BLOB *CurrentBlob;
> - KERNEL_BLOB *KernelBlob, *InitrdBlob, *CommandLineBlob;
> EFI_STATUS Status;
> - EFI_HANDLE FileSystemHandle;
> - EFI_DEVICE_PATH_PROTOCOL *KernelDevicePath;
> EFI_HANDLE KernelImageHandle;
> - EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;
>
> - Status = gRT->GetTime (&mInitTime, NULL /* Capabilities */);
> + Status = QemuLoadKernelImage (&KernelImageHandle);
> if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "%a: GetTime(): %r\n", __FUNCTION__, Status));
> return Status;
> }
>
> - //
> - // Fetch all blobs.
> - //
> - for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
> - CurrentBlob = &mKernelBlob[BlobType];
> - Status = FetchBlob (CurrentBlob);
> - if (EFI_ERROR (Status)) {
> - goto FreeBlobs;
> - }
> - mTotalBlobBytes += CurrentBlob->Size;
> - }
> - KernelBlob = &mKernelBlob[KernelBlobTypeKernel];
> - InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];
> - CommandLineBlob = &mKernelBlob[KernelBlobTypeCommandLine];
> -
> - if (KernelBlob->Data == NULL) {
> - Status = EFI_NOT_FOUND;
> - goto FreeBlobs;
> - }
> -
> - //
> - // Create a new handle with a single VenHw() node device path protocol on it,
> - // plus a custom SimpleFileSystem protocol on it.
> - //
> - FileSystemHandle = NULL;
> - Status = gBS->InstallMultipleProtocolInterfaces (&FileSystemHandle,
> - &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,
> - &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
> - NULL);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",
> - __FUNCTION__, Status));
> - goto FreeBlobs;
> - }
> -
> - //
> - // Create a device path for the kernel image to be loaded from that will call
> - // back into our file system.
> - //
> - KernelDevicePath = FileDevicePath (FileSystemHandle, KernelBlob->Name);
> - if (KernelDevicePath == NULL) {
> - DEBUG ((EFI_D_ERROR, "%a: failed to allocate kernel device path\n",
> - __FUNCTION__));
> - Status = EFI_OUT_OF_RESOURCES;
> - goto UninstallProtocols;
> - }
> -
> - //
> - // Load the image. This should call back into our file system.
> - //
> - Status = gBS->LoadImage (
> - FALSE, // BootPolicy: exact match required
> - gImageHandle, // ParentImageHandle
> - KernelDevicePath,
> - NULL, // SourceBuffer
> - 0, // SourceSize
> - &KernelImageHandle
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "%a: LoadImage(): %r\n", __FUNCTION__, Status));
> - if (Status != EFI_SECURITY_VIOLATION) {
> - goto FreeKernelDevicePath;
> - }
> - //
> - // From the resource allocation perspective, EFI_SECURITY_VIOLATION means
> - // "success", so we must roll back the image loading.
> - //
> - goto UnloadKernelImage;
> - }
> -
> - //
> - // Construct the kernel command line.
> - //
> - Status = gBS->OpenProtocol (
> - KernelImageHandle,
> - &gEfiLoadedImageProtocolGuid,
> - (VOID **)&KernelLoadedImage,
> - gImageHandle, // AgentHandle
> - NULL, // ControllerHandle
> - EFI_OPEN_PROTOCOL_GET_PROTOCOL
> - );
> - ASSERT_EFI_ERROR (Status);
> -
> - if (CommandLineBlob->Data == NULL) {
> - KernelLoadedImage->LoadOptionsSize = 0;
> - } else {
> - //
> - // Verify NUL-termination of the command line.
> - //
> - if (CommandLineBlob->Data[CommandLineBlob->Size - 1] != '\0') {
> - DEBUG ((EFI_D_ERROR, "%a: kernel command line is not NUL-terminated\n",
> - __FUNCTION__));
> - Status = EFI_PROTOCOL_ERROR;
> - goto UnloadKernelImage;
> - }
> -
> - //
> - // Drop the terminating NUL, convert to UTF-16.
> - //
> - KernelLoadedImage->LoadOptionsSize = (CommandLineBlob->Size - 1) * 2;
> - }
> -
> - if (InitrdBlob->Data != NULL) {
> - //
> - // Append ' initrd=<name>' in UTF-16.
> - //
> - KernelLoadedImage->LoadOptionsSize +=
> - (8 + StrLen(InitrdBlob->Name)) * 2;
> - }
> -
> - if (KernelLoadedImage->LoadOptionsSize == 0) {
> - KernelLoadedImage->LoadOptions = NULL;
> - } else {
> - //
> - // NUL-terminate in UTF-16.
> - //
> - KernelLoadedImage->LoadOptionsSize += 2;
> -
> - KernelLoadedImage->LoadOptions = AllocatePool (
> - KernelLoadedImage->LoadOptionsSize);
> - if (KernelLoadedImage->LoadOptions == NULL) {
> - KernelLoadedImage->LoadOptionsSize = 0;
> - Status = EFI_OUT_OF_RESOURCES;
> - goto UnloadKernelImage;
> - }
> -
> - UnicodeSPrintAsciiFormat (
> - KernelLoadedImage->LoadOptions,
> - KernelLoadedImage->LoadOptionsSize,
> - "%a%a%s",
> - (CommandLineBlob->Data == NULL) ? "" : (CHAR8 *)CommandLineBlob->Data,
> - (InitrdBlob->Data == NULL) ? "" : " initrd=",
> - (InitrdBlob->Data == NULL) ? L"" : InitrdBlob->Name
> - );
> - DEBUG ((EFI_D_INFO, "%a: command line: \"%s\"\n", __FUNCTION__,
> - (CHAR16 *)KernelLoadedImage->LoadOptions));
> - }
> -
> //
> // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event.
> //
> @@ -1080,41 +59,13 @@ TryRunningQemuKernel (
> //
> // Start the image.
> //
> - Status = gBS->StartImage (
> - KernelImageHandle,
> - NULL, // ExitDataSize
> - NULL // ExitData
> - );
> + Status = QemuStartKernelImage (&KernelImageHandle);
> if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "%a: StartImage(): %r\n", __FUNCTION__, Status));
> + DEBUG ((DEBUG_ERROR, "%a: QemuStartKernelImage(): %r\n", __FUNCTION__,
> + Status));
> }
>
> - if (KernelLoadedImage->LoadOptions != NULL) {
> - FreePool (KernelLoadedImage->LoadOptions);
> - }
> - KernelLoadedImage->LoadOptionsSize = 0;
> -
> -UnloadKernelImage:
> - gBS->UnloadImage (KernelImageHandle);
> -
> -FreeKernelDevicePath:
> - FreePool (KernelDevicePath);
> -
> -UninstallProtocols:
> - gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,
> - &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
> - &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,
> - NULL);
> -
> -FreeBlobs:
> - while (BlobType > 0) {
> - CurrentBlob = &mKernelBlob[--BlobType];
> - if (CurrentBlob->Data != NULL) {
> - FreePool (CurrentBlob->Data);
> - CurrentBlob->Size = 0;
> - CurrentBlob->Data = NULL;
> - }
> - }
> + QemuUnloadKernelImage (KernelImageHandle);
>
> return Status;
> }
>
next prev parent reply other threads:[~2020-03-05 10:01 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-04 9:52 [PATCH v2 00/14] Ovmf: use LoadImage/StartImage for loading command line images Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 01/14] OvmfPkg: add GUID for the QEMU kernel loader fs media device path Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 02/14] OvmfPkg: export abstract QEMU blob filesystem in standalone driver Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 03/14] OvmfPkg: introduce QemuLoadImageLib library class Ard Biesheuvel
2020-03-05 9:37 ` [edk2-devel] " Laszlo Ersek
2020-03-05 9:39 ` Laszlo Ersek
2020-03-05 10:22 ` Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 04/14] OvmfPkg: provide a generic implementation of QemuLoadImageLib Ard Biesheuvel
2020-03-05 9:51 ` [edk2-devel] " Laszlo Ersek
2020-03-05 11:29 ` Laszlo Ersek
2020-03-05 11:37 ` Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 05/14] ArmVirtPkg: incorporate the new QEMU kernel loader driver and library Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 06/14] ArmVirtPkg/PlatformBootManagerLib: switch to separate QEMU loader Ard Biesheuvel
2020-03-05 10:01 ` Laszlo Ersek [this message]
2020-03-04 9:52 ` [PATCH v2 07/14] OvmfPkg/QemuKernelLoaderFsDxe: don't expose kernel command line Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 08/14] OvmfPkg/QemuKernelLoaderFsDxe: add support for the kernel setup block Ard Biesheuvel
2020-03-05 10:12 ` [edk2-devel] " Laszlo Ersek
2020-03-04 9:52 ` [PATCH v2 09/14] OvmfPkg: create protocol and GUID header for legacy loaded images Ard Biesheuvel
2020-03-05 10:31 ` [edk2-devel] " Laszlo Ersek
2020-03-05 10:40 ` Ard Biesheuvel
2020-03-05 14:29 ` Laszlo Ersek
2020-03-04 9:52 ` [PATCH v2 10/14] OvmfPkg: implement QEMU loader library for X86 with legacy fallback Ard Biesheuvel
2020-03-05 12:33 ` [edk2-devel] " Laszlo Ersek
2020-03-04 9:52 ` [PATCH v2 11/14] OvmfPkg: add new QEMU kernel image loader components Ard Biesheuvel
2020-03-04 9:52 ` [PATCH v2 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib Ard Biesheuvel
2020-03-05 12:57 ` [edk2-devel] " Laszlo Ersek
2020-03-04 9:52 ` [PATCH v2 13/14] OvmfPkg/QemuKernelLoaderFsDxe: add support for new Linux initrd device path Ard Biesheuvel
2020-03-05 13:19 ` Laszlo Ersek
2020-03-04 9:52 ` [PATCH v2 14/14] OvmfPkg: use generic QEMU image loader for secure boot enabled builds Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55629ce8-f016-d6bb-b0e6-c3739bb9d2cc@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox