UEFI.源码分析.DXE的内存服务.第一部分.初始化

本文档详细分析了UEFI DXE阶段的内存服务初始化过程,包括转换HOB数据、初始化内存池、获取内存类型信息、计算所需资源、寻找可用内存资源等步骤。通过解析源码EDK2中的相关函数,阐述了如何建立内存服务,为后续的系统运行提供内存管理支持。
摘要由CSDN通过智能技术生成
  • 源码EDK2:Tianocore
  • UEFI源码分析系列第二篇,DXE阶段的内存服务
  • 第一部分,内存服务的初始化过程
  • DXE阶段源码目录MdeModulePkg/Core/Dxe
  • 源码版本为UDK2017
  • 目前最新版2018代码在/Dxe/Mem/下多了HeapGuard.c这个文件,看名称应该是用来守护堆操作防止异常的。在UDK2017中并没有这个特性,所以我们的分析按照UDK2017的代码来。
  • 关于HeapGuard的讨论将列为单独一部分,敬请期待。

内存服务的初始化

在DxeMain中调用以下函数来初始化内存服务

/** /Dxe/DxeMain/DxeMain.c **/
269   //                                                                           
270   // Initialize Memory Services                                                
271   //                                                                           
272   CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); 

该函数位于/Dxe/Gcd/Gcd.c

/** /Dxe/Gcd/Gcd.c **/
2054 EFI_STATUS                                     
2055 CoreInitializeMemoryServices (                 
2056   IN  VOID                  **HobStart,        
2057   OUT EFI_PHYSICAL_ADDRESS  *MemoryBaseAddress,
2058   OUT UINT64                *MemoryLength      
2059   )                                            
2060 {                                              
/** 进行内存服务初始化操作 **/
2295   *MemoryBaseAddress = BaseAddress;
2296   *MemoryLength      = Length;     
2297                                    
2298   return EFI_SUCCESS;              
2299 } 

1)转换HOB数据

1)把指向HOB数据的指针HobStart 转换成HOB格式的数据,本质就是把地址传给相应结构体的变量

HOB数据结构定义于/MdePkg/Include/Pi/PiHob.h

操作HOB数据的方法由库/MdePkg/Library/DxeHobLib 提供,该库的头文件位于/MdePkg/Include/Library/HobLib.h , 头文件中包含来几个操作HOB数据的宏定义,如GET_HOB_TYPE 宏来获取HOB类型。

/** /Dxe/Gcd/Gcd.c **/
2079   //                                                      
2080   // Point at the first HOB.  This must be the PHIT HOB.  
2081   //                                                      
2082   Hob.Raw = *HobStart;                                    
2083   ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF);    

注意到变量Hob的类型是EFI_PEI_HOB_POINTERS,本质上是一个union类型的数据结构。

使用union最大的好处是提高源码的可读性和间接性。利用该类型中所有域的取值均一样的特点,在不同的使用方法下,可以使用不同的变量名字,一方面可以省去强制类型转换的麻烦,另一方面可以直接体现出当前的使用需求。

/** /MdePkg/Include/Pi/PiHob.h **/
458 ///                                                             
459 /// Union of all the possible HOB Types.                        
460 ///                                                             
461 typedef union {                                                 
462   EFI_HOB_GENERIC_HEADER              *Header;                  
463   EFI_HOB_HANDOFF_INFO_TABLE          *HandoffInformationTable; 
464   EFI_HOB_MEMORY_ALLOCATION           *MemoryAllocation;        
465   EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore;
466   EFI_HOB_MEMORY_ALLOCATION_STACK     *MemoryAllocationStack;   
467   EFI_HOB_MEMORY_ALLOCATION_MODULE    *MemoryAllocationModule;  
468   EFI_HOB_RESOURCE_DESCRIPTOR         *ResourceDescriptor;      
469   EFI_HOB_GUID_TYPE                   *Guid;                    
470   EFI_HOB_FIRMWARE_VOLUME             *FirmwareVolume;          
471   EFI_HOB_FIRMWARE_VOLUME2            *FirmwareVolume2;         
472   EFI_HOB_CPU                         *Cpu;                     
473   EFI_HOB_MEMORY_POOL                 *Pool;                    
474   EFI_HOB_UEFI_CAPSULE                *Capsule;                 
475   UINT8                               *Raw;                     
476 } EFI_PEI_HOB_POINTERS;

2)初始化内存池

2)初始化内存池

/** /Dxe/Gcd/Gcd.c **/
2077   //                                                                   
2078   // Initialize the spin locks and maps in the memory services.        
2079   // Also fill in the memory services into the EFI Boot Services Table 
2080   //                                                                   
2081   CoreInitializePool ();

该函数的实现位于/Dxe/Mem/Pool.c

/** /Dxe/Mem/Pool.c **/
118 VOID                                                        
119 CoreInitializePool (                                        
120   VOID                                                      
121   )                                                         
122 {                                                           
123   UINTN  Type;                                              
124   UINTN  Index;                                             
125                                                             
126   for (Type=0; Type < EfiMaxMemoryType; Type++) {           
127     mPoolHead[Type].Signature  = 0;                         
128     mPoolHead[Type].Used       = 0;                         
129     mPoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;    
130     for (Index=0; Index < MAX_POOL_LIST; Index++) {         
131       InitializeListHead (&mPoolHead[Type].FreeList[Index]);
132     }                                                       
133   }                                                         
134 }                                                                                                                      

做的事情很简单,就是把全局变量mPoolHead 初始化,Pool 数据结构的定义也在Pool.c文件中。

/** /Dxe/Mem/Pool.c **/
 71 #define POOL_SIGNATURE  SIGNATURE_32('p','l','s','t') 
 72 typedef struct {                                      
 73     INTN             Signature;                       
 74     UINTN            Used;                            
 75     EFI_MEMORY_TYPE  MemoryType;                      
 76     LIST_ENTRY       FreeList[MAX_POOL_LIST];         
 77     LIST_ENTRY       Link;                            
 78 } POOL;                                               
 79                                                       
 80 //                                                    
 81 // Pool header for each memory type.                  
 82 //                                                    
 83 POOL            mPoolHead[EfiMaxMemoryType];          

全局变量mPoolHead对每种内存类型EFI_MEMORY_TYPE均有一组FreeList来维护可用的内存空间。

内存类型是以枚举类型定义于/MdePkg/Include/Uefi/UefiMultiPhase.h中。

/** /MdePkg/Include/Uefi/UefiMultiPhase.h **/
 19 ///                                                                                   
 20 /// Enumeration of memory types introduced in UEFI.                                   
 21 ///                                                                                   
 22 typedef enum {                                                                        
 23   ///                                                                                 
 24   /// Not used.                                                                       
 25   ///                                                                                 
 26   EfiReservedMemoryType,                                                              
 27   ///                                                                                 
 28   /// The code portions of a loaded application.                                      
 29   /// (Note that UEFI OS loaders are UEFI applications.)                              
 30   ///                                                                                 
 31   EfiLoaderCode,                                                                      
 32   ///                                                                                 
 33   /// The data portions of a loaded application and the default data allocation       
 34   /// type used by an application to allocate pool memory.                            
 35   ///                                                                                 
 36   EfiLoaderData,                                                                      
 37   ///                                                                                 
 38   /// The code portions of a loaded Boot Services Driver.                             
 39   ///                                                                                 
 40   EfiBootServicesCode,                                                                
 41   ///                                                                                 
 42   /// The data portions of a loaded Boot Serves Driver, and the default data          
 43   /// allocation type used by a Boot Services Driver to allocate pool memory.         
 44   ///                                                                                 
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值