]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Bds: Free resources after ram disk boot finishes
authorNi, Ruiyu <ruiyu.ni@intel.com>
Wed, 30 Mar 2016 00:29:10 +0000 (08:29 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Wed, 6 Apr 2016 05:27:09 +0000 (13:27 +0800)
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>
MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf

index a582b905985d5d1b1badad5aaff0d6346a7bd409..61a83455f727192b1746a55cdcf90cc525c24ab7 100644 (file)
@@ -15,6 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "InternalBm.h"\r
 \r
+EFI_RAM_DISK_PROTOCOL                        *mRamDisk                  = NULL;\r
+\r
 EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION  mBmRefreshLegacyBootOption = NULL;\r
 EFI_BOOT_MANAGER_LEGACY_BOOT                 mBmLegacyBoot              = NULL;\r
 \r
@@ -1095,6 +1097,7 @@ BmMatchHttpBootDevicePath (
   @param LoadFileHandle The handle of LoadFile instance.\r
   @param FullPath       Return the full device path pointing to the load option.\r
   @param FileSize       Return the size of the load option.\r
+  @param RamDiskHandle  Return the RAM Disk handle.\r
 \r
   @return  The load option buffer.\r
 **/\r
@@ -1102,7 +1105,8 @@ VOID *
 BmGetFileBufferFromLoadFileSystem (\r
   IN  EFI_HANDLE                      LoadFileHandle,\r
   OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
-  OUT UINTN                           *FileSize\r
+  OUT UINTN                           *FileSize,\r
+  OUT EFI_HANDLE                      *RamDiskHandle\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -1140,7 +1144,13 @@ BmGetFileBufferFromLoadFileSystem (
     FreePool (Handles);\r
   }\r
 \r
-  if (Index != HandleCount) {\r
+  if (Index == HandleCount) {\r
+    Handle = NULL;\r
+  }\r
+\r
+  *RamDiskHandle = Handle;\r
+\r
+  if (Handle != NULL) {\r
     return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), FullPath, FileSize);\r
   } else {\r
     return NULL;\r
@@ -1148,6 +1158,114 @@ BmGetFileBufferFromLoadFileSystem (
 }\r
 \r
 \r
+/**\r
+  Return the RAM Disk device path created by LoadFile.\r
+\r
+  @param FilePath  The source file path.\r
+\r
+  @return Callee-to-free RAM Disk device path\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BmGetRamDiskDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_DEVICE_PATH_PROTOCOL    *RamDiskDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL    *Node;\r
+  EFI_HANDLE                  Handle;\r
+\r
+  Node = FilePath;\r
+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);\r
+  if (!EFI_ERROR (Status) &&\r
+      (DevicePathType (Node) == MEDIA_DEVICE_PATH) &&\r
+      (DevicePathSubType (Node) == MEDIA_RAM_DISK_DP)\r
+      ) {\r
+\r
+    //\r
+    // Construct the device path pointing to RAM Disk\r
+    //\r
+    Node = NextDevicePathNode (Node);\r
+    RamDiskDevicePath = DuplicateDevicePath (FilePath);\r
+    ASSERT (RamDiskDevicePath != NULL);\r
+    SetDevicePathEndNode ((VOID *) ((UINTN) RamDiskDevicePath + ((UINTN) Node - (UINTN) FilePath)));\r
+    return RamDiskDevicePath;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Return the buffer and buffer size occupied by the RAM Disk.\r
+\r
+  @param RamDiskDevicePath  RAM Disk device path.\r
+  @param RamDiskSizeInPages Return RAM Disk size in pages.\r
+\r
+  @retval RAM Disk buffer.\r
+**/\r
+VOID *\r
+BmGetRamDiskMemoryInfo (\r
+  IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath,\r
+  OUT UINTN                   *RamDiskSizeInPages\r
+  )\r
+{\r
+\r
+  EFI_STATUS                  Status;\r
+  EFI_HANDLE                  Handle;\r
+  UINT64                      StartingAddr;\r
+  UINT64                      EndingAddr;\r
+\r
+  ASSERT (RamDiskDevicePath != NULL);\r
+\r
+  *RamDiskSizeInPages = 0;\r
+\r
+  //\r
+  // Get the buffer occupied by RAM Disk.\r
+  //\r
+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &RamDiskDevicePath, &Handle);\r
+  ASSERT_EFI_ERROR (Status);\r
+  ASSERT ((DevicePathType (RamDiskDevicePath) == MEDIA_DEVICE_PATH) &&\r
+          (DevicePathSubType (RamDiskDevicePath) == MEDIA_RAM_DISK_DP));\r
+  StartingAddr = ReadUnaligned64 ((UINT64 *) ((MEDIA_RAM_DISK_DEVICE_PATH *) RamDiskDevicePath)->StartingAddr);\r
+  EndingAddr   = ReadUnaligned64 ((UINT64 *) ((MEDIA_RAM_DISK_DEVICE_PATH *) RamDiskDevicePath)->EndingAddr);\r
+  *RamDiskSizeInPages = EFI_SIZE_TO_PAGES ((UINTN) (EndingAddr - StartingAddr + 1));\r
+  return (VOID *) (UINTN) StartingAddr;\r
+}\r
+\r
+/**\r
+  Destroy the RAM Disk.\r
+\r
+  The destroy operation includes to call RamDisk.Unregister to\r
+  unregister the RAM DISK from RAM DISK driver, free the memory\r
+  allocated for the RAM Disk.\r
+\r
+  @param RamDiskDevicePath    RAM Disk device path.\r
+**/\r
+VOID\r
+BmDestroyRamDisk (\r
+  IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  VOID                        *RamDiskBuffer;\r
+  UINTN                       RamDiskSizeInPages;\r
+\r
+  ASSERT (RamDiskDevicePath != NULL);\r
+\r
+  RamDiskBuffer = BmGetRamDiskMemoryInfo (RamDiskDevicePath, &RamDiskSizeInPages);\r
+\r
+  //\r
+  // Destroy RAM Disk.\r
+  //\r
+  if (mRamDisk == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID *) &mRamDisk);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  Status = mRamDisk->Unregister (RamDiskDevicePath);\r
+  ASSERT_EFI_ERROR (Status);\r
+  FreePages (RamDiskBuffer, RamDiskSizeInPages);\r
+}\r
+\r
 /**\r
   Get the file buffer from the specified Load File instance.\r
 \r
@@ -1160,7 +1278,7 @@ BmGetFileBufferFromLoadFileSystem (
 **/\r
 VOID *\r
 BmGetFileBufferFromLoadFile (\r
-  EFI_HANDLE                          LoadFileHandle,\r
+  IN  EFI_HANDLE                      LoadFileHandle,\r
   IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath,\r
   OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
   OUT UINTN                           *FileSize\r
@@ -1170,6 +1288,7 @@ BmGetFileBufferFromLoadFile (
   EFI_LOAD_FILE_PROTOCOL              *LoadFile;\r
   VOID                                *FileBuffer;\r
   BOOLEAN                             LoadFileSystem;\r
+  EFI_HANDLE                          RamDiskHandle;\r
   UINTN                               BufferSize;\r
 \r
   *FileSize = 0;\r
@@ -1208,7 +1327,13 @@ BmGetFileBufferFromLoadFile (
   }\r
 \r
   if (LoadFileSystem) {\r
-    FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize);\r
+    FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize, &RamDiskHandle);\r
+    if (FileBuffer == NULL) {\r
+      //\r
+      // If there is no bootable executable in the populated\r
+      //\r
+      BmDestroyRamDisk (DevicePathFromHandle (RamDiskHandle));\r
+    }\r
   } else {\r
     *FileSize = BufferSize;\r
     *FullPath = DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));\r
@@ -1436,6 +1561,7 @@ EfiBootManagerBoot (
   UINTN                     OriginalOptionNumber;\r
   EFI_DEVICE_PATH_PROTOCOL  *FilePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *Node;\r
+  EFI_DEVICE_PATH_PROTOCOL  *RamDiskDevicePath;\r
   EFI_HANDLE                FvHandle;\r
   VOID                      *FileBuffer;\r
   UINTN                     FileSize;\r
@@ -1516,10 +1642,14 @@ EfiBootManagerBoot (
   //\r
   // 5. Load EFI boot option to ImageHandle\r
   //\r
-  ImageHandle = NULL;\r
+  ImageHandle       = NULL;\r
+  RamDiskDevicePath = NULL;\r
   if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {\r
     Status     = EFI_NOT_FOUND;\r
     FileBuffer = BmGetLoadOptionBuffer (BootOption->FilePath, &FilePath, &FileSize);\r
+    if (FileBuffer != NULL) {\r
+      RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath);\r
+    }\r
     DEBUG_CODE (\r
       if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath, GetDevicePathSize (FilePath)) != 0) {\r
         DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: "));\r
@@ -1556,6 +1686,13 @@ EfiBootManagerBoot (
         (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)\r
         );\r
       BootOption->Status = Status;\r
+      //\r
+      // Destroy the RAM disk\r
+      //\r
+      if (RamDiskDevicePath != NULL) {\r
+        BmDestroyRamDisk (RamDiskDevicePath);\r
+        FreePool (RamDiskDevicePath);\r
+      }\r
       return;\r
     }\r
   }\r
@@ -1651,6 +1788,14 @@ EfiBootManagerBoot (
   }\r
   PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
 \r
+  //\r
+  // Destroy the RAM disk\r
+  //\r
+  if (RamDiskDevicePath != NULL) {\r
+    BmDestroyRamDisk (RamDiskDevicePath);\r
+    FreePool (RamDiskDevicePath);\r
+  }\r
+\r
   //\r
   // Clear the Watchdog Timer after the image returns\r
   //\r
index 7b6252a4793d56cf7c81189f703412fed740c2b6..4660323562aceab6e3dda4bebeee94935d128840 100644 (file)
@@ -43,6 +43,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/DriverHealth.h>\r
 #include <Protocol/FormBrowser2.h>\r
 #include <Protocol/VariableLock.h>\r
+#include <Protocol/RamDisk.h>\r
 \r
 #include <Guid/ZeroGuid.h>\r
 #include <Guid/MemoryTypeInformation.h>\r
index e9e74b15877481d215cb4ebead5892633ae6fb7b..9d62d3d2c12de69fd7772a997093cf0b94dfe034 100644 (file)
   gEfiDiskInfoProtocolGuid                      ## SOMETIMES_CONSUMES\r
   gEfiDriverHealthProtocolGuid                  ## SOMETIMES_CONSUMES\r
   gEfiFormBrowser2ProtocolGuid                  ## SOMETIMES_CONSUMES\r
+  gEfiRamDiskProtocolGuid                       ## SOMETIMES_CONSUMES\r
 \r
 [Pcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange      ## SOMETIMES_CONSUMES\r