UEFI EDKII 内存的分配和释放细节

版权声明:本文全部是胡说八道,如果你喜欢,可随意转载 https://blog.csdn.net/robinsongsog/article/details/84778820

内存的分配和释放作为一种

该函数实现了以字节为单位的存储空间分配,EDKII 中对这种非页面的存储空间使用了如下数据结构

来管理。

//
// Each element is the sum of the 2 previous ones: this allows us to migrate
// blocks between bins by splitting them up, while not wasting too much memory
// as we would in a strict power-of-2 sequence
//
STATIC CONST UINT16 mPoolSizeTable[] = {
  128, 256, 384, 640, 1024, 1664, 2688, 4352, 7040, 11392, 18432, 29824
};

相同大小的pool 都被存放在同一个链表中

处理了请求分配大小超过FreeList 容量的情况,对于这种情况,直接调用page.c 文件中的CoreAllocatePoolPagesI

函数去以页面为单位分配。

将新新分配的页面拆分成所需要的大小,并将这些可分配pool 加入到FreeList 数组中去,拆分后剩余的

空间“边角料”也没有浪费,而是被加入到更小单元的FreeList 数组中去

    //
    // Carve up remaining space into free pool blocks
    //
    Index--;
    while (Offset < MaxOffset) {
      ASSERT (Index < MAX_POOL_LIST);
      FSize = LIST_TO_SIZE(Index);

      while (Offset + FSize <= MaxOffset) {
        Free = (POOL_FREE *) &NewPage[Offset];
        Free->Signature = POOL_FREE_SIGNATURE;
        Free->Index     = (UINT32)Index;
        InsertHeadList (&Pool->FreeList[Index], &Free->Link);
        Offset += FSize;
      }
      Index -= 1;
    }

Index -= 1  

先尝试按最大的pool 来匹配,一直到尝试能不能匹配上128字节的内存单元。

  //
  // Get the head & tail of the pool entry
  //
  Head = BASE_CR (Buffer, POOL_HEAD, Data);
  ASSERT(Head != NULL);

  if (Head->Signature != POOL_HEAD_SIGNATURE &&
      Head->Signature != POOLPAGE_HEAD_SIGNATURE) {
    ASSERT (Head->Signature == POOL_HEAD_SIGNATURE ||
            Head->Signature == POOLPAGE_HEAD_SIGNATURE);
    return EFI_INVALID_PARAMETER;
  }

该函数与AllocatePool 相对应,将已经分配的Pool 释放以便可以重新利用这些存储空间。函数

的一开始做了些Pool 结构的检查工作,只有确实是通过AllocatePool 得到的空间才可以使用

FreePool来释放。

同样,对于大尺寸的Pool, 我们直接调用CoreFreePoolPage 来释放相关页面。对于通常的

Pool , 将这些空间重新加入到FreeList 中去。

    //
    // Put the pool entry onto the free pool list
    //
    Free = (POOL_FREE *) Head;
    ASSERT(Free != NULL);
    Free->Signature = POOL_FREE_SIGNATURE;
    Free->Index     = (UINT32)Index;
    InsertHeadList (&Pool->FreeList[Index], &Free->Link);

猜你喜欢

转载自blog.csdn.net/robinsongsog/article/details/84778820