From a914063cdd845dbc67bf3d53aaf0829c576e53ff Mon Sep 17 00:00:00 2001 From: John Starks Date: Sat, 23 May 2026 16:09:01 -0700 Subject: [PATCH] Add config blob RAM disk registration for direct kernel boot Add a mechanism for the host to declare RAM disk(s) in the config blob, which the firmware registers via EFI_RAM_DISK_PROTOCOL during DXE. This makes them available as SimpleFileSystem volumes that BDS can boot from via standard Boot####/BootOrder variables (which the host also controls via NVRAM). The implementation consists of: - A new config blob structure type (UefiConfigRamDisk = 0x29) containing the GPA and size of a RAM disk image. Multiple instances are supported. - PEI parsing in Config.c that validates each entry, marks the memory as allocated boot services data (so DXE won't use it), and creates a GUIDed HOB for DXE to consume. - A new DXE driver (RamDiskConfigDxe) that enumerates the HOBs and calls EFI_RAM_DISK_PROTOCOL.Register() for each entry. The existing driver stack (DiskIoDxe, PartitionDxe, Fat.inf) then exposes the volumes. The driver is intentionally minimal -- all boot policy is handled by the host via NVRAM Boot#### variables. The firmware just makes the volumes available. --- MsvmPkg/Include/BiosInterface.h | 14 +++ MsvmPkg/Include/RamDiskConfigHob.h | 31 ++++++ MsvmPkg/MsvmPkg.dec | 5 + MsvmPkg/MsvmPkgAARCH64.dsc | 1 + MsvmPkg/MsvmPkgAARCH64.fdf | 1 + MsvmPkg/MsvmPkgX64.dsc | 1 + MsvmPkg/MsvmPkgX64.fdf | 1 + MsvmPkg/PlatformPei/Config.c | 54 +++++++++++ MsvmPkg/PlatformPei/PlatformPei.inf | 1 + MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.c | 94 +++++++++++++++++++ MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf | 40 ++++++++ 11 files changed, 243 insertions(+) create mode 100644 MsvmPkg/Include/RamDiskConfigHob.h create mode 100644 MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.c create mode 100644 MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf diff --git a/MsvmPkg/Include/BiosInterface.h b/MsvmPkg/Include/BiosInterface.h index 72e6d6f9ec..bd43b26bb6 100644 --- a/MsvmPkg/Include/BiosInterface.h +++ b/MsvmPkg/Include/BiosInterface.h @@ -559,6 +559,7 @@ enum UefiStructureType UefiConfigHmat = 0x26, UefiConfigIort = 0x27, UefiConfigPcieBarApertures = 0x28, + UefiConfigRamDisk = 0x29, }; // @@ -905,6 +906,19 @@ typedef struct _UEFI_CONFIG_PCIE_BAR_APERTURES { PCIE_BAR_APERTURE_ENTRY Entries[]; } UEFI_CONFIG_PCIE_BAR_APERTURES; +typedef struct _UEFI_CONFIG_RAM_DISK +{ + UEFI_CONFIG_HEADER Header; + // + // GPA of the RAM disk image (must be page-aligned). + // + UINT64 RamDiskGpa; + // + // Size in bytes of the RAM disk image (must be page-aligned). + // + UINT64 RamDiskSize; +} UEFI_CONFIG_RAM_DISK; + // // UEFI configuration information for direct parsing of IGVM parameters. // diff --git a/MsvmPkg/Include/RamDiskConfigHob.h b/MsvmPkg/Include/RamDiskConfigHob.h new file mode 100644 index 0000000000..8ac594d299 --- /dev/null +++ b/MsvmPkg/Include/RamDiskConfigHob.h @@ -0,0 +1,31 @@ +/** @file + Shared definitions for RAM disk configuration HOBs passed from PEI to DXE. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#pragma once + +#include +#include + +// +// GUID used to identify RAM disk configuration HOBs. +// Each HOB with this GUID contains a RAM_DISK_CONFIG_HOB_DATA structure +// describing a RAM disk region that should be registered via +// EFI_RAM_DISK_PROTOCOL during DXE. +// +#define MSVM_RAM_DISK_CONFIG_HOB_GUID \ + { 0xa41d6c49, 0xaf34, 0x4e34, { 0xa0, 0xb3, 0x12, 0x9a, 0x48, 0x66, 0x70, 0xcd } } + +extern EFI_GUID gMsvmRamDiskConfigHobGuid; + +// +// HOB payload: describes a RAM disk region to register. +// +typedef struct { + EFI_PHYSICAL_ADDRESS RamDiskGpa; + UINT64 RamDiskSize; +} RAM_DISK_CONFIG_HOB_DATA; diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index c22cfb60f7..d8ca096a0a 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -46,6 +46,11 @@ # gAcpiReplacementTableHobGuid = {0xa24aef4c, 0xa824, 0x48e9, {0xb5, 0xb8, 0xbc, 0xd9, 0x6a, 0x59, 0x71, 0xaf}} + # + # HOB GUID for RAM disk configuration entries from the config blob + # + gMsvmRamDiskConfigHobGuid = {0xa41d6c49, 0xaf34, 0x4e34, {0xa0, 0xb3, 0x12, 0x9a, 0x48, 0x66, 0x70, 0xcd}} + # # MsvmPkg specific events # diff --git a/MsvmPkg/MsvmPkgAARCH64.dsc b/MsvmPkg/MsvmPkgAARCH64.dsc index 48dccb27c1..2fe4abe6ef 100644 --- a/MsvmPkg/MsvmPkgAARCH64.dsc +++ b/MsvmPkg/MsvmPkgAARCH64.dsc @@ -830,6 +830,7 @@ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf + MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf MdeModulePkg/Universal/Metronome/Metronome.inf diff --git a/MsvmPkg/MsvmPkgAARCH64.fdf b/MsvmPkg/MsvmPkgAARCH64.fdf index 9a5d459b51..c0709df857 100644 --- a/MsvmPkg/MsvmPkgAARCH64.fdf +++ b/MsvmPkg/MsvmPkgAARCH64.fdf @@ -199,6 +199,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf +INF MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf INF MdeModulePkg/Universal/Metronome/Metronome.inf diff --git a/MsvmPkg/MsvmPkgX64.dsc b/MsvmPkg/MsvmPkgX64.dsc index a62c04c226..870aef32f4 100644 --- a/MsvmPkg/MsvmPkgX64.dsc +++ b/MsvmPkg/MsvmPkgX64.dsc @@ -861,6 +861,7 @@ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf + MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf diff --git a/MsvmPkg/MsvmPkgX64.fdf b/MsvmPkg/MsvmPkgX64.fdf index 713c0d9ca7..565d181eae 100644 --- a/MsvmPkg/MsvmPkgX64.fdf +++ b/MsvmPkg/MsvmPkgX64.fdf @@ -242,6 +242,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf +INF MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index fbadf15987..1c2485d386 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "AllowNamelessAggregate.h" #include "AssignStruct.h" @@ -824,6 +825,13 @@ DebugDumpUefiConfigStruct( break; } + case UefiConfigRamDisk: + { + UEFI_CONFIG_RAM_DISK *ramDisk = (UEFI_CONFIG_RAM_DISK*) Header; + DEBUG((DEBUG_VERBOSE, "\tRamDisk GPA: 0x%lx Size: 0x%lx\n", ramDisk->RamDiskGpa, ramDisk->RamDiskSize)); + break; + } + default: DEBUG((DEBUG_VERBOSE, "\t!!! Unrecognized config structure type !!!\n")); break; @@ -1639,6 +1647,52 @@ Return Value: PcdSet32S(PcdPcieBarAperturesSize, dataSize)); break; } + + case UefiConfigRamDisk: + { + UEFI_CONFIG_RAM_DISK *ramDisk = (UEFI_CONFIG_RAM_DISK*) header; + + if (header->Length != sizeof(UEFI_CONFIG_RAM_DISK)) + { + DEBUG((DEBUG_ERROR, "*** Malformed RamDisk structure length\n")); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + + if (ramDisk->RamDiskGpa == 0 || ramDisk->RamDiskSize == 0) + { + DEBUG((DEBUG_ERROR, "*** RamDisk: GPA or Size is zero\n")); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + + if ((ramDisk->RamDiskGpa % EFI_PAGE_SIZE) != 0 || + (ramDisk->RamDiskSize % EFI_PAGE_SIZE) != 0) + { + DEBUG((DEBUG_ERROR, "*** RamDisk: GPA or Size not page-aligned\n")); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + + // + // Mark the RAM disk memory as allocated boot services data so + // the DXE allocator won't hand it out. + // + HobAddAllocatedMemoryRange(ramDisk->RamDiskGpa, ramDisk->RamDiskSize); + + // + // Create a GUIDed HOB for DXE to consume. + // + { + RAM_DISK_CONFIG_HOB_DATA hobData; + hobData.RamDiskGpa = ramDisk->RamDiskGpa; + hobData.RamDiskSize = ramDisk->RamDiskSize; + BuildGuidDataHob(&gMsvmRamDiskConfigHobGuid, + &hobData, + sizeof(hobData)); + } + + DEBUG((DEBUG_INFO, "RamDisk: registered HOB for GPA 0x%lx Size 0x%lx\n", + ramDisk->RamDiskGpa, ramDisk->RamDiskSize)); + break; + } } calculatedConfigSize += header->Length; diff --git a/MsvmPkg/PlatformPei/PlatformPei.inf b/MsvmPkg/PlatformPei/PlatformPei.inf index 445c7839ec..a75b13dcb3 100644 --- a/MsvmPkg/PlatformPei/PlatformPei.inf +++ b/MsvmPkg/PlatformPei/PlatformPei.inf @@ -77,6 +77,7 @@ gEfiMemoryTypeInformationGuid gMsvmDebuggerEnabledGuid gMsvmDebuggerKdnetBinaryGuid + gMsvmRamDiskConfigHobGuid [Guids.AARCH64] gArmTokenSpaceGuid diff --git a/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.c b/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.c new file mode 100644 index 0000000000..32c68f1f1b --- /dev/null +++ b/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.c @@ -0,0 +1,94 @@ +/** @file + DXE driver that registers RAM disks declared in the config blob. + + During PEI, the config blob parser creates GUIDed HOBs for each + UefiConfigRamDisk entry. This driver enumerates those HOBs and + registers each RAM disk via EFI_RAM_DISK_PROTOCOL so that the + volumes become available for BDS boot option processing. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** + Entry point for RamDiskConfigDxe. + + Enumerates RAM disk config HOBs and registers each RAM disk. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The driver completed successfully. + +**/ +EFI_STATUS +EFIAPI +RamDiskConfigDxeEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_RAM_DISK_PROTOCOL *RamDiskProtocol; + VOID *Hob; + UINTN Count; + + // + // Find the first RAM disk config HOB. If none exist, nothing to do. + // + Hob = GetFirstGuidHob (&gMsvmRamDiskConfigHobGuid); + if (Hob == NULL) { + DEBUG ((DEBUG_VERBOSE, "RamDiskConfigDxe: No RAM disk HOBs found\n")); + return EFI_SUCCESS; + } + + // + // Locate the RAM disk protocol. + // + Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID **)&RamDiskProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RamDiskConfigDxe: Failed to locate EFI_RAM_DISK_PROTOCOL: %r\n", Status)); + return Status; + } + + // + // Iterate over all RAM disk config HOBs and register each one. + // + Count = 0; + while (Hob != NULL) { + EFI_HOB_GUID_TYPE *GuidHob = (EFI_HOB_GUID_TYPE *)Hob; + RAM_DISK_CONFIG_HOB_DATA *Data = (RAM_DISK_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (GuidHob); + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + DEBUG ((DEBUG_INFO, "RamDiskConfigDxe: Registering RAM disk #%u at GPA 0x%lx, Size 0x%lx\n", + Count, Data->RamDiskGpa, Data->RamDiskSize)); + + Status = RamDiskProtocol->Register ( + Data->RamDiskGpa, + Data->RamDiskSize, + &gEfiVirtualDiskGuid, + NULL, + &DevicePath + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RamDiskConfigDxe: Failed to register RAM disk #%u: %r\n", Count, Status)); + } else { + DEBUG ((DEBUG_INFO, "RamDiskConfigDxe: RAM disk #%u registered successfully\n", Count)); + } + + Count++; + Hob = GetNextGuidHob (&gMsvmRamDiskConfigHobGuid, GET_NEXT_HOB (Hob)); + } + + DEBUG ((DEBUG_INFO, "RamDiskConfigDxe: Processed %u RAM disk(s)\n", Count)); + return EFI_SUCCESS; +} diff --git a/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf b/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf new file mode 100644 index 0000000000..a2b1ca4ce3 --- /dev/null +++ b/MsvmPkg/RamDiskConfigDxe/RamDiskConfigDxe.inf @@ -0,0 +1,40 @@ +## @file +# DXE driver that registers RAM disks declared in the config blob. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RamDiskConfigDxe + FILE_GUID = 4bcbeb49-b83c-41e0-9987-e09cd00d2467 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = RamDiskConfigDxeEntry + +[Sources] + RamDiskConfigDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MsvmPkg/MsvmPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + HobLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Guids] + gMsvmRamDiskConfigHobGuid + gEfiVirtualDiskGuid + +[Protocols] + gEfiRamDiskProtocolGuid + +[Depex] + gEfiRamDiskProtocolGuid