mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-30 17:14:07 +02:00
MdeModulePkg/Bds: Free resources after ram disk boot finishes
The resource free includes to un-register the ram disk device and free the memory occupied by the ram disk. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hpe.com>
This commit is contained in:
parent
026ede493c
commit
339ae051f6
@ -15,6 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include "InternalBm.h"
|
#include "InternalBm.h"
|
||||||
|
|
||||||
|
EFI_RAM_DISK_PROTOCOL *mRamDisk = NULL;
|
||||||
|
|
||||||
EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL;
|
EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL;
|
||||||
EFI_BOOT_MANAGER_LEGACY_BOOT mBmLegacyBoot = NULL;
|
EFI_BOOT_MANAGER_LEGACY_BOOT mBmLegacyBoot = NULL;
|
||||||
|
|
||||||
@ -1095,6 +1097,7 @@ BmMatchHttpBootDevicePath (
|
|||||||
@param LoadFileHandle The handle of LoadFile instance.
|
@param LoadFileHandle The handle of LoadFile instance.
|
||||||
@param FullPath Return the full device path pointing to the load option.
|
@param FullPath Return the full device path pointing to the load option.
|
||||||
@param FileSize Return the size of the load option.
|
@param FileSize Return the size of the load option.
|
||||||
|
@param RamDiskHandle Return the RAM Disk handle.
|
||||||
|
|
||||||
@return The load option buffer.
|
@return The load option buffer.
|
||||||
**/
|
**/
|
||||||
@ -1102,7 +1105,8 @@ VOID *
|
|||||||
BmGetFileBufferFromLoadFileSystem (
|
BmGetFileBufferFromLoadFileSystem (
|
||||||
IN EFI_HANDLE LoadFileHandle,
|
IN EFI_HANDLE LoadFileHandle,
|
||||||
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
|
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
|
||||||
OUT UINTN *FileSize
|
OUT UINTN *FileSize,
|
||||||
|
OUT EFI_HANDLE *RamDiskHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -1140,7 +1144,13 @@ BmGetFileBufferFromLoadFileSystem (
|
|||||||
FreePool (Handles);
|
FreePool (Handles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Index != HandleCount) {
|
if (Index == HandleCount) {
|
||||||
|
Handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*RamDiskHandle = Handle;
|
||||||
|
|
||||||
|
if (Handle != NULL) {
|
||||||
return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), FullPath, FileSize);
|
return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), FullPath, FileSize);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1148,6 +1158,114 @@ BmGetFileBufferFromLoadFileSystem (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the RAM Disk device path created by LoadFile.
|
||||||
|
|
||||||
|
@param FilePath The source file path.
|
||||||
|
|
||||||
|
@return Callee-to-free RAM Disk device path
|
||||||
|
**/
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *
|
||||||
|
BmGetRamDiskDevicePath (
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *Node;
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
|
||||||
|
Node = FilePath;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);
|
||||||
|
if (!EFI_ERROR (Status) &&
|
||||||
|
(DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (Node) == MEDIA_RAM_DISK_DP)
|
||||||
|
) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct the device path pointing to RAM Disk
|
||||||
|
//
|
||||||
|
Node = NextDevicePathNode (Node);
|
||||||
|
RamDiskDevicePath = DuplicateDevicePath (FilePath);
|
||||||
|
ASSERT (RamDiskDevicePath != NULL);
|
||||||
|
SetDevicePathEndNode ((VOID *) ((UINTN) RamDiskDevicePath + ((UINTN) Node - (UINTN) FilePath)));
|
||||||
|
return RamDiskDevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the buffer and buffer size occupied by the RAM Disk.
|
||||||
|
|
||||||
|
@param RamDiskDevicePath RAM Disk device path.
|
||||||
|
@param RamDiskSizeInPages Return RAM Disk size in pages.
|
||||||
|
|
||||||
|
@retval RAM Disk buffer.
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
BmGetRamDiskMemoryInfo (
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath,
|
||||||
|
OUT UINTN *RamDiskSizeInPages
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
UINT64 StartingAddr;
|
||||||
|
UINT64 EndingAddr;
|
||||||
|
|
||||||
|
ASSERT (RamDiskDevicePath != NULL);
|
||||||
|
|
||||||
|
*RamDiskSizeInPages = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the buffer occupied by RAM Disk.
|
||||||
|
//
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &RamDiskDevicePath, &Handle);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
ASSERT ((DevicePathType (RamDiskDevicePath) == MEDIA_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (RamDiskDevicePath) == MEDIA_RAM_DISK_DP));
|
||||||
|
StartingAddr = ReadUnaligned64 ((UINT64 *) ((MEDIA_RAM_DISK_DEVICE_PATH *) RamDiskDevicePath)->StartingAddr);
|
||||||
|
EndingAddr = ReadUnaligned64 ((UINT64 *) ((MEDIA_RAM_DISK_DEVICE_PATH *) RamDiskDevicePath)->EndingAddr);
|
||||||
|
*RamDiskSizeInPages = EFI_SIZE_TO_PAGES ((UINTN) (EndingAddr - StartingAddr + 1));
|
||||||
|
return (VOID *) (UINTN) StartingAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroy the RAM Disk.
|
||||||
|
|
||||||
|
The destroy operation includes to call RamDisk.Unregister to
|
||||||
|
unregister the RAM DISK from RAM DISK driver, free the memory
|
||||||
|
allocated for the RAM Disk.
|
||||||
|
|
||||||
|
@param RamDiskDevicePath RAM Disk device path.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
BmDestroyRamDisk (
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VOID *RamDiskBuffer;
|
||||||
|
UINTN RamDiskSizeInPages;
|
||||||
|
|
||||||
|
ASSERT (RamDiskDevicePath != NULL);
|
||||||
|
|
||||||
|
RamDiskBuffer = BmGetRamDiskMemoryInfo (RamDiskDevicePath, &RamDiskSizeInPages);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy RAM Disk.
|
||||||
|
//
|
||||||
|
if (mRamDisk == NULL) {
|
||||||
|
Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID *) &mRamDisk);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
Status = mRamDisk->Unregister (RamDiskDevicePath);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
FreePages (RamDiskBuffer, RamDiskSizeInPages);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the file buffer from the specified Load File instance.
|
Get the file buffer from the specified Load File instance.
|
||||||
|
|
||||||
@ -1160,7 +1278,7 @@ BmGetFileBufferFromLoadFileSystem (
|
|||||||
**/
|
**/
|
||||||
VOID *
|
VOID *
|
||||||
BmGetFileBufferFromLoadFile (
|
BmGetFileBufferFromLoadFile (
|
||||||
EFI_HANDLE LoadFileHandle,
|
IN EFI_HANDLE LoadFileHandle,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||||
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
|
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
|
||||||
OUT UINTN *FileSize
|
OUT UINTN *FileSize
|
||||||
@ -1170,6 +1288,7 @@ BmGetFileBufferFromLoadFile (
|
|||||||
EFI_LOAD_FILE_PROTOCOL *LoadFile;
|
EFI_LOAD_FILE_PROTOCOL *LoadFile;
|
||||||
VOID *FileBuffer;
|
VOID *FileBuffer;
|
||||||
BOOLEAN LoadFileSystem;
|
BOOLEAN LoadFileSystem;
|
||||||
|
EFI_HANDLE RamDiskHandle;
|
||||||
UINTN BufferSize;
|
UINTN BufferSize;
|
||||||
|
|
||||||
*FileSize = 0;
|
*FileSize = 0;
|
||||||
@ -1208,7 +1327,13 @@ BmGetFileBufferFromLoadFile (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LoadFileSystem) {
|
if (LoadFileSystem) {
|
||||||
FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize);
|
FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize, &RamDiskHandle);
|
||||||
|
if (FileBuffer == NULL) {
|
||||||
|
//
|
||||||
|
// If there is no bootable executable in the populated
|
||||||
|
//
|
||||||
|
BmDestroyRamDisk (DevicePathFromHandle (RamDiskHandle));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*FileSize = BufferSize;
|
*FileSize = BufferSize;
|
||||||
*FullPath = DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));
|
*FullPath = DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));
|
||||||
@ -1436,6 +1561,7 @@ EfiBootManagerBoot (
|
|||||||
UINTN OriginalOptionNumber;
|
UINTN OriginalOptionNumber;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *Node;
|
EFI_DEVICE_PATH_PROTOCOL *Node;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
|
||||||
EFI_HANDLE FvHandle;
|
EFI_HANDLE FvHandle;
|
||||||
VOID *FileBuffer;
|
VOID *FileBuffer;
|
||||||
UINTN FileSize;
|
UINTN FileSize;
|
||||||
@ -1516,10 +1642,14 @@ EfiBootManagerBoot (
|
|||||||
//
|
//
|
||||||
// 5. Load EFI boot option to ImageHandle
|
// 5. Load EFI boot option to ImageHandle
|
||||||
//
|
//
|
||||||
ImageHandle = NULL;
|
ImageHandle = NULL;
|
||||||
|
RamDiskDevicePath = NULL;
|
||||||
if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {
|
if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {
|
||||||
Status = EFI_NOT_FOUND;
|
Status = EFI_NOT_FOUND;
|
||||||
FileBuffer = BmGetLoadOptionBuffer (BootOption->FilePath, &FilePath, &FileSize);
|
FileBuffer = BmGetLoadOptionBuffer (BootOption->FilePath, &FilePath, &FileSize);
|
||||||
|
if (FileBuffer != NULL) {
|
||||||
|
RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath);
|
||||||
|
}
|
||||||
DEBUG_CODE (
|
DEBUG_CODE (
|
||||||
if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath, GetDevicePathSize (FilePath)) != 0) {
|
if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath, GetDevicePathSize (FilePath)) != 0) {
|
||||||
DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: "));
|
DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: "));
|
||||||
@ -1556,6 +1686,13 @@ EfiBootManagerBoot (
|
|||||||
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
|
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
|
||||||
);
|
);
|
||||||
BootOption->Status = Status;
|
BootOption->Status = Status;
|
||||||
|
//
|
||||||
|
// Destroy the RAM disk
|
||||||
|
//
|
||||||
|
if (RamDiskDevicePath != NULL) {
|
||||||
|
BmDestroyRamDisk (RamDiskDevicePath);
|
||||||
|
FreePool (RamDiskDevicePath);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1651,6 +1788,14 @@ EfiBootManagerBoot (
|
|||||||
}
|
}
|
||||||
PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);
|
PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy the RAM disk
|
||||||
|
//
|
||||||
|
if (RamDiskDevicePath != NULL) {
|
||||||
|
BmDestroyRamDisk (RamDiskDevicePath);
|
||||||
|
FreePool (RamDiskDevicePath);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clear the Watchdog Timer after the image returns
|
// Clear the Watchdog Timer after the image returns
|
||||||
//
|
//
|
||||||
|
@ -43,6 +43,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Protocol/DriverHealth.h>
|
#include <Protocol/DriverHealth.h>
|
||||||
#include <Protocol/FormBrowser2.h>
|
#include <Protocol/FormBrowser2.h>
|
||||||
#include <Protocol/VariableLock.h>
|
#include <Protocol/VariableLock.h>
|
||||||
|
#include <Protocol/RamDisk.h>
|
||||||
|
|
||||||
#include <Guid/ZeroGuid.h>
|
#include <Guid/ZeroGuid.h>
|
||||||
#include <Guid/MemoryTypeInformation.h>
|
#include <Guid/MemoryTypeInformation.h>
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiDriverHealthProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiDriverHealthProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES
|
||||||
|
Loading…
x
Reference in New Issue
Block a user