#include <Guid/FileInfo.h>\r
#include <Guid/FileSystemInfo.h>\r
#include <Guid/FileSystemVolumeLabelInfo.h>\r
+#include <Guid/LinuxEfiInitrdMedia.h>\r
#include <Guid/QemuKernelLoaderFsMedia.h>\r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/QemuFwCfgLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/UefiRuntimeServicesTableLib.h>\r
#include <Protocol/DevicePath.h>\r
+#include <Protocol/LoadFile2.h>\r
#include <Protocol/SimpleFileSystem.h>\r
\r
//\r
}\r
};\r
\r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mInitrdDevicePath = {\r
+ {\r
+ {\r
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
+ { sizeof (VENDOR_DEVICE_PATH) }\r
+ },\r
+ LINUX_EFI_INITRD_MEDIA_GUID\r
+ }, {\r
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
+ }\r
+};\r
+\r
//\r
// The "file in the EFI stub filesystem" abstraction.\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
/**\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
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
+ );\r
\r
/**\r
Closes a specified file handle.\r
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
+ 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
\r
//\r
// Protocol member functions for SimpleFileSystem.\r
StubFileSystemOpenVolume\r
};\r
\r
+STATIC\r
+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
+ )\r
+{\r
+ CONST KERNEL_BLOB *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];\r
+\r
+ ASSERT (InitrdBlob->Size > 0);\r
+\r
+ if (BootPolicy) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\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
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (Buffer == NULL || *BufferSize < InitrdBlob->Size) {\r
+ *BufferSize = InitrdBlob->Size;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ CopyMem (Buffer, InitrdBlob->Data, InitrdBlob->Size);\r
+\r
+ *BufferSize = InitrdBlob->Size;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC CONST EFI_LOAD_FILE2_PROTOCOL mInitrdLoadFile2 = {\r
+ InitrdLoadFile2,\r
+};\r
\r
//\r
// Utility functions.\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
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
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
+ __FUNCTION__, Status));\r
+ goto UninstallFileSystemHandle;\r
+ }\r
+ }\r
+\r
return EFI_SUCCESS;\r
\r
+UninstallFileSystemHandle:\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,\r
+ &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,\r
+ &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,\r
+ NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
FreeBlobs:\r
while (BlobType > 0) {\r
CurrentBlob = &mKernelBlob[--BlobType];\r