]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
UefiPayloadPkg: Fix build error
[mirror_edk2.git] / OvmfPkg / QemuKernelLoaderFsDxe / QemuKernelLoaderFsDxe.c
index 869549f164f0d523b8d562fc190633b32e7f6a6e..d4f3cd92255ffcfa0dc26c371bd00c44af260530 100644 (file)
@@ -17,6 +17,7 @@
 #include <Guid/QemuKernelLoaderFsMedia.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/BlobVerifierLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/DevicePathLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 typedef enum {\r
   KernelBlobTypeKernel,\r
   KernelBlobTypeInitrd,\r
+  KernelBlobTypeCommandLine,\r
   KernelBlobTypeMax\r
 } KERNEL_BLOB_TYPE;\r
 \r
 typedef struct {\r
-  CONST CHAR16                  Name[8];\r
+  CONST CHAR16    Name[8];\r
   struct {\r
-    FIRMWARE_CONFIG_ITEM CONST  SizeKey;\r
-    FIRMWARE_CONFIG_ITEM CONST  DataKey;\r
-    UINT32                      Size;\r
+    FIRMWARE_CONFIG_ITEM CONST    SizeKey;\r
+    FIRMWARE_CONFIG_ITEM CONST    DataKey;\r
+    UINT32                        Size;\r
   }                             FwCfgItem[2];\r
-  UINT32                        Size;\r
-  UINT8                         *Data;\r
+  UINT32          Size;\r
+  UINT8           *Data;\r
 } KERNEL_BLOB;\r
 \r
-STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {\r
+STATIC KERNEL_BLOB  mKernelBlob[KernelBlobTypeMax] = {\r
   {\r
     L"kernel",\r
     {\r
       { QemuFwCfgItemKernelSetupSize, QemuFwCfgItemKernelSetupData, },\r
       { QemuFwCfgItemKernelSize,      QemuFwCfgItemKernelData,      },\r
     }\r
-  }, {\r
+  },  {\r
     L"initrd",\r
     {\r
       { QemuFwCfgItemInitrdSize,      QemuFwCfgItemInitrdData,      },\r
     }\r
+  },  {\r
+    L"cmdline",\r
+    {\r
+      { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, },\r
+    }\r
   }\r
 };\r
 \r
-STATIC UINT64 mTotalBlobBytes;\r
+STATIC UINT64  mTotalBlobBytes;\r
 \r
 //\r
 // Device path for the handle that incorporates our "EFI stub filesystem".\r
 //\r
 #pragma pack (1)\r
 typedef struct {\r
-  VENDOR_DEVICE_PATH       VenMediaNode;\r
-  EFI_DEVICE_PATH_PROTOCOL EndNode;\r
+  VENDOR_DEVICE_PATH          VenMediaNode;\r
+  EFI_DEVICE_PATH_PROTOCOL    EndNode;\r
 } SINGLE_VENMEDIA_NODE_DEVPATH;\r
 #pragma pack ()\r
 \r
-STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mFileSystemDevicePath = {\r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH  mFileSystemDevicePath = {\r
   {\r
     {\r
       MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
-      { sizeof (VENDOR_DEVICE_PATH) }\r
+      { sizeof (VENDOR_DEVICE_PATH)       }\r
     },\r
     QEMU_KERNEL_LOADER_FS_MEDIA_GUID\r
-  }, {\r
+  },  {\r
     END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
     { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
   }\r
 };\r
 \r
-STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mInitrdDevicePath = {\r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH  mInitrdDevicePath = {\r
   {\r
     {\r
       MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
-      { sizeof (VENDOR_DEVICE_PATH) }\r
+      { sizeof (VENDOR_DEVICE_PATH)       }\r
     },\r
     LINUX_EFI_INITRD_MEDIA_GUID\r
-  }, {\r
+  },  {\r
     END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
     { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
   }\r
@@ -103,33 +110,26 @@ STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mInitrdDevicePath = {
 //\r
 // The "file in the EFI stub filesystem" abstraction.\r
 //\r
-STATIC EFI_TIME mInitTime;\r
+STATIC EFI_TIME  mInitTime;\r
 \r
-#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')\r
+#define STUB_FILE_SIG  SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')\r
 \r
 typedef struct {\r
-  UINT64            Signature; // Carries STUB_FILE_SIG.\r
+  UINT64               Signature; // Carries STUB_FILE_SIG.\r
 \r
-  KERNEL_BLOB_TYPE  BlobType;  // Index into mKernelBlob. KernelBlobTypeMax\r
-                               // denotes the root directory of the filesystem.\r
+  KERNEL_BLOB_TYPE     BlobType; // Index into mKernelBlob. KernelBlobTypeMax\r
+                                 // denotes the root directory of the filesystem.\r
 \r
-  UINT64            Position;  // Byte position for regular files;\r
-                               // next directory entry to return for the root\r
-                               // directory.\r
+  UINT64               Position; // Byte position for regular files;\r
+                                 // next directory entry to return for the root\r
+                                 // directory.\r
 \r
-  EFI_FILE_PROTOCOL File;      // Standard protocol interface.\r
+  EFI_FILE_PROTOCOL    File;   // Standard protocol interface.\r
 } STUB_FILE;\r
 \r
 #define STUB_FILE_FROM_FILE(FilePointer) \\r
         CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG)\r
 \r
-//\r
-// Tentative definition of the file protocol template. The initializer\r
-// (external definition) will be provided later.\r
-//\r
-STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate;\r
-\r
-\r
 //\r
 // Protocol member functions for File.\r
 //\r
@@ -137,6 +137,8 @@ STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate;
 /**\r
   Opens a new file relative to the source file's location.\r
 \r
+  (Forward declaration.)\r
+\r
   @param[in]  This        A pointer to the EFI_FILE_PROTOCOL instance that is\r
                           the file handle to the source location. This would\r
                           typically be an open handle to a directory.\r
@@ -176,70 +178,12 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileOpen (\r
-  IN EFI_FILE_PROTOCOL  *This,\r
-  OUT EFI_FILE_PROTOCOL **NewHandle,\r
-  IN CHAR16             *FileName,\r
-  IN UINT64             OpenMode,\r
-  IN UINT64             Attributes\r
-  )\r
-{\r
-  CONST STUB_FILE *StubFile;\r
-  UINTN           BlobType;\r
-  STUB_FILE       *NewStubFile;\r
-\r
-  //\r
-  // We're read-only.\r
-  //\r
-  switch (OpenMode) {\r
-    case EFI_FILE_MODE_READ:\r
-      break;\r
-\r
-    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
-    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
-      return EFI_WRITE_PROTECTED;\r
-\r
-    default:\r
-      return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Only the root directory supports opening files in it.\r
-  //\r
-  StubFile = STUB_FILE_FROM_FILE (This);\r
-  if (StubFile->BlobType != KernelBlobTypeMax) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Locate the file.\r
-  //\r
-  for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {\r
-    if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {\r
-      break;\r
-    }\r
-  }\r
-  if (BlobType == KernelBlobTypeMax) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Found it.\r
-  //\r
-  NewStubFile = AllocatePool (sizeof *NewStubFile);\r
-  if (NewStubFile == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  NewStubFile->Signature = STUB_FILE_SIG;\r
-  NewStubFile->BlobType  = (KERNEL_BLOB_TYPE)BlobType;\r
-  NewStubFile->Position  = 0;\r
-  CopyMem (&NewStubFile->File, &mEfiFileProtocolTemplate,\r
-    sizeof mEfiFileProtocolTemplate);\r
-  *NewHandle = &NewStubFile->File;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
+  IN EFI_FILE_PROTOCOL   *This,\r
+  OUT EFI_FILE_PROTOCOL  **NewHandle,\r
+  IN CHAR16              *FileName,\r
+  IN UINT64              OpenMode,\r
+  IN UINT64              Attributes\r
+  );\r
 \r
 /**\r
   Closes a specified file handle.\r
@@ -253,14 +197,13 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileClose (\r
-  IN EFI_FILE_PROTOCOL *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 {\r
   FreePool (STUB_FILE_FROM_FILE (This));\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Close and delete the file handle.\r
 \r
@@ -277,14 +220,13 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileDelete (\r
-  IN EFI_FILE_PROTOCOL *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 {\r
   FreePool (STUB_FILE_FROM_FILE (This));\r
   return EFI_WARN_DELETE_FAILURE;\r
 }\r
 \r
-\r
 /**\r
   Helper function that formats an EFI_FILE_INFO structure into the\r
   user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including\r
@@ -316,19 +258,19 @@ StubFileDelete (
 STATIC\r
 EFI_STATUS\r
 ConvertKernelBlobTypeToFileInfo (\r
-  IN KERNEL_BLOB_TYPE BlobType,\r
-  IN OUT UINTN        *BufferSize,\r
-  OUT VOID            *Buffer\r
+  IN KERNEL_BLOB_TYPE  BlobType,\r
+  IN OUT UINTN         *BufferSize,\r
+  OUT VOID             *Buffer\r
   )\r
 {\r
   CONST CHAR16  *Name;\r
   UINT64        FileSize;\r
   UINT64        Attribute;\r
 \r
-  UINTN         NameSize;\r
-  UINTN         FileInfoSize;\r
-  EFI_FILE_INFO *FileInfo;\r
-  UINTN         OriginalBufferSize;\r
+  UINTN          NameSize;\r
+  UINTN          FileInfoSize;\r
+  EFI_FILE_INFO  *FileInfo;\r
+  UINTN          OriginalBufferSize;\r
 \r
   if (BlobType == KernelBlobTypeMax) {\r
     //\r
@@ -338,7 +280,7 @@ ConvertKernelBlobTypeToFileInfo (
     FileSize  = KernelBlobTypeMax;\r
     Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;\r
   } else {\r
-    CONST KERNEL_BLOB *Blob;\r
+    CONST KERNEL_BLOB  *Blob;\r
 \r
     Blob      = &mKernelBlob[BlobType];\r
     Name      = Blob->Name;\r
@@ -346,7 +288,7 @@ ConvertKernelBlobTypeToFileInfo (
     Attribute = EFI_FILE_READ_ONLY;\r
   }\r
 \r
-  NameSize     = (StrLen(Name) + 1) * 2;\r
+  NameSize     = (StrLen (Name) + 1) * 2;\r
   FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize;\r
   ASSERT (FileInfoSize >= sizeof *FileInfo);\r
 \r
@@ -362,15 +304,14 @@ ConvertKernelBlobTypeToFileInfo (
   FileInfo->PhysicalSize = FileSize;\r
   FileInfo->Attribute    = Attribute;\r
 \r
-  CopyMem (&FileInfo->CreateTime,       &mInitTime, sizeof mInitTime);\r
-  CopyMem (&FileInfo->LastAccessTime,   &mInitTime, sizeof mInitTime);\r
+  CopyMem (&FileInfo->CreateTime, &mInitTime, sizeof mInitTime);\r
+  CopyMem (&FileInfo->LastAccessTime, &mInitTime, sizeof mInitTime);\r
   CopyMem (&FileInfo->ModificationTime, &mInitTime, sizeof mInitTime);\r
-  CopyMem (FileInfo->FileName,          Name,       NameSize);\r
+  CopyMem (FileInfo->FileName, Name, NameSize);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Reads data from a file, or continues scanning a directory.\r
 \r
@@ -409,14 +350,14 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileRead (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  IN OUT UINTN         *BufferSize,\r
-  OUT VOID             *Buffer\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN OUT UINTN          *BufferSize,\r
+  OUT VOID              *Buffer\r
   )\r
 {\r
-  STUB_FILE         *StubFile;\r
-  CONST KERNEL_BLOB *Blob;\r
-  UINT64            Left;\r
+  STUB_FILE          *StubFile;\r
+  CONST KERNEL_BLOB  *Blob;\r
+  UINT64             Left;\r
 \r
   StubFile = STUB_FILE_FROM_FILE (This);\r
 \r
@@ -424,7 +365,7 @@ StubFileRead (
   // Scanning the root directory?\r
   //\r
   if (StubFile->BlobType == KernelBlobTypeMax) {\r
-    EFI_STATUS Status;\r
+    EFI_STATUS  Status;\r
 \r
     if (StubFile->Position == KernelBlobTypeMax) {\r
       //\r
@@ -437,7 +378,8 @@ StubFileRead (
     Status = ConvertKernelBlobTypeToFileInfo (\r
                (KERNEL_BLOB_TYPE)StubFile->Position,\r
                BufferSize,\r
-               Buffer);\r
+               Buffer\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -458,14 +400,15 @@ StubFileRead (
   if (*BufferSize > Left) {\r
     *BufferSize = (UINTN)Left;\r
   }\r
+\r
   if (Blob->Data != NULL) {\r
     CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);\r
   }\r
+\r
   StubFile->Position += *BufferSize;\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Writes data to a file.\r
 \r
@@ -493,12 +436,12 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileWrite (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  IN OUT UINTN         *BufferSize,\r
-  IN VOID              *Buffer\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN OUT UINTN          *BufferSize,\r
+  IN VOID               *Buffer\r
   )\r
 {\r
-  STUB_FILE *StubFile;\r
+  STUB_FILE  *StubFile;\r
 \r
   StubFile = STUB_FILE_FROM_FILE (This);\r
   return (StubFile->BlobType == KernelBlobTypeMax) ?\r
@@ -506,7 +449,6 @@ StubFileWrite (
          EFI_WRITE_PROTECTED;\r
 }\r
 \r
-\r
 /**\r
   Returns a file's current position.\r
 \r
@@ -525,11 +467,11 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileGetPosition (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  OUT UINT64           *Position\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  OUT UINT64            *Position\r
   )\r
 {\r
-  STUB_FILE *StubFile;\r
+  STUB_FILE  *StubFile;\r
 \r
   StubFile = STUB_FILE_FROM_FILE (This);\r
   if (StubFile->BlobType == KernelBlobTypeMax) {\r
@@ -540,7 +482,6 @@ StubFileGetPosition (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Sets a file's current position.\r
 \r
@@ -561,12 +502,12 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileSetPosition (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  IN UINT64            Position\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN UINT64             Position\r
   )\r
 {\r
-  STUB_FILE   *StubFile;\r
-  KERNEL_BLOB *Blob;\r
+  STUB_FILE    *StubFile;\r
+  KERNEL_BLOB  *Blob;\r
 \r
   StubFile = STUB_FILE_FROM_FILE (This);\r
 \r
@@ -578,6 +519,7 @@ StubFileSetPosition (
       StubFile->Position = 0;\r
       return EFI_SUCCESS;\r
     }\r
+\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -596,10 +538,10 @@ StubFileSetPosition (
     //\r
     StubFile->Position = Position;\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Returns information about a file.\r
 \r
@@ -642,26 +584,29 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileGetInfo (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  IN EFI_GUID          *InformationType,\r
-  IN OUT UINTN         *BufferSize,\r
-  OUT VOID             *Buffer\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN EFI_GUID           *InformationType,\r
+  IN OUT UINTN          *BufferSize,\r
+  OUT VOID              *Buffer\r
   )\r
 {\r
-  CONST STUB_FILE *StubFile;\r
-  UINTN           OriginalBufferSize;\r
+  CONST STUB_FILE  *StubFile;\r
+  UINTN            OriginalBufferSize;\r
 \r
   StubFile = STUB_FILE_FROM_FILE (This);\r
 \r
   if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
-    return ConvertKernelBlobTypeToFileInfo (StubFile->BlobType, BufferSize,\r
-             Buffer);\r
+    return ConvertKernelBlobTypeToFileInfo (\r
+             StubFile->BlobType,\r
+             BufferSize,\r
+             Buffer\r
+             );\r
   }\r
 \r
   OriginalBufferSize = *BufferSize;\r
 \r
   if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
-    EFI_FILE_SYSTEM_INFO *FileSystemInfo;\r
+    EFI_FILE_SYSTEM_INFO  *FileSystemInfo;\r
 \r
     *BufferSize = sizeof *FileSystemInfo;\r
     if (OriginalBufferSize < *BufferSize) {\r
@@ -680,14 +625,14 @@ StubFileGetInfo (
   }\r
 \r
   if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
-    EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;\r
+    EFI_FILE_SYSTEM_VOLUME_LABEL  *FileSystemVolumeLabel;\r
 \r
     *BufferSize = sizeof *FileSystemVolumeLabel;\r
     if (OriginalBufferSize < *BufferSize) {\r
       return EFI_BUFFER_TOO_SMALL;\r
     }\r
 \r
-    FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;\r
+    FileSystemVolumeLabel                 = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;\r
     FileSystemVolumeLabel->VolumeLabel[0] = L'\0';\r
 \r
     return EFI_SUCCESS;\r
@@ -696,7 +641,6 @@ StubFileGetInfo (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
 /**\r
   Sets information about a file.\r
 \r
@@ -742,16 +686,15 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileSetInfo (\r
-  IN EFI_FILE_PROTOCOL *This,\r
-  IN EFI_GUID          *InformationType,\r
-  IN UINTN             BufferSize,\r
-  IN VOID              *Buffer\r
+  IN EFI_FILE_PROTOCOL  *This,\r
+  IN EFI_GUID           *InformationType,\r
+  IN UINTN              BufferSize,\r
+  IN VOID               *Buffer\r
   )\r
 {\r
   return EFI_WRITE_PROTECTED;\r
 }\r
 \r
-\r
 /**\r
   Flushes all modified data associated with a file to a device.\r
 \r
@@ -770,7 +713,7 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileFlush (\r
-  IN EFI_FILE_PROTOCOL *This\r
+  IN EFI_FILE_PROTOCOL  *This\r
   )\r
 {\r
   return EFI_WRITE_PROTECTED;\r
@@ -779,7 +722,7 @@ StubFileFlush (
 //\r
 // External definition of the file protocol template.\r
 //\r
-STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {\r
+STATIC CONST EFI_FILE_PROTOCOL  mEfiFileProtocolTemplate = {\r
   EFI_FILE_PROTOCOL_REVISION, // revision 1\r
   StubFileOpen,\r
   StubFileClose,\r
@@ -797,6 +740,77 @@ STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
   NULL                        // FlushEx, revision 2\r
 };\r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+StubFileOpen (\r
+  IN EFI_FILE_PROTOCOL   *This,\r
+  OUT EFI_FILE_PROTOCOL  **NewHandle,\r
+  IN CHAR16              *FileName,\r
+  IN UINT64              OpenMode,\r
+  IN UINT64              Attributes\r
+  )\r
+{\r
+  CONST STUB_FILE  *StubFile;\r
+  UINTN            BlobType;\r
+  STUB_FILE        *NewStubFile;\r
+\r
+  //\r
+  // We're read-only.\r
+  //\r
+  switch (OpenMode) {\r
+    case EFI_FILE_MODE_READ:\r
+      break;\r
+\r
+    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
+    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
+      return EFI_WRITE_PROTECTED;\r
+\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Only the root directory supports opening files in it.\r
+  //\r
+  StubFile = STUB_FILE_FROM_FILE (This);\r
+  if (StubFile->BlobType != KernelBlobTypeMax) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Locate the file.\r
+  //\r
+  for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {\r
+    if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (BlobType == KernelBlobTypeMax) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Found it.\r
+  //\r
+  NewStubFile = AllocatePool (sizeof *NewStubFile);\r
+  if (NewStubFile == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  NewStubFile->Signature = STUB_FILE_SIG;\r
+  NewStubFile->BlobType  = (KERNEL_BLOB_TYPE)BlobType;\r
+  NewStubFile->Position  = 0;\r
+  CopyMem (\r
+    &NewStubFile->File,\r
+    &mEfiFileProtocolTemplate,\r
+    sizeof mEfiFileProtocolTemplate\r
+    );\r
+  *NewHandle = &NewStubFile->File;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 //\r
 // Protocol member functions for SimpleFileSystem.\r
@@ -829,11 +843,11 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 StubFileSystemOpenVolume (\r
-  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
-  OUT EFI_FILE_PROTOCOL              **Root\r
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,\r
+  OUT EFI_FILE_PROTOCOL               **Root\r
   )\r
 {\r
-  STUB_FILE *StubFile;\r
+  STUB_FILE  *StubFile;\r
 \r
   StubFile = AllocatePool (sizeof *StubFile);\r
   if (StubFile == NULL) {\r
@@ -843,14 +857,17 @@ StubFileSystemOpenVolume (
   StubFile->Signature = STUB_FILE_SIG;\r
   StubFile->BlobType  = KernelBlobTypeMax;\r
   StubFile->Position  = 0;\r
-  CopyMem (&StubFile->File, &mEfiFileProtocolTemplate,\r
-    sizeof mEfiFileProtocolTemplate);\r
+  CopyMem (\r
+    &StubFile->File,\r
+    &mEfiFileProtocolTemplate,\r
+    sizeof mEfiFileProtocolTemplate\r
+    );\r
   *Root = &StubFile->File;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {\r
+STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  mFileSystem = {\r
   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,\r
   StubFileSystemOpenVolume\r
 };\r
@@ -859,14 +876,14 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 InitrdLoadFile2 (\r
-  IN      EFI_LOAD_FILE2_PROTOCOL       *This,\r
-  IN      EFI_DEVICE_PATH_PROTOCOL      *FilePath,\r
-  IN      BOOLEAN                       BootPolicy,\r
-  IN  OUT UINTN                         *BufferSize,\r
-  OUT     VOID                          *Buffer     OPTIONAL\r
+  IN      EFI_LOAD_FILE2_PROTOCOL   *This,\r
+  IN      EFI_DEVICE_PATH_PROTOCOL  *FilePath,\r
+  IN      BOOLEAN                   BootPolicy,\r
+  IN  OUT UINTN                     *BufferSize,\r
+  OUT     VOID                      *Buffer     OPTIONAL\r
   )\r
 {\r
-  CONST KERNEL_BLOB   *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];\r
+  CONST KERNEL_BLOB  *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];\r
 \r
   ASSERT (InitrdBlob->Size > 0);\r
 \r
@@ -874,16 +891,17 @@ InitrdLoadFile2 (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (BufferSize == NULL || !IsDevicePathValid (FilePath, 0)) {\r
+  if ((BufferSize == NULL) || !IsDevicePathValid (FilePath, 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (FilePath->Type != END_DEVICE_PATH_TYPE ||\r
-      FilePath->SubType != END_ENTIRE_DEVICE_PATH_SUBTYPE) {\r
+  if ((FilePath->Type != END_DEVICE_PATH_TYPE) ||\r
+      (FilePath->SubType != END_ENTIRE_DEVICE_PATH_SUBTYPE))\r
+  {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  if (Buffer == NULL || *BufferSize < InitrdBlob->Size) {\r
+  if ((Buffer == NULL) || (*BufferSize < InitrdBlob->Size)) {\r
     *BufferSize = InitrdBlob->Size;\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
@@ -894,7 +912,7 @@ InitrdLoadFile2 (
   return EFI_SUCCESS;\r
 }\r
 \r
-STATIC CONST EFI_LOAD_FILE2_PROTOCOL     mInitrdLoadFile2 = {\r
+STATIC CONST EFI_LOAD_FILE2_PROTOCOL  mInitrdLoadFile2 = {\r
   InitrdLoadFile2,\r
 };\r
 \r
@@ -917,12 +935,12 @@ STATIC CONST EFI_LOAD_FILE2_PROTOCOL     mInitrdLoadFile2 = {
 STATIC\r
 EFI_STATUS\r
 FetchBlob (\r
-  IN OUT KERNEL_BLOB *Blob\r
+  IN OUT KERNEL_BLOB  *Blob\r
   )\r
 {\r
-  UINT32 Left;\r
-  UINTN  Idx;\r
-  UINT8  *ChunkData;\r
+  UINT32  Left;\r
+  UINTN   Idx;\r
+  UINT8   *ChunkData;\r
 \r
   //\r
   // Read blob size.\r
@@ -932,10 +950,12 @@ FetchBlob (
     if (Blob->FwCfgItem[Idx].SizeKey == 0) {\r
       break;\r
     }\r
+\r
     QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].SizeKey);\r
     Blob->FwCfgItem[Idx].Size = QemuFwCfgRead32 ();\r
-    Blob->Size += Blob->FwCfgItem[Idx].Size;\r
+    Blob->Size               += Blob->FwCfgItem[Idx].Size;\r
   }\r
+\r
   if (Blob->Size == 0) {\r
     return EFI_SUCCESS;\r
   }\r
@@ -943,32 +963,49 @@ FetchBlob (
   //\r
   // Read blob.\r
   //\r
-  Blob->Data = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Blob->Size));\r
+  Blob->Data = AllocatePool (Blob->Size);\r
   if (Blob->Data == NULL) {\r
-    DEBUG ((DEBUG_ERROR, "%a: failed to allocate %Ld bytes for \"%s\"\n",\r
-      __FUNCTION__, (INT64)Blob->Size, Blob->Name));\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "%a: failed to allocate %Ld bytes for \"%s\"\n",\r
+      __FUNCTION__,\r
+      (INT64)Blob->Size,\r
+      Blob->Name\r
+      ));\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  DEBUG ((DEBUG_INFO, "%a: loading %Ld bytes for \"%s\"\n", __FUNCTION__,\r
-    (INT64)Blob->Size, Blob->Name));\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "%a: loading %Ld bytes for \"%s\"\n",\r
+    __FUNCTION__,\r
+    (INT64)Blob->Size,\r
+    Blob->Name\r
+    ));\r
 \r
   ChunkData = Blob->Data;\r
   for (Idx = 0; Idx < ARRAY_SIZE (Blob->FwCfgItem); Idx++) {\r
     if (Blob->FwCfgItem[Idx].DataKey == 0) {\r
       break;\r
     }\r
+\r
     QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].DataKey);\r
 \r
     Left = Blob->FwCfgItem[Idx].Size;\r
     while (Left > 0) {\r
-      UINT32 Chunk;\r
+      UINT32  Chunk;\r
 \r
       Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;\r
       QemuFwCfgReadBytes (Chunk, ChunkData + Blob->FwCfgItem[Idx].Size - Left);\r
       Left -= Chunk;\r
-      DEBUG ((DEBUG_VERBOSE, "%a: %Ld bytes remaining for \"%s\" (%d)\n",\r
-        __FUNCTION__, (INT64)Left, Blob->Name, (INT32)Idx));\r
+      DEBUG ((\r
+        DEBUG_VERBOSE,\r
+        "%a: %Ld bytes remaining for \"%s\" (%d)\n",\r
+        __FUNCTION__,\r
+        (INT64)Left,\r
+        Blob->Name,\r
+        (INT32)Idx\r
+        ));\r
     }\r
 \r
     ChunkData += Blob->FwCfgItem[Idx].Size;\r
@@ -977,7 +1014,6 @@ FetchBlob (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 //\r
 // The entry point of the feature.\r
 //\r
@@ -998,16 +1034,16 @@ FetchBlob (
 EFI_STATUS\r
 EFIAPI\r
 QemuKernelLoaderFsDxeEntrypoint (\r
-  IN EFI_HANDLE       ImageHandle,\r
-  IN EFI_SYSTEM_TABLE *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  UINTN                     BlobType;\r
-  KERNEL_BLOB               *CurrentBlob;\r
-  KERNEL_BLOB               *KernelBlob;\r
-  EFI_STATUS                Status;\r
-  EFI_HANDLE                FileSystemHandle;\r
-  EFI_HANDLE                InitrdLoadFile2Handle;\r
+  UINTN        BlobType;\r
+  KERNEL_BLOB  *CurrentBlob;\r
+  KERNEL_BLOB  *KernelBlob;\r
+  EFI_STATUS   Status;\r
+  EFI_HANDLE   FileSystemHandle;\r
+  EFI_HANDLE   InitrdLoadFile2Handle;\r
 \r
   if (!QemuFwCfgIsAvailable ()) {\r
     return EFI_NOT_FOUND;\r
@@ -1024,13 +1060,24 @@ QemuKernelLoaderFsDxeEntrypoint (
   //\r
   for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {\r
     CurrentBlob = &mKernelBlob[BlobType];\r
-    Status = FetchBlob (CurrentBlob);\r
+    Status      = FetchBlob (CurrentBlob);\r
     if (EFI_ERROR (Status)) {\r
       goto FreeBlobs;\r
     }\r
+\r
+    Status = VerifyBlob (\r
+               CurrentBlob->Name,\r
+               CurrentBlob->Data,\r
+               CurrentBlob->Size\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeBlobs;\r
+    }\r
+\r
     mTotalBlobBytes += CurrentBlob->Size;\r
   }\r
-  KernelBlob      = &mKernelBlob[KernelBlobTypeKernel];\r
+\r
+  KernelBlob = &mKernelBlob[KernelBlobTypeKernel];\r
 \r
   if (KernelBlob->Data == NULL) {\r
     Status = EFI_NOT_FOUND;\r
@@ -1042,25 +1089,41 @@ QemuKernelLoaderFsDxeEntrypoint (
   // it, plus a custom SimpleFileSystem protocol on it.\r
   //\r
   FileSystemHandle = NULL;\r
-  Status = gBS->InstallMultipleProtocolInterfaces (&FileSystemHandle,\r
-                  &gEfiDevicePathProtocolGuid,       &mFileSystemDevicePath,\r
-                  &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,\r
-                  NULL);\r
+  Status           = gBS->InstallMultipleProtocolInterfaces (\r
+                            &FileSystemHandle,\r
+                            &gEfiDevicePathProtocolGuid,\r
+                            &mFileSystemDevicePath,\r
+                            &gEfiSimpleFileSystemProtocolGuid,\r
+                            &mFileSystem,\r
+                            NULL\r
+                            );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
-      __FUNCTION__, Status));\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
+      __FUNCTION__,\r
+      Status\r
+      ));\r
     goto FreeBlobs;\r
   }\r
 \r
   if (KernelBlob[KernelBlobTypeInitrd].Size > 0) {\r
     InitrdLoadFile2Handle = NULL;\r
-    Status = gBS->InstallMultipleProtocolInterfaces (&InitrdLoadFile2Handle,\r
-                    &gEfiDevicePathProtocolGuid,  &mInitrdDevicePath,\r
-                    &gEfiLoadFile2ProtocolGuid,   &mInitrdLoadFile2,\r
-                    NULL);\r
+    Status                = gBS->InstallMultipleProtocolInterfaces (\r
+                                   &InitrdLoadFile2Handle,\r
+                                   &gEfiDevicePathProtocolGuid,\r
+                                   &mInitrdDevicePath,\r
+                                   &gEfiLoadFile2ProtocolGuid,\r
+                                   &mInitrdLoadFile2,\r
+                                   NULL\r
+                                   );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
-        __FUNCTION__, Status));\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
+        __FUNCTION__,\r
+        Status\r
+        ));\r
       goto UninstallFileSystemHandle;\r
     }\r
   }\r
@@ -1068,18 +1131,21 @@ QemuKernelLoaderFsDxeEntrypoint (
   return EFI_SUCCESS;\r
 \r
 UninstallFileSystemHandle:\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,\r
-                  &gEfiDevicePathProtocolGuid,       &mFileSystemDevicePath,\r
-                  &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,\r
-                  NULL);\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  FileSystemHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mFileSystemDevicePath,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &mFileSystem,\r
+                  NULL\r
+                  );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
 FreeBlobs:\r
   while (BlobType > 0) {\r
     CurrentBlob = &mKernelBlob[--BlobType];\r
     if (CurrentBlob->Data != NULL) {\r
-      FreePages (CurrentBlob->Data,\r
-        EFI_SIZE_TO_PAGES ((UINTN)CurrentBlob->Size));\r
+      FreePool (CurrentBlob->Data);\r
       CurrentBlob->Size = 0;\r
       CurrentBlob->Data = NULL;\r
     }\r