Reviewed-by: Fu Siyuan <siyuan...@intel.com> > -----Original Message----- > From: Ni, Ruiyu > Sent: Wednesday, March 30, 2016 8:29 AM > To: edk2-devel@lists.01.org > Cc: Ni, Ruiyu <ruiyu...@intel.com>; Fu, Siyuan <siyuan...@intel.com>; Tian, > Feng <feng.t...@intel.com> > Subject: [Patch v3 2/3] 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...@intel.com> > Cc: Siyuan Fu <siyuan...@intel.com> > Cc: Feng Tian <feng.t...@intel.com> > --- > MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c | 155 > ++++++++++++++++++++- > .../Library/UefiBootManagerLib/InternalBm.h | 1 + > .../UefiBootManagerLib/UefiBootManagerLib.inf | 1 + > 3 files changed, 153 insertions(+), 4 deletions(-) > > diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c > b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c > index 6e5c13b..598de26 100644 > --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c > +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c > @@ -1095,6 +1095,7 @@ BmMatchHttpBootDevicePath ( > @param LoadFileHandle The handle of LoadFile instance. > @param FullPath Return the full device path pointing to the load > option. > @param FileSize Return the size of the load option. > + @param RamDiskHandle Return the RAM Disk handle. > > @return The load option buffer. > **/ > @@ -1102,7 +1103,8 @@ VOID * > BmGetFileBufferFromLoadFileSystem ( > IN EFI_HANDLE LoadFileHandle, > OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, > - OUT UINTN *FileSize > + OUT UINTN *FileSize, > + OUT EFI_HANDLE *RamDiskHandle > ) > { > EFI_STATUS Status; > @@ -1140,7 +1142,13 @@ BmGetFileBufferFromLoadFileSystem ( > FreePool (Handles); > } > > - if (Index != HandleCount) { > + if (Index == HandleCount) { > + Handle = NULL; > + } > + > + *RamDiskHandle = Handle; > + > + if (Handle != NULL) { > return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), > FullPath, FileSize); > } else { > return NULL; > @@ -1149,6 +1157,124 @@ BmGetFileBufferFromLoadFileSystem ( > > > /** > + Return the RAM DISK handle created by LoadFile. > + > + @param FilePath The source file path. > + > + @return RAM DISK handle. > +**/ > +EFI_HANDLE > +BmGetLoadFileRamDisk ( > + 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))); > + > + // > + // Query the RAM Disk handle using the constructed device path. > + // > + Node = RamDiskDevicePath; > + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &Node, > &Handle); > + ASSERT ((Status == EFI_SUCCESS) && IsDevicePathEnd (Node)); > + FreePool (RamDiskDevicePath); > + return Handle; > + } > + > + return NULL; > +} > + > +/** > + Return the buffer and buffer size occupied by the RAM Disk. > + > + @param RamDiskHandle RAM Disk handle. > + @param RamDiskSizeInPages Return RAM Disk size in pages. > + > + @retval RAM Disk buffer. > +**/ > +VOID * > +BmGetRamDiskMemoryInfo ( > + EFI_HANDLE RamDiskHandle, > + UINTN *RamDiskSizeInPages > + ) > +{ > + > + EFI_STATUS Status; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + EFI_HANDLE Handle; > + UINT64 StartingAddr; > + UINT64 EndingAddr; > + > + *RamDiskSizeInPages = 0; > + if (RamDiskHandle == NULL) { > + return NULL; > + } > + DevicePath = DevicePathFromHandle (RamDiskHandle); > + > + // > + // Get the buffer occupied by RAM Disk. > + // > + Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePath, > &Handle); > + ASSERT_EFI_ERROR (Status); > + ASSERT ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && > (DevicePathSubType (DevicePath) == MEDIA_RAM_DISK_DP)); > + StartingAddr = ReadUnaligned64 ((UINT64 *) > ((MEDIA_RAM_DISK_DEVICE_PATH *) DevicePath)->StartingAddr); > + EndingAddr = ReadUnaligned64 ((UINT64 *) > ((MEDIA_RAM_DISK_DEVICE_PATH *) DevicePath)->EndingAddr); > + *RamDiskSizeInPages = EFI_SIZE_TO_PAGES ((UINTN) (EndingAddr - > StartingAddr + 1)); > + return (VOID *) (UINTN) StartingAddr; > +} > + > +/** > + Destroy the RAM Disk handle. > + > + 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 RamDiskHandle RAM Disk handle. > +**/ > +VOID > +BmDestroyRamDisk ( > + EFI_HANDLE RamDiskHandle > + ) > +{ > + EFI_STATUS Status; > + EFI_RAM_DISK_PROTOCOL *RamDisk; > + VOID *RamDiskBuffer; > + UINTN RamDiskSizeInPages; > + > + if (RamDiskHandle == NULL) { > + return; > + } > + RamDiskBuffer = BmGetRamDiskMemoryInfo (RamDiskHandle, > &RamDiskSizeInPages); > + > + // > + // Destroy RAM Disk. > + // > + Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID *) > &RamDisk); > + ASSERT_EFI_ERROR (Status); > + Status = RamDisk->Unregister (DevicePathFromHandle (RamDiskHandle)); > + ASSERT_EFI_ERROR (Status); > + FreePages (RamDiskBuffer, RamDiskSizeInPages); > +} > + > +/** > Get the file buffer from the specified Load File instance. > > @param LoadFileHandle The specified Load File instance. > @@ -1170,6 +1296,7 @@ BmGetFileBufferFromLoadFile ( > EFI_LOAD_FILE_PROTOCOL *LoadFile; > VOID *FileBuffer; > BOOLEAN LoadFileSystem; > + EFI_HANDLE RamDiskHandle; > UINTN BufferSize; > > *FileSize = 0; > @@ -1204,7 +1331,13 @@ BmGetFileBufferFromLoadFile ( > } > > 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 (RamDiskHandle); > + } > } else { > *FileSize = BufferSize; > *FullPath = DuplicateDevicePath (DevicePathFromHandle > (LoadFileHandle)); > @@ -1432,6 +1565,7 @@ EfiBootManagerBoot ( > UINTN OriginalOptionNumber; > EFI_DEVICE_PATH_PROTOCOL *FilePath; > EFI_DEVICE_PATH_PROTOCOL *Node; > + EFI_HANDLE RamDiskHandle; > EFI_HANDLE FvHandle; > VOID *FileBuffer; > UINTN FileSize; > @@ -1512,10 +1646,14 @@ EfiBootManagerBoot ( > // > // 5. Load EFI boot option to ImageHandle > // > - ImageHandle = NULL; > + ImageHandle = NULL; > + RamDiskHandle = NULL; > if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) { > Status = EFI_NOT_FOUND; > FileBuffer = BmGetLoadOptionBuffer (BootOption->FilePath, &FilePath, > &FileSize); > + if (FileBuffer != NULL) { > + RamDiskHandle = BmGetLoadFileRamDisk (FilePath); > + } > DEBUG_CODE ( > if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath, > GetDevicePathSize (FilePath)) != 0) { > DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: ")); > @@ -1552,6 +1690,10 @@ EfiBootManagerBoot ( > (EFI_SOFTWARE_DXE_BS_DRIVER | > EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) > ); > BootOption->Status = Status; > + // > + // Destroy the RAM disk > + // > + BmDestroyRamDisk (RamDiskHandle); > return; > } > } > @@ -1648,6 +1790,11 @@ EfiBootManagerBoot ( > PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) > OptionNumber); > > // > + // Destroy the RAM disk > + // > + BmDestroyRamDisk (RamDiskHandle); > + > + // > // Clear the Watchdog Timer after the image returns > // > gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); > diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h > b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h > index 7b6252a..4660323 100644 > --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h > +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h > @@ -43,6 +43,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > #include <Protocol/DriverHealth.h> > #include <Protocol/FormBrowser2.h> > #include <Protocol/VariableLock.h> > +#include <Protocol/RamDisk.h> > > #include <Guid/ZeroGuid.h> > #include <Guid/MemoryTypeInformation.h> > diff --git > a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf > b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf > index e9e74b1..9d62d3d 100644 > --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf > +++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf > @@ -108,6 +108,7 @@ > gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES > gEfiDriverHealthProtocolGuid ## SOMETIMES_CONSUMES > gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES > + gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES > > [Pcd] > > gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationCh > ange ## SOMETIMES_CONSUMES > -- > 2.7.0.windows.1
_______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel