Skip to content

Commit fdef7c4

Browse files
committed
UefiPayloadPkg: BlSupportDxe support for installing a UEFI ramdisk from kexec or other bootloader
Signed-off-by: Trammell Hudson <[email protected]>
1 parent f9b981e commit fdef7c4

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

UefiPayloadPkg/BlSupportDxe/BlSupportDxe.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
**/
99
#include "BlSupportDxe.h"
1010

11+
#include <Protocol/DevicePath.h>
12+
#include <Library/DevicePathLib.h>
13+
#include <Protocol/RamDisk.h>
14+
#include <Library/MemoryAllocationLib.h>
15+
1116
/**
1217
Reserve MMIO/IO resource in GCD
1318
@@ -80,6 +85,60 @@ ReserveResourceInGcd (
8085
}
8186

8287

88+
static void EFIAPI ramdisk_callback(EFI_EVENT event, void * context)
89+
{
90+
const SYSTEM_TABLE_INFO *SystemTableInfo = context;
91+
const unsigned char * ramdisk_base = (const void*) SystemTableInfo->RamDiskBase;
92+
const UINTN ramdisk_size = SystemTableInfo->RamDiskSize;
93+
94+
if (!ramdisk_base || !ramdisk_size)
95+
return;
96+
97+
EFI_STATUS Status;
98+
EFI_RAM_DISK_PROTOCOL *RamDisk;
99+
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
100+
EFI_GUID *RamDiskType = &gEfiVirtualDiskGuid;
101+
102+
Status = gBS->LocateProtocol(&gEfiRamDiskProtocolGuid, NULL, (VOID**) &RamDisk);
103+
// if there is no protocol, we've been signalled too early. we'll try again later
104+
if (EFI_ERROR (Status))
105+
return;
106+
107+
// it is necessary to copy the ramdisk from the kexec allocated memory to uefi allocated
108+
// memory. otherwise the memory will be reclaimed during the boot process, leading to
109+
// a corrupt BCD hive or other propblems.
110+
const unsigned char * ramdisk_copy = AllocateCopyPool(ramdisk_size, (const void*) ramdisk_base);
111+
if (!ramdisk_copy)
112+
{
113+
DEBUG((EFI_D_ERROR, "allocate %d bytes for ramdisk copy failed\n", ramdisk_size));
114+
return;
115+
}
116+
117+
/*
118+
for(int i = 0x200 ; i < 0x240 ; i++)
119+
DEBUG ((EFI_D_INFO, "%02x", ramdisk_base[i]));
120+
DEBUG ((EFI_D_INFO, "\n"));
121+
*/
122+
123+
Status = RamDisk->Register(
124+
(UINTN) ramdisk_copy,
125+
ramdisk_size,
126+
RamDiskType,
127+
NULL,
128+
&DevicePath
129+
);
130+
131+
if (EFI_ERROR (Status)) {
132+
DEBUG ((EFI_D_ERROR, "ramdisk_setup: Failed to register RAM Disk - %r\n", Status));
133+
return;
134+
}
135+
136+
VOID * Temp = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
137+
DEBUG ((EFI_D_INFO, "ramdisk_setup: ram disk %p + %x: device path %S\n", ramdisk_copy, ramdisk_size, Temp));
138+
FreePool(Temp);
139+
}
140+
141+
83142
/**
84143
Main entry for the bootloader support DXE module.
85144
@@ -180,5 +239,16 @@ BlDxeEntryPoint (
180239
ASSERT_EFI_ERROR (Status);
181240
}
182241

242+
// Wait for the RamDiskProtocol to become available
243+
static EFI_EVENT ramdisk_event;
244+
static void * ramdisk_registration;
245+
246+
Status = gBS->CreateEvent(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, ramdisk_callback, SystemTableInfo, &ramdisk_event);
247+
ASSERT_EFI_ERROR(Status);
248+
Status = gBS->RegisterProtocolNotify(&gEfiRamDiskProtocolGuid, ramdisk_event, &ramdisk_registration);
249+
ASSERT_EFI_ERROR(Status);
250+
Status = gBS->SignalEvent(ramdisk_event);
251+
ASSERT_EFI_ERROR(Status);
252+
183253
return EFI_SUCCESS;
184254
}

UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
BaseMemoryLib
4141
UefiLib
4242
HobLib
43+
DevicePathLib
4344

4445
[Guids]
4546
gEfiAcpiTableGuid
@@ -48,6 +49,10 @@
4849
gUefiSystemTableInfoGuid
4950
gUefiAcpiBoardInfoGuid
5051
gEfiGraphicsInfoHobGuid
52+
gEfiVirtualDiskGuid ## CONSUMES
53+
54+
[Protocols]
55+
gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES
5156

5257
[Pcd]
5358
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution

0 commit comments

Comments
 (0)