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

UEFI源码解析之UEFI_DRIVER Dxe Driver可以视作UEFI中的一个服务,在entry中通过protocol安装自己的服务,在Bds等位置通过locate protocol使用该服务,不必依赖与具体的硬件。当需要封装某个设备或总线的时候,对应于具体的物理实现,需要用到UEFI Driver的模型实现。UEFI Driver模型实现设备/总线的检测,安装,卸载,更新,启动,停止等;一个Driver可能适配多个设备,一个设备可能连接管理多个子设备等,因此UEFI Driver还可以多次安装 阅读详情
  • 源码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   ///                                                      
BIOS知识枝桠——常用functions查阅 EFI_BOOT_SERVICES.InstallProtocolInterface() 在设备句柄上安装协议接口。如果句柄不存在,它将被创建并添加到系统的句柄列表中。InstallMultipleProtocolInterfaces()比InstallProtocolInterface()执行更多的错误检查,所以建议使用InstallMultipleProtocolInterfaces()代替InstallProtocolInterface() typedef EFI_STATUS (EFIAPI *EF 阅读详情

相关推荐

【BIOS/UEFI】内存布局,包括 PEI Memory 和 DXE Memory

分配机制EFI_MEMORY_TYPE_INFORMATION可保证同种类型的内存尽可能分配在一起。初次分配时需要估算预留空间,在Boot OS前,收集真正使用的内存并用一个EFI Variable保存。在之后的启动就可以得到一个较为准确的预留值(不够再从Remaining Memory中分配)

weixin_45258382的博客 2223

UEFI.源码分析.DXE阶段的执行

源码EDK2 : Tianocore UEFI源码分析系列第一篇,DXE阶段的初始化与执行流程 源码结构 MdeModulePkg/ Core/ Dxe/ Dispatcher/ DXE调度器 DxeMain/ DXE阶段入口函数 Event/ 异步事件机制 FwVol/ 闪存文件系统FFS FwVolBloc...

随便写写 6788

UEFI.源码分析.DXE的内存服务.第二部分.函数接口

源码EDK2:Tianocore UEFI源码分析系列第二篇,DXE阶段的内存服务 第二部分,函数接口 DXE阶段源码目录MdeModulePkg/Core/Dxe 首先我们来分析上一节的遗留问题,即函数CoreAddRange 之后我们分析一下其余的接口,如申请内存、释放内存等 最后我们从一个整体的视角来看整个内存服务 初始化流程 首先我们回顾一下整个内存初始化的过程。 在D...

随便写写 2504

UEFI.源码分析.DXE的内存服务.第三部分.HeapGuard

源码EDK2:Tianocore UEFI源码分析系列第二篇,DXE阶段的内存服务 第三部分,HeapGuard DXE阶段源码目录MdeModulePkg/Core/Dxe 基于开篇日(2018/04/18:16:30)时最新的EDk2版本,commit为255101471918ed8840f2be347916b90eef0e9c08 从初始化过程入手 直到CoreAddMemo...

随便写写 1345

高通Android12启动流程分析

请注意,这个流程可能会根据不同的硬件平台、Android版本和制造商的定制有所变化。上述步骤提供了一个高通Android设备从上电到操作系统完全启动的一般概述。

hyg55555的博客 2786

EFI BIOS源码实战:启动流程、镜像构建与自定义DXE驱动

固件是连接硬件与操作系统的底层软件,EFI BIOS/UEFI启动通常按SEC、PEI、DXE、BDS等阶段推进,并通过模块清单、平台描述文件和Protocol依赖组织驱动调度与镜像打包。理解模块类型、依赖库与构建参数,是定位启动异常、验证安全启动策略的基础。对固件移植、自定义DXE驱动开发和镜像构建而言,这套机制决定了代码能否被编译、打包并真正运行。围绕一份可编译、可烧写的EFI BIOS源码,从源码树阅读、工具链构建到自定义DXE驱动上机验证,形成可重复的启动流程检查与烧写前自检链路。

weixin_29164091的博客 134

Windows下的Geant4安装教程

本教程将从0开始展示在Windows下如何安装Geant4,包括各种辅助工具(QT、Cmake、Visual Studio)的下载安装,环境变量的配置,以及example的生成等。

weixin_49065278的博客 4104

S32DS 3.5.8离线包怎么用?保姆级教程教你手动安装S32K3开发环境(附资源下载)

本文详细介绍了S32DS 3.5.8离线包的安装方法,适用于S32K3开发环境的手动搭建。从资源获取、完整性验证到分步安装指南,提供了全面的离线部署解决方案,特别适合军工/车企内网开发等场景。文章还包含版本选择建议、常见问题排查及团队协作方案,帮助开发者高效完成环境配置。

weixin_30471561的博客 477

ENVI5.6 自动化流程:GF系列卫星影像批处理与质量优化

本文详细介绍了如何利用ENVI5.6构建针对GF-2、GF-6、GF-7系列卫星影像的自动化批处理流水线。通过配置Batch Processing工具,实现从正射校正到图像融合的全流程批量处理,并分享参数设置、质量监控与故障排查的实战经验,旨在显著提升海量遥感影像的处理效率与成果质量。

efc1234567的博客 603

室内温度控制仿真(Simulink+PLC)

本篇博客将会带领大家解读Simulink自带的仿真模型(Thermal Model of a House),之后再讨论PLC控制系统控制环境温度的一些经验方法

RXXW_Dor的博客 3458

DaVinci Developer和DaVinci Configurator:AutoSAR开发与配置工具

a. 组件创建:DaVinci Developer允许开发人员创建不同类型的AutoSAR软件组件,如应用软件组件(Application Software Component,SWC)、基础软件组件(Basic Software Component,BSWC)等。除了以上功能,DaVinci Developer和DaVinci Configurator还提供了丰富的文档和代码生成功能,以支持开发人员和配置人员进行文档编写、代码生成和文档浏览等任务。用户可以根据具体需求对软件组件进行灵活的配置。

HmoaAmp的博客 2261

【WRF实操】四层嵌套网格设计-以粤港澳大湾区GBA为例

四层嵌套网格设计-以粤港澳大湾区GBA为例

WW、forever的博客 820

PCB板设置20H 原则理解

20H原则是PCB设计中抑制EMI辐射的关键方法,要求电源层比相邻地层内缩20倍介质厚度(20H)。在四层板中实现20H原则需采用S-G-P-S层叠结构,确保GND与PWR紧邻。具体步骤包括:确定GND-PWR间介质厚度H,计算20H值(通常80-120mil),并在设计软件中将电源层四周内缩20H,同时保持地层完整不内缩。注意避免常见误区,如混淆介质厚度、地层内缩等。该原则能有效限制边缘场辐射,降低EMI干扰,是四层板EMC设计的重要规范。

qq_37999850的博客 689

镜头调焦的 调整的是焦距还是像距?

在镜头 “调焦”(即日常拍照时的)中,调整的核心是,而非焦距。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 1350

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: UEFI.源码分析.DXE阶段的执行
下一篇: UEFI.源码分析.DXE的内存服务.第二部分.函数接口
木艮氵
博客等级 码龄11年 136粉丝 51原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值